summaryrefslogtreecommitdiff
path: root/drivers/autotst
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
committerYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
commit8e4bff4cab0ddac6060645b0715210484d02ff40 (patch)
tree3a5c3024371a04692a3a6d9974d001cdff8ebf84 /drivers/autotst
Initial file dump from open source releaseHEADmaster
Diffstat (limited to 'drivers/autotst')
-rw-r--r--drivers/autotst/Kconfig3
-rw-r--r--drivers/autotst/Makefile22
-rw-r--r--drivers/autotst/autotstdrv.c440
-rw-r--r--drivers/autotst/autotstdrv.h87
-rw-r--r--drivers/autotst/dispc.c1221
-rw-r--r--drivers/autotst/dispc.h42
-rw-r--r--drivers/autotst/dispc_reg.h136
-rw-r--r--drivers/autotst/dsi.c477
-rw-r--r--drivers/autotst/lcd_dummy.c109
-rw-r--r--drivers/autotst/lcd_dummy.h125
-rw-r--r--drivers/autotst/lcdc.c114
-rw-r--r--drivers/autotst/lcdc_reg.h95
-rw-r--r--drivers/autotst/mipi_dsih_api.c1708
-rw-r--r--drivers/autotst/mipi_dsih_api.h134
-rw-r--r--drivers/autotst/mipi_dsih_dphy.c1082
-rw-r--r--drivers/autotst/mipi_dsih_dphy.h67
-rw-r--r--drivers/autotst/mipi_dsih_hal.c1114
-rw-r--r--drivers/autotst/mipi_dsih_hal.h1804
-rw-r--r--drivers/autotst/mipi_dsih_local.h362
-rw-r--r--drivers/autotst/pinmap_gpio.h116
20 files changed, 9258 insertions, 0 deletions
diff --git a/drivers/autotst/Kconfig b/drivers/autotst/Kconfig
new file mode 100644
index 00000000..eedfb46c
--- /dev/null
+++ b/drivers/autotst/Kconfig
@@ -0,0 +1,3 @@
+config HAS_AUTOTST
+ boolean
+ default n
diff --git a/drivers/autotst/Makefile b/drivers/autotst/Makefile
new file mode 100644
index 00000000..97135f3a
--- /dev/null
+++ b/drivers/autotst/Makefile
@@ -0,0 +1,22 @@
+
+ifneq ($(KERNELRELEASE),)
+
+ autotst-objs := autotstdrv.o dispc.o dsi.o lcd_dummy.o mipi_dsih_api.o mipi_dsih_dphy.o mipi_dsih_hal.o
+ obj-m := autotst.o
+
+else
+ PRJ_ROOT=/home/anli/andr4
+ export ARCH=arm
+ export CROSS_COMPILE=${PRJ_ROOT}/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
+ KNRL_DIR=${PRJ_ROOT}/out/target/product/sp8810gb/obj/KERNEL
+
+all:
+ make -C ${KNRL_DIR} M=`pwd` $@
+
+clean:
+ @rm -rf *.o .*.o.cmd *.mod.c *.ko .*.ko.cmd *.order *.symvers Makefile~ .tmp_versions
+
+#@rmdir .tmp_versions
+
+endif
+
diff --git a/drivers/autotst/autotstdrv.c b/drivers/autotst/autotstdrv.c
new file mode 100644
index 00000000..be14b956
--- /dev/null
+++ b/drivers/autotst/autotstdrv.c
@@ -0,0 +1,440 @@
+// ****************************************** //
+// access IIC, GPIO, etc. from user space by anli.wei
+// 2012-11-25
+// 2013-01-22 add key info anli.wei
+// ****************************************** //
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <soc/sprd/pinmap.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <soc/sprd/board.h>
+#include <soc/sprd/gpio.h>
+//
+#include "autotstdrv.h"
+#include "dispc.h"
+//
+#define DBG_ENABLE_FUN
+#define DBG_ENABLE_INFO
+
+#ifdef DBG_ENABLE_FUN
+#define FUN_ENTER printk(KERN_INFO "autotst-> %s ++.\n", __FUNCTION__)
+#define FUN_LEAVE printk(KERN_INFO "autotst-> %s --.\n", __FUNCTION__)
+#else
+#define FUN_ENTER do {} while(0)
+#define FUN_LEAVE do {} while(0)
+#endif // DBG_ENABLE_FUN
+
+#ifdef DBG_ENABLE_INFO
+#define DBG_INFO(fmt, arg...) printk(KERN_INFO "autotst-> " fmt, ##arg)
+#else
+#define DBG_INFO(fmt, arg...) do {} while(0)
+#endif // DBG_ENABLE_INFO
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+#define SPRD_MAX_PIN 200
+#define SPRD_GPIO_PIN_INVALID_VALUE 0xFFFFFFFF
+
+//static uint32_t sGpioPins[SPRD_MAX_PIN];
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+extern int lcm_init( void );
+extern int32_t lcm_send_data (uint32_t data);
+
+//------------------------------------------------------------------------------
+#define CDEV_NAME "autotst"
+
+static dev_t s_devt;
+static struct cdev s_cdev;
+static struct class *s_class;
+
+//------------------------------------------------------------------------------
+
+static int autotst_open (struct inode *inode, struct file *filp)
+{
+ FUN_ENTER;
+ FUN_LEAVE;
+ return 0;
+}
+
+static int autotst_release (struct inode *inode, struct file *filp)
+{
+ FUN_ENTER;
+ FUN_LEAVE;
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+static int i2c_read( struct autotst_i2c_info_t * info )
+{
+ struct i2c_msg xfer[2];
+ u8 reg[2], reg_len = 0;
+ u8 addr = (info->addr >> 1);
+ int ret;
+
+ struct i2c_adapter * adpt = i2c_get_adapter(info->bus);
+ if( NULL == adpt ) {
+ printk(KERN_ERR "get adapter(%d) fail!\n", info->bus);
+ return -ENXIO;
+ }
+
+ DBG_INFO("i2c read: bus = %d, addr = %X, reg = %X\n", info->bus, addr, info->reg);
+
+ if( 16 == info->regBits ) {
+ reg[reg_len++] = (u8)(info->reg >> 8);
+ }
+ reg[reg_len++] = (u8)(info->reg);
+
+ // Write address
+ xfer[0].addr = addr;
+ xfer[0].flags = 0;
+ xfer[0].len = reg_len;
+ xfer[0].buf = reg;
+
+ /* Read data */
+ xfer[1].addr = addr;
+ xfer[1].flags = I2C_M_RD;
+ xfer[1].len = info->data_len;
+ xfer[1].buf = info->data;
+
+ ret = i2c_transfer(adpt, xfer, 2);
+ if( ret < 0 ) {
+ printk(KERN_ERR "i2c_transfer() returned %d\n", ret);
+
+ i2c_put_adapter(adpt);
+ return ret;
+ }
+
+ DBG_INFO("i2c read done: bus = %d, addr = 0x%04X, reg = 0x%04X\n",
+ info->bus, info->addr, info->reg);
+
+ i2c_put_adapter(adpt);
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+static int i2c_write( struct autotst_i2c_info_t * info )
+{
+ u8 buf[64];
+ u8 num = 0;
+ int ret, i;
+
+ struct i2c_msg xfer;
+
+ struct i2c_adapter * adpt = i2c_get_adapter(info->bus);
+ if( NULL == adpt ) {
+ printk(KERN_ERR "get adapter(%d) fail!\n", info->bus);
+ return -ENXIO;
+ }
+
+ if( 16 == info->regBits ) {
+ buf[num++] = (u8)(info->reg >> 8);
+ }
+
+ buf[num++] = (u8)(info->reg);
+
+ for( i = 0; i < info->data_len; ++i )
+ {
+ buf[num++] = info->data[i];
+ }
+
+ xfer.addr = info->addr;
+ xfer.flags = 0;
+ xfer.len = num;
+ xfer.buf = buf;
+
+ ret = i2c_transfer(adpt, &xfer, 1);
+ if( ret < 0 ) {
+ printk(KERN_ERR "i2c_transfer() returned %d\n", ret);
+
+ i2c_put_adapter(adpt);
+ return ret;
+ }
+
+ DBG_INFO("i2c write done: bus = %d, addr = 0x%04X, reg = 0x%04X\n",
+ info->bus, info->addr, info->reg);
+
+ i2c_put_adapter(adpt);
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+static int i2c_ioctl( unsigned int cmd, unsigned long arg )
+{
+ int ret = 0;
+ struct autotst_i2c_info_t iit;
+
+ if( copy_from_user(&iit, (const void __user *)arg, sizeof(struct autotst_i2c_info_t)) ) {
+ printk(KERN_ERR "copy_from_user fail: arg = %lu\n", arg);
+ return -EFAULT;
+ }
+
+ switch( cmd ) {
+ case AUTOTST_IOCTL_I2C_READ:
+ ret = i2c_read( &iit );
+ if( ret == 0 ) {
+ if( copy_to_user((void __user *)arg, &iit, sizeof(struct autotst_i2c_info_t)) ) {
+ printk(KERN_ERR "copy_to_user fail: arg = %lu\n", arg);
+ ret = -EFAULT;
+ }
+ }
+ break;
+ case AUTOTST_IOCTL_I2C_WRITE:
+ ret = i2c_write( &iit );
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+static int gpio_ioctl( unsigned int cmd, unsigned long arg )
+{
+ int ret = 0;
+ int pull = 0;
+ struct autotst_gpio_info_t git;
+
+ if( copy_from_user(&git, (const void __user *)arg, sizeof(struct autotst_gpio_info_t)) ) {
+ printk(KERN_ERR "copy_from_user fail: arg = %lu\n", arg);
+ return -EFAULT;
+ }
+
+ switch( cmd ) {
+ case AUTOTST_IOCTL_GPIO_INIT:
+ {
+ char name[32];
+ snprintf(name, 32, "at_gio_%d", git.gpio);
+/* // not support, already config on platform
+ if( git.pup_enb ) {
+ }
+ if( git.pdwn_enb ) {
+ }
+*/
+ pull = ( (git.pdwn_enb << 6) & (BIT_PIN_WPD) ) | ((git.pup_enb << 7) & (BIT_PIN_WPU));
+ autotst_pin_ctrl(DISPC_PIN_FUNC3, git.gpio, pull);
+ gpio_request(git.gpio, name);
+ if( AUTOTST_GPIO_DIR_IN == git.dir ) {
+ gpio_direction_input(git.gpio);
+ } else {
+ gpio_direction_output(git.gpio, git.val);
+ }
+ }
+ break;
+ case AUTOTST_IOCTL_GPIO_GET: {
+ int gv = gpio_get_value(git.gpio);
+
+ git.val = (gv > 0) ? 1 : 0;
+ if( copy_to_user((void __user *)arg, &git, sizeof(struct autotst_gpio_info_t)) ) {
+ printk(KERN_ERR "copy_to_user fail: arg = %lu\n", arg);
+ ret = -EFAULT;
+ }
+ }
+ break;
+ case AUTOTST_IOCTL_GPIO_SET:
+ gpio_set_value(git.gpio, git.val);
+ break;
+ case AUTOTST_IOCTL_GPIO_CLOSE:
+ autotst_pin_ctrl(DISPC_PIN_FUNC0, git.gpio, pull);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+static int key_ioctl( unsigned int cmd, unsigned long arg )
+{
+ int ret = 0;
+ struct autotst_key_info_t kit;
+
+ if( copy_from_user(&kit, (const void __user *)arg, sizeof(struct autotst_key_info_t)) ) {
+ printk(KERN_ERR "copy_from_user fail: arg = %lu\n", arg);
+ return -EFAULT;
+ }
+
+ if( KEY_POWER == kit.val ) {
+ kit.row = AUTOTST_KEY_INVALID_ROW;
+ kit.col = AUTOTST_KEY_INVALID_COL;
+ kit.gio = EIC_KEY_POWER;
+ } else {
+ unsigned char rc = (kit.val & 0xF7);
+
+ kit.row = ((rc >> 4) & 0x0F);
+ kit.col = ((rc >> 0) & 0x0F);
+ kit.gio = 0;
+ }
+
+ if( 0 == ret ) {
+ if( copy_to_user((void __user *)arg, &kit, sizeof(struct autotst_key_info_t)) ) {
+ printk(KERN_ERR "copy_to_user fail: arg = %lu\n", arg);
+ ret = -EFAULT;
+ }
+ }
+
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+static long autotst_ioctl( struct file *filp, unsigned int cmd, unsigned long arg )
+{
+ long ret = -1;
+
+ FUN_ENTER;
+
+ DBG_INFO("cmd = 0x%X\n", cmd);
+ switch( cmd ) {
+ case AUTOTST_IOCTL_I2C_READ:
+ case AUTOTST_IOCTL_I2C_WRITE:
+ ret = i2c_ioctl(cmd, arg);
+ break;
+ case AUTOTST_IOCTL_GPIO_INIT:
+ case AUTOTST_IOCTL_GPIO_GET:
+ case AUTOTST_IOCTL_GPIO_SET:
+ case AUTOTST_IOCTL_GPIO_CLOSE:
+ ret = gpio_ioctl(cmd, arg);
+ break;
+ case AUTOTST_IOCTL_LCD_DATA:
+ {
+ int i;
+ DBG_INFO("lcd data = 0x%X\n", (uint32_t)arg);
+#if 0
+ lcm_init();
+ for( i = 0; i < 32; ++i ) {
+ lcm_send_data((uint32_t)arg);
+ }
+#else
+ autotst_dispc_init(DISPLAY_TYPE_MCU);
+ for( i = 0; i < 32; ++i ) {
+ autotst_dispc_mcu_send_data((uint32_t)arg);
+ }
+ autotst_dispc_uninit(DISPLAY_TYPE_MCU);
+#endif
+ ret = 0;
+ }
+ break;
+#if 1
+ case AUTOTST_IOCTL_LCD_MIPI_ON:
+ {
+ int i;
+ DBG_INFO("lcd mipi on\n");
+ autotst_dispc_init(DISPLAY_TYPE_MIPI);
+ autotst_dispc_refresh();
+ ret = 0;
+ }
+ break;
+ case AUTOTST_IOCTL_LCD_MIPI_OFF:
+ {
+ int i;
+ DBG_INFO("lcd mipi off\n");
+ autotst_dispc_uninit(DISPLAY_TYPE_MIPI);
+ ret = 0;
+ }
+ break;
+#endif
+ case AUTOTST_IOCTL_GET_KEYINFO:
+ ret = key_ioctl(cmd, arg);
+ break;
+ default:
+ ret = -EINVAL;
+ DBG_INFO("lcd default \n");
+ break;
+ }
+
+ FUN_LEAVE;
+ return ret;
+}
+
+static struct file_operations autotst_fops =
+{
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = autotst_ioctl,
+ .open = autotst_open,
+ .release = autotst_release,
+};
+
+//==============================================================================
+
+static int __init autotst_init(void)
+{
+ int ret;
+
+ FUN_ENTER;
+
+ // auto select a major
+ ret = alloc_chrdev_region(&s_devt, 0, 1, CDEV_NAME);
+ if( ret < 0 ) {
+ printk(KERN_ERR "ERROR: alloc_chrdev_region %d\n", ret);
+ return ret;
+ }
+
+ cdev_init(&s_cdev, &autotst_fops);
+ ret = cdev_add(&s_cdev, s_devt, 1);
+ if( ret < 0 )
+ {
+ unregister_chrdev_region(s_devt, 1);
+ printk(KERN_ERR "ERROR: cdev_add %d\n", ret);
+ return ret;
+ }
+
+ s_class = class_create(THIS_MODULE, CDEV_NAME);
+ device_create(s_class, NULL, MKDEV(MAJOR(s_devt), MINOR(s_devt)), NULL, CDEV_NAME);
+
+// autotst_dispc_pin_ctrl(DISPC_PIN_FUNC3);
+
+ //for( i = 0; i < SPRD_MAX_PIN; ++i ) {
+ // sGpioPins[i] = SPRD_GPIO_PIN_INVALID_VALUE;
+ //}
+ //sGpioPins[59] = MFP_CFG_X(SIMCLK3, AF3, DS1, F_PULL_NONE, S_PULL_NONE, IO_OE);
+
+ FUN_LEAVE;
+ return 0;
+}
+
+static void __exit autotst_exit(void)
+{
+ FUN_ENTER;
+
+ device_destroy(s_class, MKDEV(MAJOR(s_devt), MINOR(s_devt)));
+ class_destroy(s_class);
+
+ cdev_del(&s_cdev);
+ unregister_chrdev_region(s_devt, 1);
+
+// autotst_dispc_pin_ctrl(DISPC_PIN_FUNC0);
+
+ FUN_LEAVE;
+}
+
+module_init(autotst_init);
+module_exit(autotst_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("anli.wei");
+MODULE_VERSION("0.0.1");
diff --git a/drivers/autotst/autotstdrv.h b/drivers/autotst/autotstdrv.h
new file mode 100644
index 00000000..48cb8f6e
--- /dev/null
+++ b/drivers/autotst/autotstdrv.h
@@ -0,0 +1,87 @@
+
+#ifndef _AUTOTSTDRV_20130207_H__
+#define _AUTOTSTDRV_20130207_H__
+
+//-----------------------------------------------------------------------------
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+//-----------------------------------------------------------------------------
+
+#include <asm/ioctl.h>
+
+//
+//------------------------------------------------------------------------------
+//
+#define AUTOTST_IOCTL_MAGIC 'A'
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+struct autotst_i2c_info_t {
+ unsigned char bus;
+ unsigned char rcv0;
+ unsigned short addr;
+
+ unsigned short reg;
+ unsigned char regBits; // 8 or 16
+ unsigned char rcv1;
+
+ unsigned char rcv2;
+ unsigned char data_len;
+ unsigned char data[16];
+
+};
+
+//
+#define AUTOTST_IOCTL_I2C_READ _IOWR(AUTOTST_IOCTL_MAGIC, 0x00, struct autotst_i2c_info_t)
+#define AUTOTST_IOCTL_I2C_WRITE _IOWR(AUTOTST_IOCTL_MAGIC, 0x01, struct autotst_i2c_info_t)
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+#define AUTOTST_GPIO_DIR_IN 0
+#define AUTOTST_GPIO_DIR_OUT 1
+
+struct autotst_gpio_info_t {
+ unsigned short gpio;
+ unsigned char dir;
+ unsigned char val;
+ unsigned char pup_enb;
+ unsigned char pup;
+ unsigned char pdwn_enb;
+ unsigned char pdwn;
+};
+
+#define AUTOTST_IOCTL_GPIO_INIT _IOWR(AUTOTST_IOCTL_MAGIC, 0x10, struct autotst_gpio_info_t)
+#define AUTOTST_IOCTL_GPIO_GET _IOWR(AUTOTST_IOCTL_MAGIC, 0x11, struct autotst_gpio_info_t)
+#define AUTOTST_IOCTL_GPIO_SET _IOW (AUTOTST_IOCTL_MAGIC, 0x12, struct autotst_gpio_info_t)
+#define AUTOTST_IOCTL_GPIO_CLOSE _IOW (AUTOTST_IOCTL_MAGIC, 0x13, struct autotst_gpio_info_t)
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+#define AUTOTST_LCD_DATA_NUM 32
+#define AUTOTST_IOCTL_LCD_DATA _IOW (AUTOTST_IOCTL_MAGIC, 0x30, int)
+#define AUTOTST_IOCTL_LCD_MIPI_ON _IOW (AUTOTST_IOCTL_MAGIC, 0x31, int)
+#define AUTOTST_IOCTL_LCD_MIPI_OFF _IOW (AUTOTST_IOCTL_MAGIC, 0x32, int)
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+#define AUTOTST_KEY_INVALID_ROW 0xFFEE
+#define AUTOTST_KEY_INVALID_COL 0xFFEE
+
+struct autotst_key_info_t {
+ unsigned short val; // key value
+ unsigned short row; //
+ unsigned short col;
+ unsigned short gio;
+};
+
+#define AUTOTST_IOCTL_GET_KEYINFO _IOWR(AUTOTST_IOCTL_MAGIC, 0x40, struct autotst_key_info_t)
+
+
+//-----------------------------------------------------------------------------
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+//-----------------------------------------------------------------------------
+
+#endif // _AUTOTSTDRV_20130207_H__
diff --git a/drivers/autotst/dispc.c b/drivers/autotst/dispc.c
new file mode 100644
index 00000000..763be07e
--- /dev/null
+++ b/drivers/autotst/dispc.c
@@ -0,0 +1,1221 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/clk.h>
+#include <linux/io.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+
+#include <soc/sprd/hardware.h>
+#include <soc/sprd/globalregs.h>
+#include <soc/sprd/irqs.h>
+#include <soc/sprd/sci.h>
+//#include <soc/sprd/sci_glb_regs.h>
+
+//#include <mach/pinmap.h>
+
+#include "dispc_reg.h"
+#include "lcd_dummy.h"
+#include "dispc.h"
+#include "pinmap_gpio.h"
+
+#define pr_debug printk
+
+#ifdef CONFIG_FB_SCX15
+#define DISPC_CLOCK_PARENT ("clk_192m")
+#define DISPC_CLOCK (192*1000000)
+#define DISPC_DBI_CLOCK_PARENT ("clk_256m")
+#define DISPC_DBI_CLOCK (256*1000000)
+#define DISPC_DPI_CLOCK_PARENT ("clk_192m")
+#define SPRDFB_DPI_CLOCK_SRC (192000000)
+#define DISPC_DPI_CLOCK (192*1000000/18)
+#else
+#define DISPC_CLOCK_PARENT ("clk_256m")
+#define DISPC_CLOCK (256*1000000)
+#define DISPC_DBI_CLOCK_PARENT ("clk_256m")
+#define DISPC_DBI_CLOCK (256*1000000)
+#define DISPC_DPI_CLOCK_PARENT ("clk_384m")
+#define SPRDFB_DPI_CLOCK_SRC (384000000)
+#define DISPC_DPI_CLOCK (384*1000000/36)
+#endif
+
+#define DISPC_EMC_EN_PARENT ("clk_aon_apb")
+
+#if ((defined CONFIG_FB_SCX30G)||(defined CONFIG_FB_SCX35L))
+#define DISPC_PLL_CLK ("clk_dispc0")
+#define DISPC_DBI_CLK ("clk_dispc0_dbi")
+#define DISPC_DPI_CLK ("clk_dispc0_dpi")
+#else
+#define DISPC_PLL_CLK ("clk_disc0")
+#define DISPC_DBI_CLK ("clk_disc0_dbi")
+#define DISPC_DPI_CLK ("clk_disc0_dpi")
+#endif
+#define DISPC_EMC_CLK ("clk_disp_emc")
+
+#define PATTEN_GRID_WIDTH (40)
+#define PATTEN_GRID_HEIGHT (40)
+#define PATTEN_COLOR_COUNT (7)
+
+extern struct panel_spec lcd_dummy_mipi_spec;
+extern struct panel_spec lcd_dummy_rgb_spec;
+extern struct panel_spec lcd_dummy_mcu_spec;
+
+extern void autotst_dsi_dump(void);
+extern void autotst_dsi_dump1(void);
+extern int32_t autotst_dsi_init(struct panel_spec *panel);
+extern int32_t autotst_dsi_uninit(void);
+
+struct autotst_dispc_context {
+ struct clk *clk_dispc;
+ struct clk *clk_dispc_dpi;
+ struct clk *clk_dispc_dbi;
+ struct clk *clk_dispc_emc;
+ uint32_t fb_addr_v;
+ uint32_t fb_addr_p;
+ uint32_t fb_size;
+ uint32_t dispc_if;
+ bool is_inited;
+};
+
+static struct autotst_dispc_context autotst_dispc_ctx = {0};
+static struct panel_spec *autotst_panel = NULL;
+
+static uint32_t g_patten_table[PATTEN_COLOR_COUNT] =
+ {0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffff00, 0xff00ffff, 0xffff00ff, 0xffffffff};
+
+unsigned long sprd_adi_base;
+
+#if 0 /*designed for RGB, not used for SHARKL*/
+int autotst_dispc_pin_ctrl(int type)
+{
+ static int pin_table[29];
+ static int is_first_time = true;
+ int i;
+ u32 regs = REG_PIN_LCD_CSN1;
+ u32 func;
+
+ if (is_first_time) {
+ for (i = 0; i < 29; ++i) {
+ pin_table[i] = pinmap_get(regs);
+ regs += 4;
+ }
+ is_first_time = false;
+ }
+
+ if (type == DISPC_PIN_FUNC3)
+ func = BITS_PIN_DS(1) | BITS_PIN_AF(DISPC_PIN_FUNC3) | BIT_PIN_SLP_AP;
+ else {
+ pr_err("The function hasn't been implemented yet\n");
+ return 0;
+ }
+
+ regs = REG_PIN_LCD_CSN1;
+ for (i = 0; i < 29; ++i) {
+ if (type == DISPC_PIN_FUNC0)
+ pinmap_set(regs, pin_table[i]);
+ else
+ pinmap_set(regs, func);
+ regs += 4;
+ }
+
+ return 0;
+}
+#endif
+
+int autotst_pin_ctrl(int type, int gpio_num, int gpio_pull)
+{
+ static int pin_table;
+ int i;
+ u32 regs = REG_PIN_U0TXD;
+ u32 func;
+ u32 mask;
+#ifdef CONFIG_REGULATOR_SC2713S
+ mask = BIT_LDO_SD_PD | BIT_LDO_SIM0_PD | BIT_LDO_SIM1_PD | BIT_LDO_SIM2_PD | BIT_LDO_CAMA_PD |\
+ BIT_LDO_CAMD_PD | BIT_LDO_CAMIO_PD | BIT_LDO_CAMMOT_PD;
+
+ ANA_REG_BIC(ANA_REG_GLB_LDO_PD_CTRL, mask);
+
+ for (i = 0; i < ARRAY_SIZE(pinmap_gpio); ++i) {
+ if( gpio_num == pinmap_gpio[i].num){
+ regs = pinmap_gpio[i].reg;
+ pin_table = pinmap_get(regs);
+ break;
+ }
+ }
+
+ if (type == DISPC_PIN_FUNC3){
+ func = BITS_PIN_DS(1) | BITS_PIN_AF(DISPC_PIN_FUNC3) | BIT_PIN_SLP_AP | gpio_pull;
+ }else {
+ pr_err("The function hasn't been implemented yet\n");
+ }
+
+ if (type == DISPC_PIN_FUNC0){
+ pinmap_set(regs, pin_table);
+ }else{
+ pinmap_set(regs, func);
+ }
+#endif
+ return 0;
+}
+
+/**********************************************/
+/* MCU PANEL CONFIG */
+/**********************************************/
+static uint32_t mcu_calc_timing(struct timing_mcu *timing)
+{
+ uint32_t clk_rate;
+ uint32_t rcss, rlpw, rhpw, wcss, wlpw, whpw;
+ struct clk * clk = NULL;
+
+ if(NULL == timing){
+ printk(KERN_ERR "autotst_dispc: [%s]: Invalid Param\n", __FUNCTION__);
+ return 0;
+ }
+
+ clk = clk_get(NULL,"clk_dispc_dbi");
+ if (IS_ERR(clk)) {
+ printk(KERN_WARNING "autotst_dispc: get clk_dispc_dbi fail!\n");
+ } else {
+ pr_debug(KERN_INFO "autotst_dispc: get clk_dispc_dbi ok!\n");
+ }
+// clk_rate = clk_get_rate(clk) / 1000000;
+ clk_rate = 250; // dummy 250M Hz
+
+ pr_debug(KERN_INFO "autotst_dispc: [%s] clk_rate: 0x%x\n", __FUNCTION__, clk_rate);
+
+ /********************************************************
+ * we assume : t = ? ns, dispc_dbi = ? MHz so
+ * 1ns need cycle : dispc_dbi /1000
+ * tns need cycles : t * dispc_dbi / 1000
+ *
+ ********************************************************/
+#define MAX_DBI_RWCSS_TIMING_VALUE 15
+#define MAX_DBI_RWLPW_TIMING_VALUE 63
+#define MAX_DBI_RWHPW_TIMING_VALUE 63
+#define DBI_CYCLES(ns) (( (ns) * clk_rate + 1000 - 1)/ 1000)
+
+ /* ceiling*/
+ rcss = DBI_CYCLES(timing->rcss);
+ if (rcss > MAX_DBI_RWCSS_TIMING_VALUE) {
+ rcss = MAX_DBI_RWCSS_TIMING_VALUE ;
+ }
+
+ rlpw = DBI_CYCLES(timing->rlpw);
+ if (rlpw > MAX_DBI_RWLPW_TIMING_VALUE) {
+ rlpw = MAX_DBI_RWLPW_TIMING_VALUE ;
+ }
+
+ rhpw = DBI_CYCLES (timing->rhpw);
+ if (rhpw > MAX_DBI_RWHPW_TIMING_VALUE) {
+ rhpw = MAX_DBI_RWHPW_TIMING_VALUE ;
+ }
+
+ wcss = DBI_CYCLES(timing->wcss);
+ if (wcss > MAX_DBI_RWCSS_TIMING_VALUE) {
+ wcss = MAX_DBI_RWCSS_TIMING_VALUE ;
+ }
+
+ wlpw = DBI_CYCLES(timing->wlpw);
+ if (wlpw > MAX_DBI_RWLPW_TIMING_VALUE) {
+ wlpw = MAX_DBI_RWLPW_TIMING_VALUE ;
+ }
+
+#ifndef CONFIG_LCD_CS_ALWAYS_LOW
+ /* dispc/lcdc will waste one cycle because CS pulse will use one cycle*/
+ whpw = DBI_CYCLES (timing->whpw) - 1;
+#else
+ whpw = DBI_CYCLES (timing->whpw) ;
+#endif
+ if (whpw > MAX_DBI_RWHPW_TIMING_VALUE) {
+ whpw = MAX_DBI_RWHPW_TIMING_VALUE ;
+ }
+
+ return (whpw | (wlpw << 6) | (wcss << 12)
+ | (rhpw << 16) |(rlpw << 22) | (rcss << 28));
+}
+
+#ifdef CONFIG_FB_LCD_CS1
+/*cs1*/
+static void mcu_dispc_init_config(struct panel_spec *panel)
+{
+ uint32_t reg_val = 0;
+
+ pr_debug("autotst_dispc: [%s] for cs1\n", __FUNCTION__);
+
+ if(NULL == panel){
+ printk(KERN_ERR "autotst_dispc: [%s] fail.(Invalid Param)\n", __FUNCTION__);
+ return;
+ }
+
+ if(SPRDFB_PANEL_TYPE_MCU != panel->type){
+ printk(KERN_ERR "autotst_dispc: [%s] fail.(not mcu panel)\n", __FUNCTION__);
+ return;
+ }
+
+ /*use dbi as interface*/
+ dispc_set_bits((2<<1), DISPC_CTRL);
+ autotst_dispc_ctx.dispc_if = DISPC_IF_DBI;
+
+ /* CS1 bus mode [BIT8]: 8080/6800 */
+ switch (panel->info.mcu->bus_mode) {
+ case LCD_BUS_8080:
+ break;
+ case LCD_BUS_6800:
+ reg_val |= (1<<8);
+ break;
+ default:
+ break;
+ }
+ /* CS1 bus width [BIT11:9] */
+ switch (panel->info.mcu->bus_width) {
+ case 8:
+ break;
+ case 9:
+ reg_val |= (1 << 9);
+ break;
+ case 16:
+ reg_val |= (2 << 9);
+ break;
+ case 18:
+ reg_val |= (3 << 9) ;
+ break;
+ case 24:
+ reg_val |= (4 << 9);
+ break;
+ default:
+ break;
+ }
+
+ /*CS1 pixel bits [BIT13:12]*/
+ switch (panel->info.mcu->bpp) {
+ case 16:
+ break;
+ case 18:
+ reg_val |= (1 << 12) ;
+ break;
+ case 24:
+ reg_val |= (2 << 12);
+ break;
+ default:
+ break;
+ }
+
+#ifndef CONFIG_FB_NO_FMARK
+ /*TE enable*/
+ reg_val |= (1 << 16);
+ if(SPRDFB_POLARITY_NEG == panel->info.mcu->te_pol){
+ reg_val |= (1<< 17);
+ }
+ dispc_write(panel->info.mcu->te_sync_delay, DISPC_TE_SYNC_DELAY);
+#endif
+
+#ifdef CONFIG_LCD_CS_ALWAYS_LOW
+ /*CS alway low mode*/
+ reg_val |= (1<<21);
+#else
+ /*CS not alway low mode*/
+#endif
+
+ /*CS1 selected*/
+ reg_val |= (1 << 20);
+
+ dispc_write(reg_val, DISPC_DBI_CTRL);
+
+ pr_debug("autotst_dispc: [%s] DISPC_DBI_CTRL = %d\n", __FUNCTION__, dispc_read(DISPC_DBI_CTRL));
+}
+
+static void mcu_dispc_set_timing(struct panel_spec *panel)
+{
+ uint32_t timing = 0;
+
+ pr_debug("autotst_dispc: [%s] for cs1\n", __FUNCTION__);
+
+ timing = mcu_calc_timing(panel->info.mcu->timing);
+ dispc_write(timing,DISPC_DBI_TIMING1);
+}
+
+#else
+/*cs0*/
+static void mcu_dispc_init_config(struct panel_spec *panel)
+{
+ uint32_t reg_val = 0;
+
+ pr_debug("autotst_dispc: [%s] for cs0\n", __FUNCTION__);
+
+ if(NULL == panel){
+ printk(KERN_ERR "autotst_dispc: [%s] fail.(Invalid Param)\n", __FUNCTION__);
+ return;
+ }
+
+ if(SPRDFB_PANEL_TYPE_MCU != panel->type){
+ printk(KERN_ERR "autotst_dispc: [%s] fail.(not mcu panel)\n", __FUNCTION__);
+ return;
+ }
+
+ /*use dbi as interface*/
+ dispc_set_bits((2<<1), DISPC_CTRL);
+ autotst_dispc_ctx.dispc_if = DISPC_IF_DBI;
+
+ /* CS0 bus mode [BIT0]: 8080/6800 */
+ switch (panel->info.mcu->bus_mode) {
+ case LCD_BUS_8080:
+ break;
+ case LCD_BUS_6800:
+ reg_val |= 1;
+ break;
+ default:
+ break;
+ }
+ /* CS0 bus width [BIT3:1] */
+ switch (panel->info.mcu->bus_width) {
+ case 8:
+ break;
+ case 9:
+ reg_val |= (1 << 1);
+ break;
+ case 16:
+ reg_val |= (2 << 1);
+ break;
+ case 18:
+ reg_val |= (3 << 1) ;
+ break;
+ case 24:
+ reg_val |= (4 << 1);
+ break;
+ default:
+ break;
+ }
+
+ /*CS0 pixel bits [BIT5:4]*/
+ switch (panel->info.mcu->bpp) {
+ case 16:
+ break;
+ case 18:
+ reg_val |= (1 << 4) ;
+ break;
+ case 24:
+ reg_val |= (2 << 4);
+ break;
+ default:
+ break;
+ }
+
+#ifndef CONFIG_FB_NO_FMARK
+ /*TE enable*/
+ reg_val |= (1 << 16);
+ if(SPRDFB_POLARITY_NEG == panel->info.mcu->te_pol){
+ reg_val |= (1<< 17);
+ }
+ dispc_write(panel->info.mcu->te_sync_delay, DISPC_TE_SYNC_DELAY);
+#endif
+
+#ifdef CONFIG_LCD_CS_ALWAYS_LOW
+ /*CS alway low mode*/
+ reg_val |= (1<<21);
+#else
+ /*CS not alway low mode*/
+#endif
+
+ /*CS0 selected*/
+
+ dispc_write(reg_val, DISPC_DBI_CTRL);
+
+ pr_debug("autotst_dispc: [%s] DISPC_DBI_CTRL = %d\n", __FUNCTION__, dispc_read(DISPC_DBI_CTRL));
+}
+
+static void mcu_dispc_set_timing(struct panel_spec *panel)
+{
+ uint32_t timing = 0;
+
+ pr_debug("autotst_dispc: [%s] for cs0\n", __FUNCTION__);
+
+ timing = mcu_calc_timing(panel->info.mcu->timing);
+ dispc_write(timing,DISPC_DBI_TIMING0);
+}
+#endif
+
+
+/**********************************************/
+/* RGB PANEL CONFIG */
+/**********************************************/
+static uint32_t rgb_calc_h_timing(struct timing_rgb *timing)
+{
+ return (timing->hsync | (timing->hbp << 8) | (timing->hfp << 20));
+}
+
+
+static uint32_t rgb_calc_v_timing(struct timing_rgb *timing)
+{
+ return (timing->vsync| (timing->vbp << 8) | (timing->vfp << 20));
+}
+
+static void rgb_dispc_init_config(struct panel_spec *panel)
+{
+ uint32_t reg_val = dispc_read(DISPC_DPI_CTRL);
+
+ pr_debug("autotst_dispc: [%s]\n", __FUNCTION__);
+
+ if(NULL == panel){
+ printk(KERN_ERR "autotst_dispc: [%s] fail.(Invalid Param)\n", __FUNCTION__);
+ return;
+ }
+
+ if(SPRDFB_PANEL_TYPE_RGB != panel->type){
+ printk(KERN_ERR "autotst_dispc: [%s] fail.(not mcu panel)\n", __FUNCTION__);
+ return;
+ }
+
+ /*use dpi as interface*/
+ dispc_clear_bits((3<<1), DISPC_CTRL);
+ autotst_dispc_ctx.dispc_if = DISPC_IF_DPI;
+
+ /*h sync pol*/
+ if(SPRDFB_POLARITY_NEG == panel->info.rgb->h_sync_pol){
+ reg_val |= (1<<0);
+ }
+
+ /*v sync pol*/
+ if(SPRDFB_POLARITY_NEG == panel->info.rgb->v_sync_pol){
+ reg_val |= (1<<1);
+ }
+
+ /*de sync pol*/
+ if(SPRDFB_POLARITY_NEG == panel->info.rgb->de_pol){
+ reg_val |= (1<<2);
+ }
+
+#ifdef CONFIG_DPI_SINGLE_RUN
+ /*single run mode*/
+ reg_val |= (1<<3);
+#endif
+
+ /*dpi bits*/
+ switch(panel->info.rgb->video_bus_width){
+ case 16:
+ break;
+ case 18:
+ reg_val |= (1 << 6);
+ break;
+ case 24:
+ reg_val |= (2 << 6);
+ break;
+ default:
+ break;
+ }
+
+ dispc_write(reg_val, DISPC_DPI_CTRL);
+
+ pr_debug("autotst_dispc: [%s] DISPC_DPI_CTRL = %d\n", __FUNCTION__, dispc_read(DISPC_DPI_CTRL));
+}
+
+static void rgb_dispc_set_timing(struct panel_spec *panel)
+{
+ uint32_t timing_h = 0;
+ uint32_t timing_v = 0;
+
+ pr_debug("autotst_dispc: [%s]\n", __FUNCTION__);
+
+ timing_h = rgb_calc_h_timing(panel->info.rgb->timing);
+ timing_v = rgb_calc_v_timing(panel->info.rgb->timing);
+
+ dispc_write(timing_h, DISPC_DPI_H_TIMING);
+ dispc_write(timing_v, DISPC_DPI_V_TIMING);
+}
+
+
+/**********************************************/
+/* MIPI PANEL CONFIG */
+/**********************************************/
+static void mipi_dispc_init_config(struct panel_spec *panel)
+{
+ uint32_t reg_val = dispc_read(DISPC_DPI_CTRL);
+
+ pr_debug("autotst_dispc: [%s]\n", __FUNCTION__);
+
+ if(NULL == panel){
+ printk(KERN_ERR "autotst_dispc: [%s] fail.(Invalid Param)\n", __FUNCTION__);
+ return;
+ }
+
+ if(SPRDFB_PANEL_TYPE_MIPI != panel->type){
+ printk(KERN_ERR "autotst_dispc: [%s] fail.(not mcu panel)\n", __FUNCTION__);
+ return;
+ }
+
+ if(SPRDFB_MIPI_MODE_CMD == panel->info.mipi->work_mode){
+ /*use edpi as interface*/
+ dispc_set_bits((1<<1), DISPC_CTRL);
+ autotst_dispc_ctx.dispc_if = DISPC_IF_EDPI;
+ }else{
+ /*use dpi as interface*/
+ dispc_clear_bits((3<<1), DISPC_CTRL);
+ autotst_dispc_ctx.dispc_if = DISPC_IF_DPI;
+ }
+
+ /*h sync pol*/
+ if(SPRDFB_POLARITY_NEG == panel->info.mipi->h_sync_pol){
+ reg_val |= (1<<0);
+ }
+
+ /*v sync pol*/
+ if(SPRDFB_POLARITY_NEG == panel->info.mipi->v_sync_pol){
+ reg_val |= (1<<1);
+ }
+
+ /*de sync pol*/
+ if(SPRDFB_POLARITY_NEG == panel->info.mipi->de_pol){
+ reg_val |= (1<<2);
+ }
+
+ if(SPRDFB_MIPI_MODE_VIDEO == panel->info.mipi->work_mode){
+#ifdef CONFIG_DPI_SINGLE_RUN
+ /*single run mode*/
+ reg_val |= (1<<3);
+#endif
+ }else{
+ if(!(panel->cap & PANEL_CAP_NOT_TEAR_SYNC)){
+ printk("autotst_dispc: mipi_dispc_init_config not support TE\n");
+ /*enable te*/
+ reg_val |= (1<<8);
+ }
+ /*te pol*/
+ if(SPRDFB_POLARITY_NEG == panel->info.mipi->te_pol){
+ reg_val |= (1<<9);
+ }
+ /*use external te*/
+ reg_val |= (1<<10);
+ }
+
+ /*dpi bits*/
+ switch(panel->info.rgb->video_bus_width){
+ case 16:
+ break;
+ case 18:
+ reg_val |= (1 << 6);
+ break;
+ case 24:
+ reg_val |= (2 << 6);
+ break;
+ default:
+ break;
+ }
+
+ dispc_write(reg_val, DISPC_DPI_CTRL);
+
+ pr_debug("autotst_dispc: [%s] DISPC_DPI_CTRL = %d\n", __FUNCTION__, dispc_read(DISPC_DPI_CTRL));
+}
+
+static void mipi_dispc_set_timing(struct panel_spec *panel)
+{
+ uint32_t timing_h = 0;
+ uint32_t timing_v = 0;
+
+ pr_debug("autotst_dispc: [%s]\n", __FUNCTION__);
+
+ timing_h = rgb_calc_h_timing(panel->info.mipi->timing);
+ timing_v = rgb_calc_v_timing(panel->info.mipi->timing);
+
+ dispc_write(timing_h, DISPC_DPI_H_TIMING);
+ dispc_write(timing_v, DISPC_DPI_V_TIMING);
+}
+
+/**********************************************/
+/* COMMON CONFIG */
+/**********************************************/
+static void dispc_print_clk(void)
+{
+ uint32_t reg_val0,reg_val1,reg_val2;
+ reg_val0 = sci_glb_read(SPRD_AONAPB_BASE+0x4, 0xffffffff);
+ reg_val1 = sci_glb_read(SPRD_AHB_BASE, 0xffffffff);
+ reg_val2 = sci_glb_read(SPRD_APBREG_BASE, 0xffffffff);
+ printk("autotst_dispc:0x402e0004 = 0x%x 0x20d00000 = 0x%x 0x71300000 = 0x%x \n",reg_val0, reg_val1, reg_val2);
+ reg_val0 = sci_glb_read(SPRD_APBCKG_BASE+0x34, 0xffffffff);
+ reg_val1 = sci_glb_read(SPRD_APBCKG_BASE+0x30, 0xffffffff);
+ reg_val2 = sci_glb_read(SPRD_APBCKG_BASE+0x2c, 0xffffffff);
+ printk("autotst_dispc:0x71200034 = 0x%x 0x71200030 = 0x%x 0x7120002c = 0x%x \n",reg_val0, reg_val1, reg_val2);
+}
+
+static void dispc_reset(void)
+{
+ sci_glb_set(REG_AHB_SOFT_RST, (BIT_DISPC0_SOFT_RST) );
+ udelay(10);
+ sci_glb_clr(REG_AHB_SOFT_RST, (BIT_DISPC0_SOFT_RST) );
+}
+
+static inline void dispc_set_bg_color(uint32_t bg_color)
+{
+ dispc_write(bg_color, DISPC_BG_COLOR);
+}
+
+static inline void dispc_set_osd_ck(uint32_t ck_color)
+{
+ dispc_write(ck_color, DISPC_OSD_CK);
+}
+
+static inline void dispc_osd_enable(bool is_enable)
+{
+ uint32_t reg_val;
+
+ reg_val = dispc_read(DISPC_OSD_CTRL);
+ if(is_enable){
+ reg_val = reg_val | (BIT(0));
+ }
+ else{
+ reg_val = reg_val & (~(BIT(0)));
+ }
+ dispc_write(reg_val, DISPC_OSD_CTRL);
+}
+
+
+static void dispc_dithering_enable(bool enable)
+{
+ if(enable){
+ dispc_set_bits(BIT(6), DISPC_CTRL);
+ }else{
+ dispc_clear_bits(BIT(6), DISPC_CTRL);
+ }
+}
+
+static void dispc_pwr_enable(bool enable)
+{
+ if(enable){
+ dispc_set_bits(BIT(7), DISPC_CTRL);
+ }else{
+ dispc_clear_bits(BIT(7), DISPC_CTRL);
+ }
+}
+
+static void dispc_set_exp_mode(uint16_t exp_mode)
+{
+ uint32_t reg_val = dispc_read(DISPC_CTRL);
+
+ reg_val &= ~(0x3 << 16);
+ reg_val |= (exp_mode << 16);
+ dispc_write(reg_val, DISPC_CTRL);
+}
+
+static void dispc_module_enable(void)
+{
+ /*dispc module enable */
+ dispc_write((1<<0), DISPC_CTRL);
+
+ /*disable dispc INT*/
+ dispc_write(0x0, DISPC_INT_EN);
+
+ /* clear dispc INT */
+ dispc_write(0x1F, DISPC_INT_CLR);
+}
+
+static void dispc_layer_init(struct panel_spec *panel)
+{
+ uint32_t reg_val = 0;
+
+// dispc_clear_bits((1<<0),DISPC_IMG_CTRL);
+ dispc_write(0x0, DISPC_IMG_CTRL);
+ dispc_clear_bits((1<<0),DISPC_OSD_CTRL);
+
+ /******************* OSD layer setting **********************/
+
+ /*enable OSD layer*/
+ reg_val |= (1 << 0);
+
+ /*disable color key */
+
+ /* alpha mode select - block alpha*/
+ reg_val |= (1 << 2);
+
+ /* data format */
+ //if (var->bits_per_pixel == 32) {
+ if(1){
+ /* ABGR */
+ reg_val |= (3 << 4);
+ /* rb switch */
+ reg_val |= (1 << 15);
+ } else {
+ /* RGB565 */
+ reg_val |= (5 << 4);
+ /* B2B3B0B1 */
+ reg_val |= (2 << 8);
+ }
+
+ dispc_write(reg_val, DISPC_OSD_CTRL);
+
+ /* OSD layer alpha value */
+ dispc_write(0xff, DISPC_OSD_ALPHA);
+
+ /* OSD layer size */
+ reg_val = ( panel->width & 0xfff) | (( panel->height & 0xfff ) << 16);
+ dispc_write(reg_val, DISPC_OSD_SIZE_XY);
+
+ /* OSD layer start position */
+ dispc_write(0, DISPC_OSD_DISP_XY);
+
+ /* OSD layer pitch */
+ reg_val = ( panel->width & 0xfff) ;
+ dispc_write(reg_val, DISPC_OSD_PITCH);
+
+ /* OSD color_key value */
+ dispc_set_osd_ck(0x0);
+
+ /* DISPC workplane size */
+ reg_val = ( panel->width & 0xfff) | ((panel->height & 0xfff ) << 16);
+ dispc_write(reg_val, DISPC_SIZE_XY);
+}
+
+static void dispc_run(void)
+{
+ if(DISPC_IF_DPI == autotst_dispc_ctx.dispc_if){
+ /*dpi register update*/
+ dispc_set_bits(BIT(5), DISPC_DPI_CTRL);
+ udelay(30);
+
+ /*dpi register update with SW and VSync*/
+ dispc_clear_bits(BIT(4), DISPC_DPI_CTRL);
+
+ /* start refresh */
+ dispc_set_bits((1 << 4), DISPC_CTRL);
+
+ }else{
+ /* start refresh */
+ dispc_set_bits((1 << 4), DISPC_CTRL);
+ }
+}
+
+static void dispc_stop(void)
+{
+ if(DISPC_IF_DPI == autotst_dispc_ctx.dispc_if){
+ /*dpi register update with SW only*/
+ dispc_set_bits(BIT(4), DISPC_DPI_CTRL);
+
+ /* stop refresh */
+ dispc_clear_bits((1 << 4), DISPC_CTRL);
+ }
+}
+
+static int dispc_clk_enable(struct autotst_dispc_context *dispc_ctx_ptr)
+{
+ int ret = 0;
+ bool is_dispc_enable=false;
+ bool is_dispc_dpi_enable=false;
+
+ pr_debug(KERN_INFO "autotst_dispc:[%s]\n",__FUNCTION__);
+ if(!dispc_ctx_ptr){
+ return -1;
+ }
+
+ ret = clk_enable(dispc_ctx_ptr->clk_dispc);
+ if(ret){
+ printk("autotst_dispc:enable clk_dispc error!!!\n");
+ ret=-1;
+ goto ERROR_CLK_ENABLE;
+ }
+ is_dispc_enable=true;
+ ret = clk_enable(dispc_ctx_ptr->clk_dispc_dpi);
+ if(ret){
+ printk("autotst_dispc:enable clk_dispc_dpi error!!!\n");
+ ret=-1;
+ goto ERROR_CLK_ENABLE;
+ }
+ is_dispc_dpi_enable=true;
+ ret = clk_enable(dispc_ctx_ptr->clk_dispc_dbi);
+ if(ret){
+ printk("autotst_dispc:enable clk_dispc_dbi error!!!\n");
+ ret=-1;
+ goto ERROR_CLK_ENABLE;
+ }
+
+ return ret;
+
+ERROR_CLK_ENABLE:
+ if(is_dispc_enable){
+ clk_disable(dispc_ctx_ptr->clk_dispc);
+ }
+ if(is_dispc_dpi_enable){
+ clk_disable(dispc_ctx_ptr->clk_dispc_dpi);
+ }
+
+ printk("autotst_dispc:sprdfb_dispc_clk_enable error!!!!!!\n");
+ return ret;
+}
+
+static int32_t dispc_clk_init(void)
+{
+ int ret = 0;
+ struct clk *clk_parent1, *clk_parent2, *clk_parent3, *clk_parent4;
+
+ pr_debug(KERN_INFO "autotst_dispc:[%s]\n", __FUNCTION__);
+
+ sci_glb_set(DISPC_CORE_EN, BIT_DISPC_CORE_EN);
+
+ clk_parent1 = clk_get(NULL, DISPC_CLOCK_PARENT);
+ if (IS_ERR(clk_parent1)) {
+ printk(KERN_WARNING "autotst_dispc: get clk_parent1 fail!\n");
+ return -1;
+ } else {
+ pr_debug(KERN_INFO "autotst_dispc: get clk_parent1 ok!\n");
+ }
+
+ clk_parent2 = clk_get(NULL, DISPC_DBI_CLOCK_PARENT);
+ if (IS_ERR(clk_parent2)) {
+ printk(KERN_WARNING "autotst_dispc: get clk_parent2 fail!\n");
+ return -1;
+ } else {
+ pr_debug(KERN_INFO "autotst_dispc: get clk_parent2 ok!\n");
+ }
+
+ clk_parent3 = clk_get(NULL, DISPC_DPI_CLOCK_PARENT);
+ if (IS_ERR(clk_parent3)) {
+ printk(KERN_WARNING "autotst_dispc: get clk_parent3 fail!\n");
+ return -1;
+ } else {
+ pr_debug(KERN_INFO "autotst_dispc: get clk_parent3 ok!\n");
+ }
+
+ clk_parent4 = clk_get(NULL, DISPC_EMC_EN_PARENT);
+ if (IS_ERR(clk_parent3)) {
+ printk(KERN_WARNING "autotst_dispc: get clk_parent4 fail!\n");
+ return -1;
+ } else {
+ pr_debug(KERN_INFO "autotst_dispc: get clk_parent4 ok!\n");
+ }
+
+ autotst_dispc_ctx.clk_dispc = clk_get(NULL, DISPC_PLL_CLK);
+ if (IS_ERR(autotst_dispc_ctx.clk_dispc)) {
+ printk(KERN_WARNING "autotst_dispc: get clk_dispc fail!\n");
+ return -1;
+ } else {
+ pr_debug(KERN_INFO "autotst_dispc: get clk_dispc ok!\n");
+ }
+
+ autotst_dispc_ctx.clk_dispc_dbi = clk_get(NULL, DISPC_DBI_CLK);
+ if (IS_ERR(autotst_dispc_ctx.clk_dispc_dbi)) {
+ printk(KERN_WARNING "autotst_dispc: get clk_dispc_dbi fail!\n");
+ return -1;
+ } else {
+ pr_debug(KERN_INFO "autotst_dispc: get clk_dispc_dbi ok!\n");
+ }
+
+ autotst_dispc_ctx.clk_dispc_dpi = clk_get(NULL, DISPC_DPI_CLK);
+ if (IS_ERR(autotst_dispc_ctx.clk_dispc_dpi)) {
+ printk(KERN_WARNING "autotst_dispc: get clk_dispc_dpi fail!\n");
+ return -1;
+ } else {
+ pr_debug(KERN_INFO "autotst_dispc: get clk_dispc_dpi ok!\n");
+ }
+
+ autotst_dispc_ctx.clk_dispc_emc = clk_get(NULL, DISPC_EMC_CLK);
+ if (IS_ERR(autotst_dispc_ctx.clk_dispc_emc)) {
+ printk(KERN_WARNING "autotst_dispc: get clk_dispc_dpi fail!\n");
+ return -1;
+ } else {
+ pr_debug(KERN_INFO "autotst_dispc: get clk_dispc_emc ok!\n");
+ }
+
+ ret = clk_set_parent(autotst_dispc_ctx.clk_dispc, clk_parent1);
+ if(ret){
+ printk(KERN_ERR "autotst_dispc: dispc set clk parent fail\n");
+ }
+ ret = clk_set_rate(autotst_dispc_ctx.clk_dispc, DISPC_CLOCK);
+ if(ret){
+ printk(KERN_ERR "autotst_dispc: dispc set clk parent fail\n");
+ }
+
+ ret = clk_set_parent(autotst_dispc_ctx.clk_dispc_dbi, clk_parent2);
+ if(ret){
+ printk(KERN_ERR "autotst_dispc: dispc set dbi clk parent fail\n");
+ }
+ ret = clk_set_rate(autotst_dispc_ctx.clk_dispc_dbi, DISPC_DBI_CLOCK);
+ if(ret){
+ printk(KERN_ERR "autotst_dispc: dispc set dbi clk parent fail\n");
+ }
+
+ ret = clk_set_parent(autotst_dispc_ctx.clk_dispc_dpi, clk_parent3);
+ if(ret){
+ printk(KERN_ERR "autotst_dispc: dispc set dpi clk parent fail\n");
+ }
+ ret = clk_set_rate(autotst_dispc_ctx.clk_dispc_dpi, DISPC_DPI_CLOCK);
+ if(ret){
+ printk(KERN_ERR "autotst_dispc: dispc set dpi clk parent fail\n");
+ }
+
+ ret = clk_set_parent(autotst_dispc_ctx.clk_dispc_emc, clk_parent4);
+ if(ret){
+ printk(KERN_ERR "autotst_dispc: dispc set emc clk parent fail\n");
+ }
+
+ ret = clk_enable(autotst_dispc_ctx.clk_dispc_emc);
+ if(ret){
+ printk("autotst_dispc:enable clk_dispc_emc error!!!\n");
+ return -1;
+ }
+
+ ret = dispc_clk_enable(&autotst_dispc_ctx);
+ if (ret) {
+ printk(KERN_WARNING "autotst_dispc:[%s] enable dispc_clk fail!\n",__FUNCTION__);
+ return -1;
+ } else {
+ pr_debug(KERN_INFO "autotst_dispc:[%s] enable dispc_clk ok!\n",__FUNCTION__);
+ }
+
+ dispc_print_clk();
+
+ return 0;
+}
+
+static int dispc_clk_disable(struct autotst_dispc_context *dispc_ctx_ptr)
+{
+ pr_debug(KERN_INFO "autotst_dispc:[%s]\n",__FUNCTION__);
+ if(!dispc_ctx_ptr){
+ return 0;
+ }
+
+ pr_debug(KERN_INFO "autotst_dispc:sprdfb_dispc_clk_disable real\n");
+ clk_disable(dispc_ctx_ptr->clk_dispc);
+ clk_disable(dispc_ctx_ptr->clk_dispc_dpi);
+ clk_disable(dispc_ctx_ptr->clk_dispc_dbi);
+
+ return 0;
+}
+
+static void draw_patten(uint32_t* buffer, int buffer_w, int buffer_h, int grid_w, int grid_h)
+{
+ int h = 0;
+ int v = 0;
+ int i,j;
+ int grid_in_width = buffer_h / grid_w;
+ unsigned int c = 0;
+
+ for (j = 0; j < buffer_h; j++) {
+ for (i = 0; i < buffer_w; i++) {
+ h = i / grid_w;
+ v = j / grid_h;
+ c = g_patten_table[(v*grid_in_width+h) % PATTEN_COLOR_COUNT];
+ buffer[j*buffer_w+i] = c;
+ }
+ }
+}
+
+static int dispc_fb_prepare(struct panel_spec *panel)
+{
+ uint32_t fb_size = 0;// should be ABGR888
+ uint32_t *p_pixel = NULL;
+
+ fb_size = panel->width * panel->height * 4;// should be ABGR888
+
+ autotst_dispc_ctx.fb_addr_v = __get_free_pages(GFP_ATOMIC | __GFP_ZERO , get_order(fb_size));
+ if (!autotst_dispc_ctx.fb_addr_v) {
+ printk(KERN_ERR "sprdfb: %s Failed to allocate frame buffer\n", __FUNCTION__);
+ return -1;
+ }
+ printk(KERN_INFO "sprdfb: got %d bytes frame buffer at 0x%x\n", fb_size,
+ autotst_dispc_ctx.fb_addr_v);
+
+ autotst_dispc_ctx.fb_addr_p = __pa(autotst_dispc_ctx.fb_addr_v);
+ autotst_dispc_ctx.fb_size = fb_size;
+
+ p_pixel = autotst_dispc_ctx.fb_addr_v;
+ draw_patten(p_pixel, panel->width, panel->height, PATTEN_GRID_WIDTH, PATTEN_GRID_HEIGHT);
+
+ return 0;
+}
+
+void dispc_dump(void)
+{
+ int i = 0;
+ for(i=0;i<256;i+=16){
+ printk("autotst_dispc: %x: 0x%x, 0x%x, 0x%x, 0x%x\n", i, dispc_read(i),
+ dispc_read(i+4),
+ dispc_read(i+8),
+ dispc_read(i+12));
+ }
+ printk("**************************\n");
+}
+
+int32_t autotst_dispc_uninit(int display_type)
+{
+ printk(KERN_INFO "autotst_dispc:[%s]\n",__FUNCTION__);
+
+ dispc_stop();
+ dispc_clk_disable(&autotst_dispc_ctx);
+ if(DISPLAY_TYPE_MIPI == display_type){
+ autotst_dsi_uninit();
+ }
+ if(0 != autotst_dispc_ctx.fb_addr_v){
+ free_pages(autotst_dispc_ctx.fb_addr_v, get_order(autotst_dispc_ctx.fb_size));
+ }
+ autotst_dispc_ctx.fb_addr_v = 0;
+ autotst_dispc_ctx.fb_addr_p = 0;
+ autotst_dispc_ctx.fb_size = 0;
+ return 0;
+}
+
+int32_t autotst_dispc_init(int display_type)
+{
+ int ret = 0;
+
+ printk(KERN_INFO "autotst_dispc:[%s]\n",__FUNCTION__);
+
+ //autotst_dsi_dump();
+
+ autotst_dispc_uninit(DISPLAY_TYPE_MIPI);
+
+ ret = dispc_clk_init();
+ if(ret){
+ printk(KERN_WARNING "autotst_dispc: dispc_clk_init fail!\n");
+ return -1;
+ }
+
+ dispc_reset();
+ dispc_module_enable();
+
+ /*set bg color*/
+ dispc_set_bg_color(0xFFFFFFFF);
+ /*enable dithering*/
+ dispc_dithering_enable(true);
+ /*use MSBs as img exp mode*/
+ dispc_set_exp_mode(0x0);
+ //enable DISPC Power Control
+ dispc_pwr_enable(true);
+
+ switch(display_type){
+ case DISPLAY_TYPE_MCU:
+ autotst_panel = &lcd_dummy_mcu_spec;
+ mcu_dispc_init_config(autotst_panel);
+ mcu_dispc_set_timing(autotst_panel);
+ break;
+ case DISPLAY_TYPE_RGB:
+ autotst_panel = &lcd_dummy_rgb_spec;
+ rgb_dispc_init_config(autotst_panel);
+ rgb_dispc_set_timing(autotst_panel);
+ autotst_dispc_ctx.dispc_if = DISPC_IF_DPI;
+ break;
+ case DISPLAY_TYPE_MIPI:
+ autotst_panel = &lcd_dummy_mipi_spec;
+ mipi_dispc_init_config(autotst_panel);
+ mipi_dispc_set_timing(autotst_panel);
+ autotst_dsi_init(autotst_panel);
+ break;
+ default:
+ printk("autotst_dispc:[%s] error display type (%d)\n", __FUNCTION__, display_type);
+ }
+
+ dispc_layer_init(autotst_panel);
+
+ if(DISPC_IF_DPI == autotst_dispc_ctx.dispc_if){
+ if(1){
+ /*set dpi register update only with SW*/
+ dispc_set_bits(BIT(4), DISPC_DPI_CTRL);
+ }else{
+ /*set dpi register update with SW & VSYNC*/
+ dispc_clear_bits(BIT(4), DISPC_DPI_CTRL);
+ }
+ /*enable dispc update done INT*/
+ //dispc_write((1<<4), DISPC_INT_EN);
+ }else{
+ /* enable dispc DONE INT*/
+ //dispc_write((1<<0), DISPC_INT_EN);
+ }
+ //dispc_set_bits(BIT(2), DISPC_INT_EN);
+ return 0;
+}
+
+int32_t autotst_dispc_refresh (void)
+{
+ int ret = 0;
+ uint32_t size = (autotst_panel->width& 0xffff) | ((autotst_panel->height) << 16);
+ printk(KERN_INFO "autotst_dispc:[%s]\n",__FUNCTION__);
+
+ //autotst_dsi_dump();
+
+ ret = dispc_fb_prepare(autotst_panel);
+ if(0 != ret){
+ printk("autotst_dispc: refresh fail!(can't prepare frame buffer)!]n");
+ return -1;
+ }
+
+ dispc_write(autotst_dispc_ctx.fb_addr_p, DISPC_OSD_BASE_ADDR);
+ dispc_write(0, DISPC_OSD_DISP_XY);
+ dispc_write(size, DISPC_OSD_SIZE_XY);
+ dispc_write(autotst_panel->width, DISPC_OSD_PITCH);
+ dispc_write(size, DISPC_SIZE_XY);
+
+ dispc_run();
+
+#if 1
+ pr_debug("DISPC_CTRL: 0x%x\n", dispc_read(DISPC_CTRL));
+ pr_debug("DISPC_SIZE_XY: 0x%x\n", dispc_read(DISPC_SIZE_XY));
+ pr_debug("DISPC_BG_COLOR: 0x%x\n", dispc_read(DISPC_BG_COLOR));
+ pr_debug("DISPC_INT_EN: 0x%x\n", dispc_read(DISPC_INT_EN));
+ pr_debug("DISPC_OSD_CTRL: 0x%x\n", dispc_read(DISPC_OSD_CTRL));
+ pr_debug("DISPC_OSD_BASE_ADDR: 0x%x\n", dispc_read(DISPC_OSD_BASE_ADDR));
+ pr_debug("DISPC_OSD_SIZE_XY: 0x%x\n", dispc_read(DISPC_OSD_SIZE_XY));
+ pr_debug("DISPC_OSD_PITCH: 0x%x\n", dispc_read(DISPC_OSD_PITCH));
+ pr_debug("DISPC_OSD_DISP_XY: 0x%x\n", dispc_read(DISPC_OSD_DISP_XY));
+ pr_debug("DISPC_OSD_ALPHA : 0x%x\n", dispc_read(DISPC_OSD_ALPHA));
+#else
+ mdelay(20);
+ dispc_dump();
+ autotst_dsi_dump();
+ autotst_dsi_dump1();
+#endif
+ return 0;
+}
+
+/**********************************************/
+/* MCU OPERATION */
+/**********************************************/
+int32_t autotst_dispc_mcu_send_cmd(uint32_t cmd)
+{
+ /* busy wait for ahb fifo full sign's disappearance */
+ while(dispc_read(DISPC_DBI_QUEUE) & BIT(5));
+
+ dispc_write(cmd, DISPC_DBI_CMD);
+
+ return 0;
+}
+
+int32_t autotst_dispc_mcu_send_cmd_data(uint32_t cmd, uint32_t data)
+{
+ /* busy wait for ahb fifo full sign's disappearance */
+ while(dispc_read(DISPC_DBI_QUEUE) & BIT(5));
+
+ dispc_write(cmd, DISPC_DBI_CMD);
+
+ /* busy wait for ahb fifo full sign's disappearance */
+ while(dispc_read(DISPC_DBI_QUEUE) & BIT(5));
+
+ dispc_write(data, DISPC_DBI_DATA);
+
+ return 0;
+}
+
+int32_t autotst_dispc_mcu_send_data(uint32_t data)
+{
+ /* busy wait for ahb fifo full sign's disappearance */
+ while(dispc_read(DISPC_DBI_QUEUE) & BIT(5));
+
+ dispc_write(data, DISPC_DBI_DATA);
+
+ return 0;
+}
+
+uint32_t autotst_dispc_mcu_read_data(void)
+{
+ /* busy wait for ahb fifo full sign's disappearance */
+ while(dispc_read(DISPC_DBI_QUEUE) & BIT(5));
+ dispc_write(1 << 24, DISPC_DBI_DATA);
+ udelay(50);
+ return dispc_read(DISPC_DBI_RDATA);
+}
+
+
diff --git a/drivers/autotst/dispc.h b/drivers/autotst/dispc.h
new file mode 100644
index 00000000..98844358
--- /dev/null
+++ b/drivers/autotst/dispc.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 _DISPC_H_
+#define _DISPC_H_
+
+typedef enum{
+ DISPLAY_TYPE_MCU = 0,
+ DISPLAY_TYPE_RGB,
+ DISPLAY_TYPE_MIPI,
+}E_DISPLAY_TYPE;
+
+enum DISPC_PIN_FUNC {
+ DISPC_PIN_FUNC0 = 0,
+ DISPC_PIN_FUNC1,
+ DISPC_PIN_FUNC2,
+ DISPC_PIN_FUNC3,
+};
+
+int32_t autotst_dispc_mcu_send_cmd(uint32_t cmd);
+int32_t autotst_dispc_mcu_send_cmd_data(uint32_t cmd, uint32_t data);
+int32_t autotst_dispc_mcu_send_data(uint32_t data);
+uint32_t autotst_dispc_mcu_read_data(void);
+
+int32_t autotst_dispc_init(int display_type);
+int32_t autotst_dispc_uninit(int display_type);
+int32_t autotst_dispc_refresh (void);
+int autotst_pin_ctrl(int type, int gpio_num, int gpio_pull);
+
+//int autotst_dispc_pin_ctrl(int type);
+
+#endif
diff --git a/drivers/autotst/dispc_reg.h b/drivers/autotst/dispc_reg.h
new file mode 100644
index 00000000..869c47da
--- /dev/null
+++ b/drivers/autotst/dispc_reg.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 _DISPC_REG_H_
+#define _DISPC_REG_H_
+
+#include <asm/io.h>
+#include <soc/sprd/sci.h>
+#include <soc/sprd/hardware.h>
+#include <soc/sprd/sci_glb_regs.h>
+
+/* DISPC regs offset */
+#define DISPC_CTRL (0x0000)
+#define DISPC_SIZE_XY (0x0004)
+#define DISPC_RSTN (0x0008)
+
+#define DISPC_STS (0x0010)
+
+#define DISPC_IMG_CTRL (0x0020)
+#define DISPC_IMG_Y_BASE_ADDR (0x0024)
+#define DISPC_IMG_UV_BASE_ADDR (0x0028)
+#define DISPC_IMG_V_BASE_ADDR (0x002c)
+#define DISPC_IMG_SIZE_XY (0x0030)
+#define DISPC_IMG_PITCH (0x0034)
+#define DISPC_IMG_DISP_XY (0x0038)
+#define DISPC_BG_COLOR (0x003c)
+
+#define DISPC_OSD_CTRL (0x0040)
+#define DISPC_OSD_BASE_ADDR (0x0044)
+#define DISPC_OSD_SIZE_XY (0x0048)
+#define DISPC_OSD_PITCH (0x004c)
+#define DISPC_OSD_DISP_XY (0x0050)
+#define DISPC_OSD_ALPHA (0x0054)
+#define DISPC_OSD_CK (0x0058)
+
+#define DISPC_Y2R_CTRL (0x0060)
+#define DISPC_Y2R_CONTRAST (0x0064)
+#define DISPC_Y2R_SATURATION (0x0068)
+#define DISPC_Y2R_BRIGHTNESS (0x006c)
+
+#define DISPC_INT_EN (0x0070)
+#define DISPC_INT_CLR (0x0074)
+#define DISPC_INT_STATUS (0x0078)
+#define DISPC_INT_RAW (0x007c)
+
+#define DISPC_DPI_CTRL (0x0080)
+#define DISPC_DPI_H_TIMING (0x0084)
+#define DISPC_DPI_V_TIMING (0x0088)
+#define DISPC_DPI_STS0 (0x008c)
+#define DISPC_DPI_STS1 (0x0090)
+
+#define DISPC_DBI_CTRL (0x00a0)
+#define DISPC_DBI_TIMING0 (0x00a4)
+#define DISPC_DBI_TIMING1 (0x00a8)
+#define DISPC_DBI_RDATA (0x00ac)
+#define DISPC_DBI_CMD (0x00b0)
+#define DISPC_DBI_DATA (0x00b4)
+#define DISPC_DBI_QUEUE (0x00b8)
+
+
+
+//shadow register , read only
+#define SHDW_IMG_CTRL (0x00C0)
+#define SHDW_IMG_Y_BASE_ADDR (0x00C4)
+#define SHDW_IMG_UV_BASE_ADDR (0x00C8)
+#define SHDW_IMG_V_BASE_ADDR (0x00CC)
+#define SHDW_IMG_SIZE_XY (0x00D0)
+#define SHDW_IMG_PITCH (0x00D4)
+#define SHDW_IMG_DISP_XY (0x00D8)
+#define SHDW_BG_COLOR (0x00DC)
+#define SHDW_OSD_CTRL (0x00E0)
+#define SHDW_OSD_BASE_ADDR (0x00E4)
+#define SHDW_OSD_SIZE_XY (0x00E8)
+#define SHDW_OSD_PITCH (0x00EC)
+#define SHDW_OSD_DISP_XY (0x00F0)
+#define SHDW_OSD_ALPHA (0x00F4)
+#define SHDW_OSD_CK (0x00F8)
+#define SHDW_Y2R_CTRL (0x0100)
+#define SHDW_Y2R_CONTRAST (0x0104)
+#define SHDW_Y2R_SATURATION (0x0108)
+#define SHDW_Y2R_BRIGHTNESS (0x010C)
+#define SHDW_DPI_H_TIMING (0x0110)
+#define SHDW_DPI_V_TIMING (0x0114)
+#define DISPC_TE_SYNC_DELAY (0x00bc)
+
+#define SPRD_LCDC_BASE g_dispc_base_addr
+
+#define SPRD_DISPC_BASE SPRD_LCDC_BASE
+#define IRQ_DISPC_INT IRQ_DISPC0_INT
+
+#define REG_AHB_SOFT_RST (0x4 + SPRD_AHB_BASE)
+
+#define DISPC_CORE_EN (REG_AP_APB_APB_EB)
+#define BIT_DISPC_CORE_EN (BIT_AP_CKG_EB)
+
+extern unsigned long g_dispc_base_addr;
+
+
+enum{
+ DISPC_IF_DBI = 0,
+ DISPC_IF_DPI,
+ DISPC_IF_EDPI,
+ DISPC_IF_LIMIT
+};
+
+static inline uint32_t dispc_read(uint32_t reg)
+{
+ return sci_glb_read(SPRD_DISPC_BASE + reg, 0xffffffff);
+}
+
+static inline void dispc_write(uint32_t value, uint32_t reg)
+{
+ sci_glb_write((SPRD_DISPC_BASE + reg), value, 0xffffffff);
+}
+
+static inline void dispc_set_bits(uint32_t bits, uint32_t reg)
+{
+ dispc_write(dispc_read(reg) | bits, reg);
+}
+
+static inline void dispc_clear_bits(uint32_t bits, uint32_t reg)
+{
+ dispc_write(dispc_read(reg) & ~bits, reg);
+}
+
+#endif
diff --git a/drivers/autotst/dsi.c b/drivers/autotst/dsi.c
new file mode 100644
index 00000000..ce4e9d97
--- /dev/null
+++ b/drivers/autotst/dsi.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/kgdb.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/irqreturn.h>
+#include <linux/interrupt.h>
+
+#include <soc/sprd/hardware.h>
+#include <soc/sprd/globalregs.h>
+#include <soc/sprd/irqs.h>
+#include <soc/sprd/sci.h>
+#include <soc/sprd/sci_glb_regs.h>
+#include <soc/sprd/board.h>
+
+#include "lcd_dummy.h"
+
+#include "mipi_dsih_local.h"
+#include "mipi_dsih_dphy.h"
+#include "mipi_dsih_hal.h"
+#include "mipi_dsih_api.h"
+
+#define pr_debug printk
+
+#define DSI_PHY_REF_CLOCK (26*1000)
+#define DSI_EDPI_CFG (0x6c)
+
+#ifdef CONFIG_FB_SCX15
+#define DISPC_DPI_CLOCK (192*1000000/18)
+#else
+#define DISPC_DPI_CLOCK (384*1000000/36)
+#endif
+
+#define SPRD_MIPI_DSIC_BASE SPRD_DSI_BASE
+#define IRQ_DSI_INTN0 IRQ_DSI0_INT
+#define IRQ_DSI_INTN1 IRQ_DSI1_INT
+
+#define DSI_REG_EB REG_AP_AHB_AHB_EB
+#define DSI_BIT_EB BIT_DSI_EB
+
+#define DSI_AHB_SOFT_RST REG_AP_AHB_AHB_RST
+#define SPRD_DSI_BASE g_dsi_base_addr
+
+extern unsigned long g_dsi_base_addr;
+
+
+struct autotst_dsi_context {
+ struct clk *clk_dsi;
+ bool is_inited;
+ uint32_t status;/*0- normal, 1- uninit, 2-abnormal*/
+ dsih_ctrl_t dsi_inst;
+};
+
+static struct autotst_dsi_context autotst_dsi_ctx;
+
+static uint32_t dsi_core_read_function(uint32_t addr, uint32_t offset)
+{
+ return sci_glb_read(addr + offset, 0xffffffff);
+}
+
+static void dsi_core_write_function(uint32_t addr, uint32_t offset, uint32_t data)
+{
+ sci_glb_write((addr + offset), data, 0xffffffff);
+}
+
+static void dsi_core_or_function(unsigned int addr,unsigned int data)
+{
+ sci_glb_write(addr,(sci_glb_read(addr, 0xffffffff) | data), 0xffffffff);
+}
+static void dsi_core_and_function(unsigned int addr,unsigned int data)
+{
+ sci_glb_write(addr,(sci_glb_read(addr, 0xffffffff) & data), 0xffffffff);
+}
+
+#if 0
+static irqreturn_t dsi_isr0(int irq, void *data)
+{
+ uint32_t reg_val = dsi_core_read_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_ERROR_ST0);
+ printk(KERN_ERR "autotst_dsi: [%s](0x%x)!\n", __FUNCTION__, reg_val);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dsi_isr1(int irq, void *data)
+{
+ uint32_t reg_val = dsi_core_read_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_ERROR_ST1);
+ printk(KERN_ERR "autotst_dsi: [%s](0x%x)!\n", __FUNCTION__, reg_val);
+ return IRQ_HANDLED;
+}
+#endif
+
+static int32_t dsi_edpi_setbuswidth(struct info_mipi * mipi)
+{
+ dsih_color_coding_t color_coding = 0;
+
+ switch(mipi->video_bus_width){
+ case 16:
+ color_coding = COLOR_CODE_16BIT_CONFIG1;
+ break;
+ case 18:
+ color_coding = COLOR_CODE_18BIT_CONFIG1;
+ break;
+ case 24:
+ color_coding = COLOR_CODE_24BIT;
+ break;
+ default:
+ printk(KERN_ERR "autotst_dsi:[%s] fail, invalid video_bus_width\n", __FUNCTION__);
+ return 0;
+ }
+
+#ifdef FB_DSIH_VERSION_1P21A
+ dsi_core_and_function((SPRD_MIPI_DSIC_BASE+R_DSI_HOST_DPI_COLOR_CODE),0xfffffff0);
+ dsi_core_or_function((SPRD_MIPI_DSIC_BASE+R_DSI_HOST_DPI_COLOR_CODE),color_coding);
+#else
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_DPI_CFG, ((uint32_t)color_coding<<2));
+#endif
+ return 0;
+}
+
+
+static int32_t dsi_edpi_init(void)
+{
+#ifdef FB_DSIH_VERSION_1P21A
+ dsi_core_write_function((uint32_t)SPRD_MIPI_DSIC_BASE, (uint32_t)R_DSI_HOST_EDPI_CMD_SIZE, 0x500);
+#else
+ dsi_core_write_function((uint32_t)SPRD_MIPI_DSIC_BASE, (uint32_t)DSI_EDPI_CFG, 0x10500);
+#endif
+ return 0;
+}
+
+static int32_t dsi_dpi_init(struct panel_spec* panel)
+{
+ dsih_dpi_video_t dpi_param;
+ dsih_error_t result;
+ struct info_mipi * mipi = panel->info.mipi;
+
+ dpi_param.no_of_lanes = mipi->lan_number;
+ dpi_param.byte_clock = mipi->phy_feq / 8;
+ dpi_param.pixel_clock = DISPC_DPI_CLOCK / 1000;
+#ifdef FB_DSIH_VERSION_1P21A
+ dpi_param.max_hs_to_lp_cycles = 4;//110;
+ dpi_param.max_lp_to_hs_cycles = 15;//10;
+#endif
+
+ switch(mipi->video_bus_width){
+ case 16:
+ dpi_param.color_coding = COLOR_CODE_16BIT_CONFIG1;
+ break;
+ case 18:
+ dpi_param.color_coding = COLOR_CODE_18BIT_CONFIG1;
+ break;
+ case 24:
+ dpi_param.color_coding = COLOR_CODE_24BIT;
+ break;
+ default:
+ printk(KERN_ERR "autotst_dsi:[%s] fail, invalid video_bus_width\n", __FUNCTION__);
+ break;
+ }
+
+ if(SPRDFB_POLARITY_POS == mipi ->h_sync_pol){
+ dpi_param.h_polarity = 1;
+ }
+
+ if(SPRDFB_POLARITY_POS == mipi ->v_sync_pol){
+ dpi_param.v_polarity = 1;
+ }
+
+ if(SPRDFB_POLARITY_POS == mipi ->de_pol){
+ dpi_param.data_en_polarity = 1;
+ }
+
+ dpi_param.h_active_pixels = panel->width;
+ dpi_param.h_sync_pixels = mipi->timing->hsync;
+ dpi_param.h_back_porch_pixels = mipi->timing->hbp;
+ dpi_param.h_total_pixels = panel->width + mipi->timing->hsync + mipi->timing->hbp + mipi->timing->hfp;
+
+ dpi_param.v_active_lines = panel->height;
+ dpi_param.v_sync_lines = mipi->timing->vsync;
+ dpi_param.v_back_porch_lines = mipi->timing->vbp;
+ dpi_param.v_total_lines = panel->height + mipi->timing->vsync + mipi->timing->vbp + mipi->timing->vfp;
+
+ dpi_param.receive_ack_packets = 0;
+ dpi_param.video_mode = VIDEO_BURST_WITH_SYNC_PULSES;
+ dpi_param.virtual_channel = 0;
+ dpi_param.is_18_loosely = 0;
+
+ result = mipi_dsih_dpi_video(&(autotst_dsi_ctx.dsi_inst), &dpi_param);
+ if(result != OK){
+ printk(KERN_ERR "autotst_dsi: [%s] mipi_dsih_dpi_video fail (%d)!\n", __FUNCTION__, result);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void dsi_log_error(const char * string)
+{
+ printk(string);
+}
+
+static int32_t dsi_module_init(struct panel_spec *panel)
+{
+ int ret = 0;
+ dsih_ctrl_t* dsi_instance = &(autotst_dsi_ctx.dsi_inst);
+ dphy_t *phy = &(dsi_instance->phy_instance);
+ struct info_mipi * mipi = panel->info.mipi;
+
+ pr_debug(KERN_INFO "autotst_dsi:[%s]\n", __FUNCTION__);
+
+ if(autotst_dsi_ctx.is_inited){
+ printk(KERN_INFO "autotst_dsi: dsi_module_init. is_inited==true!");
+ return 0;
+ }
+ else{
+ printk(KERN_INFO "autotst_dsi: dsi_module_init. call only once!\n");
+ }
+
+ phy->address = SPRD_MIPI_DSIC_BASE;
+ phy->core_read_function = dsi_core_read_function;
+ phy->core_write_function = dsi_core_write_function;
+ phy->log_error = dsi_log_error;
+ phy->log_info = NULL;
+ phy->reference_freq = DSI_PHY_REF_CLOCK;
+
+ dsi_instance->address = SPRD_MIPI_DSIC_BASE;
+ dsi_instance->color_mode_polarity =mipi->color_mode_pol;
+ dsi_instance->shut_down_polarity = mipi->shut_down_pol;
+ dsi_instance->core_read_function = dsi_core_read_function;
+ dsi_instance->core_write_function = dsi_core_write_function;
+ dsi_instance->log_error = dsi_log_error;
+ dsi_instance->log_info = NULL;
+ /*in our rtl implementation, this is max rd time, not bta time and use 15bits*/
+ dsi_instance->max_bta_cycles = 0x6000;//10;
+#ifndef FB_DSIH_VERSION_1P21A
+ dsi_instance->max_hs_to_lp_cycles = 4;//110;
+ dsi_instance->max_lp_to_hs_cycles = 15;//10;
+#endif
+ dsi_instance->max_lanes = mipi->lan_number;
+#if 0
+ ret = request_irq(IRQ_DSI_INTN0, dsi_isr0, IRQF_DISABLED, "DSI_INT0", &autotst_dsi_ctx);
+ if (ret) {
+ printk(KERN_ERR "autotst_dsi: dsi failed to request irq int0!\n");
+ }else{
+ printk(KERN_ERR "autotst_dsi: dsi request irq int0 OK!\n");
+ }
+
+ ret = request_irq(IRQ_DSI_INTN1, dsi_isr1, IRQF_DISABLED, "DSI_INT1", &autotst_dsi_ctx);
+ if (ret) {
+ printk(KERN_ERR "autotst_dsi: dsi failed to request irq int1!\n");
+ }else{
+ printk(KERN_ERR "autotst_dsi: dsi request irq int1 OK!\n");
+ }
+#endif
+ autotst_dsi_ctx.is_inited = true;
+
+ return 0;
+}
+
+static int32_t dsih_init(struct panel_spec *panel)
+{
+ dsih_error_t result = OK;
+ dsih_ctrl_t* dsi_instance = &(autotst_dsi_ctx.dsi_inst);
+ dphy_t *phy = &(dsi_instance->phy_instance);
+ struct info_mipi * mipi = panel->info.mipi;
+ int i = 0;
+#ifdef FB_DSIH_VERSION_1P21A
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_INT_MSK0, 0x1fffff);
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_INT_MSK1, 0x3ffff);
+#else
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_ERROR_MSK0, 0x1fffff);
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_ERROR_MSK1, 0x3ffff);
+#endif
+
+ if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
+ dsi_edpi_init();
+ }
+
+#ifndef FB_DSIH_VERSION_1P21A
+ dsi_instance->phy_feq = panel->info.mipi->phy_feq;
+#endif
+ result = mipi_dsih_open(dsi_instance);
+ if(OK != result){
+ printk(KERN_ERR "autotst_dsi: [%s]: mipi_dsih_open fail (%d)!\n", __FUNCTION__, result);
+ autotst_dsi_ctx.status = 1;
+ return -1;
+ }
+
+ result = mipi_dsih_dphy_configure(phy, mipi->lan_number, mipi->phy_feq);
+ if(OK != result){
+ printk(KERN_ERR "autotst_dsi: [%s]: mipi_dsih_dphy_configure fail (%d)!\n", __FUNCTION__, result);
+ autotst_dsi_ctx.status = 1;
+ return -1;
+ }
+
+ while(5 != (dsi_core_read_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_PHY_STATUS) & 5)){
+ if(0x0 == ++i%500000){
+ printk("autotst_dsi: [%s] warning: busy waiting!\n", __FUNCTION__);
+ }
+ }
+
+ if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
+ dsi_edpi_setbuswidth(mipi);
+ }
+
+ result = mipi_dsih_enable_rx(dsi_instance, 1);
+ if(OK != result){
+ printk(KERN_ERR "autotst_dsi: [%s]: mipi_dsih_enable_rx fail (%d)!\n", __FUNCTION__, result);
+ autotst_dsi_ctx.status = 1;
+ return -1;
+ }
+
+ result = mipi_dsih_ecc_rx(dsi_instance, 1);
+ if(OK != result){
+ printk(KERN_ERR "autotst_dsi: [%s]: mipi_dsih_ecc_rx fail (%d)!\n", __FUNCTION__, result);
+ autotst_dsi_ctx.status = 1;
+ return -1;
+ }
+
+ result = mipi_dsih_eotp_rx(dsi_instance, 1);
+ if(OK != result){
+ printk(KERN_ERR "autotst_dsi: [%s]: mipi_dsih_eotp_rx fail (%d)!\n", __FUNCTION__, result);
+ autotst_dsi_ctx.status = 1;
+ return -1;
+ }
+
+ result = mipi_dsih_eotp_tx(dsi_instance, 1);
+ if(OK != result){
+ printk(KERN_ERR "autotst_dsi: [%s]: mipi_dsih_eotp_tx fail (%d)!\n", __FUNCTION__, result);
+ autotst_dsi_ctx.status = 1;
+ return -1;
+ }
+
+ if(SPRDFB_MIPI_MODE_VIDEO == mipi->work_mode){
+ dsi_dpi_init(panel);
+ }
+
+#ifdef FB_DSIH_VERSION_1P21A
+ mipi_dsih_dphy_enable_nc_clk(&(dsi_instance->phy_instance), false);
+#endif
+ autotst_dsi_ctx.status = 0;
+
+ return 0;
+}
+
+static void dsi_enable(void)
+{
+ sci_glb_set(REG_AP_AHB_MISC_CKG_EN, BIT_DPHY_REF_CKG_EN);
+ sci_glb_set(REG_AP_AHB_MISC_CKG_EN, BIT_DPHY_CFG_CKG_EN);
+ sci_glb_set(DSI_REG_EB, DSI_BIT_EB);
+}
+
+static void dsi_disable(void)
+{
+ sci_glb_clr(REG_AP_AHB_MISC_CKG_EN, BIT_DPHY_REF_CKG_EN);
+ sci_glb_clr(REG_AP_AHB_MISC_CKG_EN, BIT_DPHY_CFG_CKG_EN);
+ sci_glb_clr(DSI_REG_EB, DSI_BIT_EB);
+}
+
+static void dsi_reset(void)
+{
+ sci_glb_set(DSI_AHB_SOFT_RST, BIT_DSI_SOFT_RST);
+ udelay(10);
+ sci_glb_clr(DSI_AHB_SOFT_RST, BIT_DSI_SOFT_RST);
+}
+
+static int32_t dsi_ready(struct panel_spec *panel)
+{
+ struct info_mipi * mipi = panel->info.mipi;
+
+ if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
+ mipi_dsih_cmd_mode(&(autotst_dsi_ctx.dsi_inst), 1);
+#ifdef FB_DSIH_VERSION_1P21A
+ mipi_dsih_dphy_enable_hs_clk(&(autotst_dsi_ctx.dsi_inst.phy_instance), true);
+#else
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_CMD_MODE_CFG, 0x1);
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_PHY_IF_CTRL, 0x1);
+#endif
+ }else{
+#ifdef FB_DSIH_VERSION_1P21A
+ mipi_dsih_dphy_enable_hs_clk(&(autotst_dsi_ctx.dsi_inst.phy_instance), true);
+#else
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_PHY_IF_CTRL, 0x1);
+#endif
+ mipi_dsih_video_mode(&(autotst_dsi_ctx.dsi_inst), 1);
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_PWR_UP, 0);
+ udelay(100);
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_PWR_UP, 1);
+ mdelay(3);
+#ifdef FB_DSIH_VERSION_1P21A
+ dsi_core_read_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_INT_ST0);
+ dsi_core_read_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_INT_ST1);
+#else
+ dsi_core_read_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_ERROR_ST0);
+ dsi_core_read_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_ERROR_ST1);
+#endif
+ }
+
+#ifdef FB_DSIH_VERSION_1P21A
+ //dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_INT_MSK0, 0x0);
+ //dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_INT_MSK1, 0x800);
+#else
+ //dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_ERROR_MSK0, 0x0);
+ //dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_ERROR_MSK1, 0x800);
+#endif
+ return 0;
+}
+
+void autotst_dsi_dump(void)
+{
+ int i = 0;
+ for(i=0;i<256;i+=16){
+ printk("autotst_dsi: %x: 0x%x, 0x%x, 0x%x, 0x%x\n", i, dsi_core_read_function(SPRD_MIPI_DSIC_BASE, i),
+ dsi_core_read_function(SPRD_MIPI_DSIC_BASE, i+4),
+ dsi_core_read_function(SPRD_MIPI_DSIC_BASE, i+8),
+ dsi_core_read_function(SPRD_MIPI_DSIC_BASE, i+12));
+ }
+ printk("**************************\n");
+}
+
+void autotst_dsi_dump1(void)
+{
+ int i = 0;
+ for(i=0;i<50;i++){
+ printk("autotst_dsi: 0x%x\n", dsi_core_read_function(SPRD_MIPI_DSIC_BASE, 0x60));
+ udelay(5);
+ }
+ printk("**************************\n");
+}
+
+int32_t autotst_dsi_init(struct panel_spec *panel)
+{
+ dsih_error_t result = OK;
+
+ printk(KERN_INFO "autotst_dsi:[%s]\n", __FUNCTION__);
+ dsi_enable();
+ dsi_reset();
+ dsi_module_init(panel);
+ result=dsih_init(panel);
+ dsi_ready(panel);
+
+ return result;
+}
+
+int32_t autotst_dsi_uninit(void)
+{
+ dsih_error_t result;
+ dsih_ctrl_t* dsi_instance = &(autotst_dsi_ctx.dsi_inst);
+
+ printk(KERN_INFO "autotst_dsi: [%s]\n",__FUNCTION__);
+
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_PHY_IF_CTRL, 0);
+ result = mipi_dsih_close(&(autotst_dsi_ctx.dsi_inst));
+ dsi_instance->status = NOT_INITIALIZED;
+
+ autotst_dsi_ctx.status = 1;
+
+ if(OK != result){
+ printk(KERN_ERR "autotst_dsi: [%s] fail (%d)!\n", __FUNCTION__, result);
+ return -1;
+ }
+
+ mdelay(10);
+ dsi_disable();
+ return 0;
+}
diff --git a/drivers/autotst/lcd_dummy.c b/drivers/autotst/lcd_dummy.c
new file mode 100644
index 00000000..8db38899
--- /dev/null
+++ b/drivers/autotst/lcd_dummy.c
@@ -0,0 +1,109 @@
+/* drivers/video/sprdfb/lcd_ssd2075_mipi.c
+ *
+ * Support for ssd2075 mipi LCD device
+ *
+ * Copyright (C) 2010 Spreadtrum
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/kernel.h>
+#include "lcd_dummy.h"
+//#define printk printf
+
+/*mcu panel*/
+static struct timing_mcu lcd_dummy_mcu_timing = {
+ .rcss = 15, // 15ns
+ .rlpw = 60,
+ .rhpw = 60,
+ .wcss = 10,
+ .wlpw = 35,
+ .whpw = 35,
+};
+
+static struct info_mcu lcd_dummy_mcu_info = {
+ .bus_mode = LCD_BUS_8080,
+ .bus_width = 24,
+ .bpp = 24, /*RGB88*/
+ .te_pol = SPRDFB_POLARITY_POS,
+ .te_sync_delay = 0,
+ .timing = &lcd_dummy_mcu_timing,
+};
+
+struct panel_spec lcd_dummy_mcu_spec = {
+ .width = 320,
+ .height = 480,
+ .type = LCD_MODE_MCU,
+ .info = {
+ .mcu = &lcd_dummy_mcu_info
+ },
+};
+
+/*rgb panel*/
+static struct timing_rgb lcd_dummy_rgb_timing = {
+ .hfp = 30, /* unit: pixel */
+ .hbp = 16,
+ .hsync = 1,
+ .vfp = 16, /*unit: line*/
+ .vbp = 16,
+ .vsync = 1,
+};
+
+static struct info_rgb lcd_dummy_rgb_info = {
+ .video_bus_width = 24, /*18,16*/
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .timing = &lcd_dummy_rgb_timing,
+};
+
+struct panel_spec lcd_dummy_rgb_spec = {
+ .width = 320,
+ .height = 480,
+ .type = LCD_MODE_RGB,
+ .info = {
+ .rgb = &lcd_dummy_rgb_info
+ },
+};
+
+/*mipi panel*/
+static struct timing_rgb lcd_dummy_mipi_timing = {
+ .hfp =50,
+ .hbp = 36,
+ .hsync =16,
+ .vfp = 12,
+ .vbp = 14,
+ .vsync = 2,
+};
+
+static struct info_mipi lcd_dummy_mipi_info = {
+ .work_mode = SPRDFB_MIPI_MODE_VIDEO,
+ .video_bus_width = 24, /*18,16*/
+ .lan_number = 4,
+ .phy_feq =100*1000,
+ .h_sync_pol = SPRDFB_POLARITY_POS,
+ .v_sync_pol = SPRDFB_POLARITY_POS,
+ .de_pol = SPRDFB_POLARITY_POS,
+ .te_pol = SPRDFB_POLARITY_POS,
+ .color_mode_pol = SPRDFB_POLARITY_NEG,
+ .shut_down_pol = SPRDFB_POLARITY_NEG,
+ .timing = &lcd_dummy_mipi_timing,
+};
+
+struct panel_spec lcd_dummy_mipi_spec = {
+ .width = 320,
+ .height = 480,
+ .type = LCD_MODE_DSI,
+ .info = {
+ .mipi = &lcd_dummy_mipi_info
+ },
+};
+
+
diff --git a/drivers/autotst/lcd_dummy.h b/drivers/autotst/lcd_dummy.h
new file mode 100644
index 00000000..44701652
--- /dev/null
+++ b/drivers/autotst/lcd_dummy.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 _LCD_DUMMY_H_
+#define _LCD_DUMMY_H_
+
+/* LCD mode */
+#define LCD_MODE_MCU 0
+#define LCD_MODE_RGB 1
+#define LCD_MODE_DSI 2
+
+/* bus mode */
+#define LCD_BUS_8080 0
+#define LCD_BUS_6800 1
+
+/* panel property */
+/* lcdc refresh, TE on, double timing, partial update*/
+#define PANEL_CAP_NORMAL 0x0
+
+/* only not support partial update*/
+#define PANEL_CAP_NOT_PARTIAL_UPDATE 0x1
+
+/* write register, grame have the same timing */
+#define PANEL_CAP_UNIQUE_TIMING 0x2
+
+/* lcd not support TE */
+#define PANEL_CAP_NOT_TEAR_SYNC 0x4
+
+/* only do command/data register, such as some mono oled display device */
+#define PANEL_CAP_MANUAL_REFRESH 0x8
+
+enum{
+ SPRDFB_PANEL_TYPE_MCU = 0,
+ SPRDFB_PANEL_TYPE_RGB,
+ SPRDFB_PANEL_TYPE_MIPI,
+ SPRDFB_PANEL_TYPE_LIMIT
+};
+
+enum{
+ SPRDFB_POLARITY_POS = 0,
+ SPRDFB_POLARITY_NEG,
+ SPRDFB_POLARITY_LIMIT
+};
+
+enum{
+ SPRDFB_MIPI_MODE_CMD = 0,
+ SPRDFB_MIPI_MODE_VIDEO,
+ SPRDFB_MIPI_MODE_LIMIT
+};
+
+/* MCU LCD specific properties */
+struct timing_mcu {
+ uint16_t rcss; /*unit: ns*/
+ uint16_t rlpw;
+ uint16_t rhpw;
+ uint16_t wcss;
+ uint16_t wlpw;
+ uint16_t whpw;
+};
+
+/* RGB LCD specific properties */
+struct timing_rgb {
+ uint16_t hfp;/*unit: pixel*/
+ uint16_t hbp;
+ uint16_t hsync;
+ uint16_t vfp; /*unit: line*/
+ uint16_t vbp;
+ uint16_t vsync;
+};
+
+struct info_mipi {
+ uint16_t work_mode; /*command_mode, video_mode*/
+ uint16_t video_bus_width;
+ uint32_t lan_number;
+ uint32_t phy_feq; /*unit:Hz*/
+ uint16_t h_sync_pol;
+ uint16_t v_sync_pol;
+ uint16_t de_pol;
+ uint16_t te_pol; /*only for command_mode*/
+ uint16_t color_mode_pol;
+ uint16_t shut_down_pol;
+ struct timing_rgb *timing;
+};
+
+struct info_rgb {
+ uint16_t video_bus_width;
+ uint16_t h_sync_pol;
+ uint16_t v_sync_pol;
+ uint16_t de_pol;
+ struct timing_rgb *timing;
+};
+
+struct info_mcu {
+ uint16_t bus_mode; /*8080, 6800*/
+ uint16_t bus_width;
+ uint16_t bpp;
+ uint16_t te_pol;
+ uint32_t te_sync_delay;
+ struct timing_mcu *timing;
+};
+
+/* LCD abstraction */
+struct panel_spec {
+ uint32_t cap;
+ uint16_t width;
+ uint16_t height;
+ uint16_t type; /*mcu, rgb, mipi*/
+ union {
+ struct info_mcu *mcu;
+ struct info_rgb *rgb;
+ struct info_mipi * mipi;
+ } info;
+};
+
+#endif
diff --git a/drivers/autotst/lcdc.c b/drivers/autotst/lcdc.c
new file mode 100644
index 00000000..2c61701e
--- /dev/null
+++ b/drivers/autotst/lcdc.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/fb.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+
+#include "lcdc_reg.h"
+
+
+//#define LCDC_DEBUG
+#ifdef LCDC_DEBUG
+#define LCDC_PRINT printk
+#else
+#define LCDC_PRINT(...)
+#endif
+
+
+int32_t lcm_send_cmd (uint32_t cmd)
+{
+ /* wait for that the ahb enter idle state */
+ while(lcdc_read(LCM_CTRL) & BIT(20));
+
+ lcdc_write(cmd, LCM_CMD);
+ return 0;
+}
+
+int32_t lcm_send_cmd_data (uint32_t cmd, uint32_t data)
+{
+ /* wait for that the ahb enter idle state */
+ while(lcdc_read(LCM_CTRL) & BIT(20));
+
+ lcdc_write(cmd, LCM_CMD);
+
+ /* wait for that the ahb enter idle state */
+ while(lcdc_read(LCM_CTRL) & BIT(20));
+
+ lcdc_write(data, LCM_DATA);
+ return 0;
+}
+
+int32_t lcm_send_data (uint32_t data)
+{
+ /* wait for that the ahb enter idle state */
+ while(lcdc_read(LCM_CTRL) & BIT(20));
+
+ lcdc_write(data, LCM_DATA);
+ return 0;
+}
+
+uint32_t lcm_read_data (void)
+{
+ /* wait for that the ahb enter idle state */
+ while(lcdc_read(LCM_CTRL) & BIT(20));
+ lcdc_write(1 << 24, LCM_DATA);
+ udelay(50);
+ return lcdc_read(LCM_RDDATA);
+}
+
+static struct clk * s_lcdcclk = NULL;
+
+int lcm_init(void)
+{
+ //int i;
+ unsigned int ctrl;
+
+ if( NULL == s_lcdcclk ) {
+ s_lcdcclk = clk_get(NULL, "clk_lcdc");
+ }
+ if( s_lcdcclk == NULL ) {
+ printk(KERN_ERR "can not get clk_lcdc!!!!!\n");
+ return -EFAULT;
+ }
+
+ clk_enable(s_lcdcclk);
+
+ ctrl = lcdc_read(LCM_CTRL);
+ printk("reg[LCM_CTRL] = %x\n", ctrl);
+
+ ctrl &= 0x10000;
+ ctrl |= 0x02828; // bus&pixel are 24bits
+
+ lcdc_write(ctrl, LCM_CTRL);
+
+ //lcdc_write((1 << 8) | (5 << 4) | 5, LCM_TIMING0);
+ //lcdc_write((1 << 8) | (5 << 4) | 5, LCM_TIMING1);
+
+ //for( i = LCM_CTRL; i <= LCM_RSTN; i += 4 ) {
+ // printk("reg[%x] = %x\n", i, lcdc_read(i));
+ //}
+
+ return 0;
+}
+
+int lcm_close(void)
+{
+ if( NULL != s_lcdcclk ) {
+ clk_disable(s_lcdcclk);
+ }
+ printk("lcm_close \n");
+ return 0;
+}
+
+
diff --git a/drivers/autotst/lcdc_reg.h b/drivers/autotst/lcdc_reg.h
new file mode 100644
index 00000000..cd190dd8
--- /dev/null
+++ b/drivers/autotst/lcdc_reg.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 _LCDC_REG_H_
+#define _LCDC_REG_H_
+
+#include <soc/sprd/hardware.h>
+
+#define AHB_CTL0 (SPRD_AHB_BASE + 0x200)
+#define AHB_SOFT_RST (SPRD_AHB_BASE + 0x210)
+
+/* LCDC regs offset */
+#define LCDC_CTRL (0x0000)
+#define LCDC_DISP_SIZE (0x0004)
+#define LCDC_LCM_START (0x0008)
+#define LCDC_LCM_SIZE (0x000c)
+#define LCDC_BG_COLOR (0x0010)
+#define LCDC_FIFO_STATUS (0x0014)
+
+#define LCDC_IMG_CTRL (0x0020)
+#define LCDC_IMG_Y_BASE_ADDR (0x0024)
+#define LCDC_IMG_UV_BASE_ADDR (0x0028)
+#define LCDC_IMG_SIZE_XY (0x002c)
+#define LCDC_IMG_PITCH (0x0030)
+#define LCDC_IMG_DISP_XY (0x0034)
+
+#define LCDC_OSD1_CTRL (0x0050)
+#define LCDC_OSD2_CTRL (0x0080)
+#define LCDC_OSD3_CTRL (0x00b0)
+#define LCDC_OSD4_CTRL (0x00e0)
+#define LCDC_OSD5_CTRL (0x0110)
+
+#define LCDC_OSD1_BASE_ADDR (0x0054)
+#define LCDC_OSD1_ALPHA_BASE_ADDR (0x0058)
+#define LCDC_OSD1_SIZE_XY (0x005c)
+#define LCDC_OSD1_PITCH (0x0060)
+#define LCDC_OSD1_DISP_XY (0x0064)
+#define LCDC_OSD1_ALPHA (0x0068)
+#define LCDC_OSD1_GREY_RGB (0x006c)
+#define LCDC_OSD1_CK (0x0070)
+
+#define LCDC_OSD2_BASE_ADDR (0x0084)
+#define LCDC_OSD2_SIZE_XY (0x008c)
+#define LCDC_OSD2_PITCH (0x0090)
+#define LCDC_OSD2_DISP_XY (0x0094)
+#define LCDC_OSD2_ALPHA (0x0098)
+#define LCDC_OSD2_GREY_RGB (0x009c)
+#define LCDC_OSD2_CK (0x00a0)
+
+#define LCDC_IRQ_EN (0x0170)
+#define LCDC_IRQ_CLR (0x0174)
+#define LCDC_IRQ_STATUS (0x0178)
+#define LCDC_IRQ_RAW (0x017c)
+
+#define LCM_CTRL (0x0180)
+#define LCM_TIMING0 (0x0184)
+#define LCM_TIMING1 (0x0188)
+#define LCM_RDDATA (0x018c)
+#define LCM_RSTN (0x0190)
+#define LCM_CMD (0x01A0)
+#define LCM_DATA (0x01A4)
+
+extern unsigned long g_dispc_base_addr;
+
+static inline uint32_t lcdc_read(uint32_t reg)
+{
+ return __raw_readl(SPRD_LCDC_BASE + reg);
+}
+
+static inline void lcdc_write(uint32_t value, uint32_t reg)
+{
+ __raw_writel(value, (SPRD_LCDC_BASE + reg));
+}
+
+static inline void lcdc_set_bits(uint32_t bits, uint32_t reg)
+{
+ lcdc_write(lcdc_read(reg) | bits, reg);
+}
+
+static inline void lcdc_clear_bits(uint32_t bits, uint32_t reg)
+{
+ lcdc_write(lcdc_read(reg) & ~bits, reg);
+}
+
+#endif
diff --git a/drivers/autotst/mipi_dsih_api.c b/drivers/autotst/mipi_dsih_api.c
new file mode 100644
index 00000000..b8904d81
--- /dev/null
+++ b/drivers/autotst/mipi_dsih_api.c
@@ -0,0 +1,1708 @@
+#include "mipi_dsih_api.h"
+#include "mipi_dsih_hal.h"
+#include "mipi_dsih_dphy.h"
+#include <linux/delay.h>
+
+/* whether to get debug messages (1) or not (0) */
+#define DEBUG 0
+
+#define PRECISION_FACTOR 1000
+#define VIDEO_PACKET_OVERHEAD 6
+#define NULL_PACKET_OVERHEAD 6
+#define SHORT_PACKET 4
+#define BLANKING_PACKET 6
+/** Version supported by this driver */
+static const uint32_t mipi_dsih_supported_versions[] = {0x3132302A, 0x3132312A};
+static const uint32_t mipi_dsih_no_of_versions = sizeof(mipi_dsih_supported_versions) / sizeof(uint32_t);
+
+/**
+ * Open controller instance
+ * - Check if driver is compatible with core version
+ * - Check if instance context data structure is not NULL
+ * - Bring up PHY for any transmissions in low power
+ * + Includes programming PLL to DEFAULT_BYTE_CLOCK
+ * - Bring up controller and perform initial configuration
+ * + Includes start all commands transmision in LP
+ * + Controller will not turn the bus around after commands
+ * + program counters
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return dsih_error_t
+ * @note this function must be called before any other function in this API
+ */
+dsih_error_t mipi_dsih_open(dsih_ctrl_t * instance)
+{
+ dsih_error_t err = OK;
+ uint32_t version = 0;
+ int i = 0;
+
+ if (instance == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ else if ((instance->core_read_function == 0) || (instance->core_write_function == 0))
+ {
+ return ERR_DSI_INVALID_IO;
+ }
+ else if (instance->status == INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ else if (mipi_dsih_dphy_open(&(instance->phy_instance)))
+ {
+ return ERR_DSI_PHY_INVALID;
+ }
+ else
+ {
+ instance->status = NOT_INITIALIZED;
+ version = mipi_dsih_hal_get_version(instance);
+ for (i = 0; i < mipi_dsih_no_of_versions; i++)
+ {
+ if (version == mipi_dsih_supported_versions[i])
+ {
+ break;
+ }
+ }
+ /* no matching supported version has been found*/
+ if (i >= mipi_dsih_no_of_versions)
+ {
+ if (instance->log_info != 0)
+ {
+ instance->log_info("sprdfb: driver does not support this core version 0x%lX", version);
+ }
+ return ERR_DSI_CORE_INCOMPATIBLE;
+ }
+ }
+ mipi_dsih_hal_power(instance, 0);
+ //mipi_dsih_hal_power(instance, 0);//Jessica
+ //mipi_dsih_hal_power(instance, 1);//Jessica
+ mipi_dsih_hal_dpi_color_mode_pol(instance, !instance->color_mode_polarity);
+ mipi_dsih_hal_dpi_shut_down_pol(instance, !instance->shut_down_polarity);
+ //err = mipi_dsih_phy_hs2lp_config(instance, instance->max_hs_to_lp_cycles);
+ //err |= mipi_dsih_phy_lp2hs_config(instance, instance->max_lp_to_hs_cycles);
+ mipi_dsih_hal_int_mask_0(instance, 0xffffff);
+ mipi_dsih_hal_int_mask_1(instance, 0xffffff);
+ err = mipi_dsih_phy_bta_time(instance, instance->max_bta_cycles);
+ if (err)
+ {
+ return ERR_DSI_OVERFLOW;
+ }
+ /* by default, return to LP during ALL, unless otherwise specified*/
+ mipi_dsih_hal_dpi_lp_during_hfp(instance, 1);
+ mipi_dsih_hal_dpi_lp_during_hbp(instance, 1);
+ mipi_dsih_hal_dpi_lp_during_vactive(instance, 1);
+ mipi_dsih_hal_dpi_lp_during_vfp(instance, 1);
+ mipi_dsih_hal_dpi_lp_during_vbp(instance, 1);
+ mipi_dsih_hal_dpi_lp_during_vsync(instance, 1);
+ /* by default, all commands are sent in LP */
+ mipi_dsih_hal_dcs_wr_tx_type(instance, 0, 1);
+ mipi_dsih_hal_dcs_wr_tx_type(instance, 1, 1);
+ mipi_dsih_hal_dcs_wr_tx_type(instance, 3, 1); /* long packet*/
+ mipi_dsih_hal_dcs_rd_tx_type(instance, 0, 1);
+ /*Jessica add to support max rd packet size command*/
+ mipi_dsih_hal_max_rd_packet_size_type(instance, 1);
+ mipi_dsih_hal_gen_wr_tx_type(instance, 0, 1);
+ mipi_dsih_hal_gen_wr_tx_type(instance, 1, 1);
+ mipi_dsih_hal_gen_wr_tx_type(instance, 2, 1);
+ mipi_dsih_hal_gen_wr_tx_type(instance, 3, 1); /* long packet*/
+ mipi_dsih_hal_gen_rd_tx_type(instance, 0, 1);
+ mipi_dsih_hal_gen_rd_tx_type(instance, 1, 1);
+ mipi_dsih_hal_gen_rd_tx_type(instance, 2, 1);
+ /* by default, RX_VC = 0, NO EOTp, EOTn, BTA, ECC rx and CRC rx */
+ mipi_dsih_hal_gen_rd_vc(instance, 0);
+ mipi_dsih_hal_gen_eotp_rx_en(instance, 0);
+ mipi_dsih_hal_gen_eotp_tx_en(instance, 0);
+ mipi_dsih_hal_bta_en(instance, 0);
+ mipi_dsih_hal_gen_ecc_rx_en(instance, 0);
+ mipi_dsih_hal_gen_crc_rx_en(instance, 0);
+ //mipi_dsih_hal_power(instance, 0);//Jessica
+ mipi_dsih_hal_power(instance, 1);//Jessica
+
+ /* dividing by 6 is aimed for max PHY frequency, 1GHz */
+ mipi_dsih_hal_tx_escape_division(instance, 4); //6 //Jessica
+ instance->status = INITIALIZED;
+ /* initialize pll so escape clocks could be generated at 864MHz, 1 lane */
+ /* however the high speed clock will not be requested */
+ //err = mipi_dsih_dphy_configure(&(instance->phy_instance), 1, DEFAULT_BYTE_CLOCK);
+ return err;
+}
+/**
+ * Close DSI Host driver
+ * - Free up resources and shutdown host controller and PHY
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return dsih_error_t
+ */
+dsih_error_t mipi_dsih_close(dsih_ctrl_t * instance)
+{
+ if (instance == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ mipi_dsih_hal_int_mask_0(instance, 0xffffff);
+ mipi_dsih_hal_int_mask_1(instance, 0xffffff);
+ mipi_dsih_dphy_close(&(instance->phy_instance));
+ mipi_dsih_hal_power(instance, 0);
+ instance->status = NOT_INITIALIZED;
+ return OK;
+}
+/**
+ * Enable return to low power mode inside video periods when timing allows
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param hfp allow to return to lp inside horizontal front porch pixels
+ * @param hbp allow to return to lp inside horizontal back porch pixels
+ * @param vactive allow to return to lp inside vertical active lines
+ * @param vfp allow to return to lp inside vertical front porch lines
+ * @param vbp allow to return to lp inside vertical back porch lines
+ * @param vsync allow to return to lp inside vertical sync lines
+ */
+void mipi_dsih_allow_return_to_lp(dsih_ctrl_t * instance, int hfp, int hbp, int vactive, int vfp, int vbp, int vsync)
+{
+ if(0 == instance)
+ {
+ return;
+ }
+
+ if (instance->status == INITIALIZED)
+ {
+ mipi_dsih_hal_dpi_lp_during_hfp(instance, hfp);
+ mipi_dsih_hal_dpi_lp_during_hbp(instance, hbp);
+ mipi_dsih_hal_dpi_lp_during_vactive(instance, vactive);
+ mipi_dsih_hal_dpi_lp_during_vfp(instance, vfp);
+ mipi_dsih_hal_dpi_lp_during_vbp(instance, vbp);
+ mipi_dsih_hal_dpi_lp_during_vsync(instance, vsync);
+ return;
+ }
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: [mipi_dsih_allow_return_to_lp] invalid instance");
+ }
+
+}
+/**
+ * Set DCS command packet transmission to low power
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param long_write command packets
+ * @param short_write command packets with none and one parameters
+ * @param short_read command packets with none parameters
+ */
+void mipi_dsih_dcs_cmd_lp_transmission(dsih_ctrl_t * instance, int long_write, int short_write, int short_read)
+{
+ if(0 == instance)
+ {
+ return;
+ }
+
+ if (instance->status == INITIALIZED)
+ {
+ mipi_dsih_hal_dcs_wr_tx_type(instance, 0, short_write);
+ mipi_dsih_hal_dcs_wr_tx_type(instance, 1, short_write);
+ mipi_dsih_hal_dcs_wr_tx_type(instance, 3, long_write); /* long packet*/
+ mipi_dsih_hal_dcs_rd_tx_type(instance, 0, short_read);
+ return;
+ }
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: [mipi_dsih_dcs_cmd_lp_transmission] invalid instance");
+ }
+
+}
+/**
+ * Set Generic interface packet transmission to low power
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param long_write command packets
+ * @param short_write command packets with none, one and two parameters
+ * @param short_read command packets with none, one and two parameters
+ */
+void mipi_dsih_gen_cmd_lp_transmission(dsih_ctrl_t * instance, int long_write, int short_write, int short_read)
+{
+ if(0 == instance)
+ {
+ return;
+ }
+
+ if (instance->status == INITIALIZED)
+ {
+ mipi_dsih_hal_gen_wr_tx_type(instance, 0, short_write);
+ mipi_dsih_hal_gen_wr_tx_type(instance, 1, short_write);
+ mipi_dsih_hal_gen_wr_tx_type(instance, 2, short_write);
+ mipi_dsih_hal_gen_wr_tx_type(instance, 3, long_write); /* long packet*/
+ mipi_dsih_hal_gen_rd_tx_type(instance, 0, short_read);
+ mipi_dsih_hal_gen_rd_tx_type(instance, 1, short_read);
+ mipi_dsih_hal_gen_rd_tx_type(instance, 2, short_read);
+ return;
+ }
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: [mipi_dsih_gen_cmd_lp_transmission] invalid instance");
+ }
+
+}
+/* packet handling */
+/**
+ * Enable all receiving activities (applying a Bus Turn Around).
+ * - Disabling using this function will stop all acknowledges by the
+ * peripherals and no interrupts from low-level protocol error reporting
+ * will be able to rise.
+ * - Enabling any receiving function (command or frame ACKs, ECC,
+ * tear effect ACK or EoTp receiving) will enable this automatically,
+ * but it must be EXPLICITLY be disabled to disabled all kinds of
+ * receiving functionality.
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable or disable
+ * @return error code
+ */
+dsih_error_t mipi_dsih_enable_rx(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_hal_bta_en(instance, enable);
+ return OK;
+}
+/**
+ * Enable command packet acknowledges by the peripherals
+ * - For interrupts to rise the monitored event must be registered
+ * using the event_register function
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable or disable
+ * @return error code
+ */
+dsih_error_t mipi_dsih_peripheral_ack(dsih_ctrl_t * instance, int enable)
+{
+ if (instance != 0)
+ {
+ if (instance->status == INITIALIZED)
+ {
+ mipi_dsih_hal_cmd_ack_en(instance, enable);
+ if (enable)
+ {
+ mipi_dsih_hal_bta_en(instance, 1);
+ }
+ return OK;
+ }
+ }
+ return ERR_DSI_INVALID_INSTANCE;
+}
+/**
+ * Enable tearing effect acknowledges by the peripherals (wait for TE)
+ * - It enables the following from the DSI specification
+ * "Since the timing of a TE event is, by definition, unknown to the host
+ * processor, the host processor shall give bus possession to the display
+ * module and then wait for up to one video frame period for the TE response.
+ * During this time, the host processor cannot send new commands, or requests
+ * to the display module, because it does not have bus possession."
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable or disable
+ * @return error code
+ */
+dsih_error_t mipi_dsih_tear_effect_ack(dsih_ctrl_t * instance, int enable)
+{
+ if (instance != 0)
+ {
+ if (instance->status == INITIALIZED)
+ {
+ mipi_dsih_hal_tear_effect_ack_en(instance, enable);
+ if (enable)
+ {
+ mipi_dsih_hal_bta_en(instance, 1);
+ }
+ return OK;
+ }
+ }
+ return ERR_DSI_INVALID_INSTANCE;
+}
+/**
+ * Enable the receiving of EoT packets at the end of LS transmission.
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable or disable
+ * @return error code
+ */
+dsih_error_t mipi_dsih_eotp_rx(dsih_ctrl_t * instance, int enable)
+{
+ if (instance != 0)
+ {
+ if (instance->status == INITIALIZED)
+ {
+ mipi_dsih_hal_gen_eotp_rx_en(instance, enable);
+ if (enable)
+ {
+ mipi_dsih_hal_bta_en(instance, 1);
+ }
+ return OK;
+ }
+ }
+ return ERR_DSI_INVALID_INSTANCE;
+}
+/**
+ * Enable the listening to ECC bytes. This allows for recovering from
+ * 1 bit errors. To report ECC events, the ECC events should be registered
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable or disable
+ * @return error code
+ */
+dsih_error_t mipi_dsih_ecc_rx(dsih_ctrl_t * instance, int enable)
+{
+ if (instance != 0)
+ {
+ if (instance->status == INITIALIZED)
+ {
+ mipi_dsih_hal_gen_ecc_rx_en(instance, enable);
+ if (enable)
+ {
+ mipi_dsih_hal_bta_en(instance, 1);
+ }
+ return OK;
+ }
+ }
+ return ERR_DSI_INVALID_INSTANCE;
+}
+/**
+ * Enable the sending of EoT (End of Transmission) packets at the end of HS
+ * transmission. It was made optional in the DSI spec. for retro-compatibility.
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable or disable
+ * @return error code
+ */
+dsih_error_t mipi_dsih_eotp_tx(dsih_ctrl_t * instance, int enable)
+{
+ if (instance != 0)
+ {
+ if (instance->status == INITIALIZED)
+ {
+ mipi_dsih_hal_gen_eotp_tx_en(instance, enable);
+ return OK;
+ }
+ }
+ return ERR_DSI_INVALID_INSTANCE;
+}
+/**
+ * Configure DPI video interface
+ * - If not in burst mode, it will compute the video and null packet sizes
+ * according to necessity
+ * - Configure timers for data lanes and/or clock lane to return to LP when
+ * bandwidth is not filled by data
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param video_params pointer to video stream-to-send information
+ * @return error code
+ */
+dsih_error_t mipi_dsih_dpi_video(dsih_ctrl_t * instance, dsih_dpi_video_t * video_params)
+{
+ dsih_error_t err_code = OK;
+ uint16_t bytes_per_pixel_x100 = 0; /* bpp x 100 because it can be 2.25 */
+ uint16_t video_size = 0;
+ uint32_t ratio_clock_xPF = 0; /* holds dpi clock/byte clock times precision factor */
+ uint16_t null_packet_size = 0;
+ uint8_t video_size_step = 1;
+ uint32_t hs_timeout = 0;
+ uint32_t total_bytes = 0;
+ uint32_t bytes_per_chunk = 0;
+ uint32_t no_of_chunks = 0;
+ uint32_t bytes_left = 0;
+ uint32_t chunk_overhead = 0;
+ int counter = 0;
+ /* check DSI controller instance */
+ if ((instance == 0) || (video_params == 0))
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (video_params->no_of_lanes > instance->max_lanes)
+ {
+ return ERR_DSI_OUT_OF_BOUND;
+ }
+ /* set up phy pll to required lane clock */
+ err_code = mipi_dsih_phy_hs2lp_config(instance, video_params->max_hs_to_lp_cycles);
+ err_code |= mipi_dsih_phy_lp2hs_config(instance, video_params->max_lp_to_hs_cycles);
+ err_code = mipi_dsih_phy_clk_hs2lp_config(instance, video_params->max_clk_hs_to_lp_cycles);
+ err_code |= mipi_dsih_phy_clk_lp2hs_config(instance, video_params->max_clk_lp_to_hs_cycles);
+ video_params->non_continuous_clock = 0; // 1.21a new feature, set 1 result in half-bottom snow screen , disbale it
+ mipi_dsih_non_continuous_clock(instance,video_params->non_continuous_clock);
+ //begin--frank
+ //err_code = mipi_dsih_dphy_configure(&(instance->phy_instance), video_params->no_of_lanes, video_params->byte_clock * 8);
+ //if (err_code)
+ //{
+ // return err_code;
+ //}
+ //end--frank
+ ratio_clock_xPF = (video_params->byte_clock * PRECISION_FACTOR) / (video_params->pixel_clock);
+ video_size = video_params->h_active_pixels;
+ /* set up ACKs and error reporting */
+ mipi_dsih_hal_dpi_frame_ack_en(instance, video_params->receive_ack_packets);
+ if (video_params->receive_ack_packets)
+ { /* if ACK is requested, enable BTA, otherwise leave as is */
+ mipi_dsih_hal_bta_en(instance, 1);
+ }
+ /* mipi_dsih_hal_gen_cmd_mode_en(instance, 0); */
+ mipi_dsih_hal_dpi_video_mode_en(instance, 1);
+ /* get bytes per pixel and video size step (depending if loosely or not */
+ switch (video_params->color_coding)
+ {
+ case COLOR_CODE_16BIT_CONFIG1:
+ case COLOR_CODE_16BIT_CONFIG2:
+ case COLOR_CODE_16BIT_CONFIG3:
+ bytes_per_pixel_x100 = 200;
+ video_size_step = 1;
+ break;
+ case COLOR_CODE_18BIT_CONFIG1:
+ case COLOR_CODE_18BIT_CONFIG2:
+ mipi_dsih_hal_dpi_18_loosely_packet_en(instance, video_params->is_18_loosely);
+ bytes_per_pixel_x100 = 225;
+ if (!video_params->is_18_loosely)
+ { /* 18bits per pixel and NOT loosely, packets should be multiples of 4 */
+ video_size_step = 4;
+ /* round up active H pixels to a multiple of 4 */
+ for (; (video_size % 4) != 0; video_size++)
+ {
+ ;
+ }
+ }
+ else
+ {
+ video_size_step = 1;
+ }
+ break;
+ case COLOR_CODE_24BIT:
+ bytes_per_pixel_x100 = 300;
+ video_size_step = 1;
+ break;
+ case COLOR_CODE_20BIT_YCC422_LOOSELY:
+ bytes_per_pixel_x100 = 250;
+ video_size_step = 2;
+ /* round up active H pixels to a multiple of 2 */
+ if ((video_size % 2) != 0)
+ {
+ video_size += 1;
+ }
+ break;
+ case COLOR_CODE_24BIT_YCC422:
+ bytes_per_pixel_x100 = 300;
+ video_size_step = 2;
+ /* round up active H pixels to a multiple of 2 */
+ if ((video_size % 2) != 0)
+ {
+ video_size += 1;
+ }
+ break;
+ case COLOR_CODE_16BIT_YCC422:
+ bytes_per_pixel_x100 = 200;
+ video_size_step = 2;
+ /* round up active H pixels to a multiple of 2 */
+ if ((video_size % 2) != 0)
+ {
+ video_size += 1;
+ }
+ break;
+ case COLOR_CODE_30BIT:
+ bytes_per_pixel_x100 = 375;
+ video_size_step = 2;
+ break;
+ case COLOR_CODE_36BIT:
+ bytes_per_pixel_x100 = 450;
+ video_size_step = 2;
+ break;
+ case COLOR_CODE_12BIT_YCC420:
+ bytes_per_pixel_x100 = 150;
+ video_size_step = 2;
+ /* round up active H pixels to a multiple of 2 */
+ if ((video_size % 2) != 0)
+ {
+ video_size += 1;
+ }
+ break;
+ default:
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: invalid color coding");
+ }
+ err_code = ERR_DSI_COLOR_CODING;
+ break;
+ }
+ if (err_code == OK)
+ {
+ err_code = mipi_dsih_hal_dpi_color_coding(instance, video_params->color_coding);
+ }
+ if (err_code != OK)
+ {
+ return err_code;
+ }
+ mipi_dsih_hal_dpi_video_mode_type(instance, video_params->video_mode);
+ mipi_dsih_hal_dpi_hline(instance, (uint16_t)((video_params->h_total_pixels * ratio_clock_xPF) / PRECISION_FACTOR));
+ mipi_dsih_hal_dpi_hbp(instance, ((video_params->h_back_porch_pixels * ratio_clock_xPF) / PRECISION_FACTOR));
+ mipi_dsih_hal_dpi_hsa(instance, ((video_params->h_sync_pixels * ratio_clock_xPF) / PRECISION_FACTOR));
+ mipi_dsih_hal_dpi_vactive(instance, video_params->v_active_lines);
+ mipi_dsih_hal_dpi_vfp(instance, video_params->v_total_lines - (video_params->v_back_porch_lines + video_params->v_sync_lines + video_params->v_active_lines));
+ mipi_dsih_hal_dpi_vbp(instance, video_params->v_back_porch_lines);
+ mipi_dsih_hal_dpi_vsync(instance, video_params->v_sync_lines);
+ mipi_dsih_hal_dpi_hsync_pol(instance, !video_params->h_polarity);
+ mipi_dsih_hal_dpi_vsync_pol(instance, !video_params->v_polarity);
+ mipi_dsih_hal_dpi_dataen_pol(instance, !video_params->data_en_polarity);
+ /* HS timeout */
+ hs_timeout = ((video_params->h_total_pixels * video_params->v_active_lines) + (DSIH_PIXEL_TOLERANCE * bytes_per_pixel_x100) / 100);
+ for (counter = 0x80; (counter < hs_timeout) && (counter > 2); counter--)
+ {
+ if ((hs_timeout % counter) == 0)
+ {
+ mipi_dsih_hal_timeout_clock_division(instance, counter);
+ mipi_dsih_hal_lp_rx_timeout(instance, (uint16_t)(hs_timeout / counter));
+ mipi_dsih_hal_hs_tx_timeout(instance, (uint16_t)(hs_timeout / counter));
+ break;
+ }
+ }
+ /* TX_ESC_CLOCK_DIV must be less than 20000KHz */
+ mipi_dsih_hal_tx_escape_division(instance, 4); //6 //Jessia
+ /* video packetisation */
+ if (video_params->video_mode == VIDEO_BURST_WITH_SYNC_PULSES)
+ { /* BURST */
+ mipi_dsih_hal_dpi_null_packet_en(instance, 0);
+ mipi_dsih_hal_dpi_multi_packet_en(instance, 0);
+ err_code = mipi_dsih_hal_dpi_null_packet_size(instance, 0);
+ err_code = err_code? err_code: mipi_dsih_hal_dpi_chunks_no(instance, 1);
+ err_code = err_code? err_code: mipi_dsih_hal_dpi_video_packet_size(instance, video_size);
+ if (err_code != OK)
+ {
+ return err_code;
+ }
+ /* BURST by default, returns to LP during ALL empty periods - energy saving */
+ mipi_dsih_hal_dpi_lp_during_hfp(instance, 1);
+#if defined(CONFIG_FB_SCX35) && defined(CONFIG_FB_LCD_SSD2075_MIPI)
+ mipi_dsih_hal_dpi_lp_during_hbp(instance, 0);//forbit return to lp during hbp
+#else
+ mipi_dsih_hal_dpi_lp_during_hbp(instance, 1);
+#endif
+ mipi_dsih_hal_dpi_lp_during_vactive(instance, 1);
+ mipi_dsih_hal_dpi_lp_during_vfp(instance, 1);
+ mipi_dsih_hal_dpi_lp_during_vbp(instance, 1);
+ mipi_dsih_hal_dpi_lp_during_vsync(instance, 1);
+#if DEBUG
+ /* D E B U G */
+ if (instance->log_info != 0)
+ {
+ instance->log_info("sprdfb: burst video");
+ instance->log_info("sprdfb: h line time %ld", (uint16_t)((video_params->h_total_pixels * ratio_clock_xPF) / PRECISION_FACTOR));
+ instance->log_info("sprdfb: video_size %ld", video_size);
+ }
+#endif
+ }
+ else
+ { /* non burst transmission */
+ null_packet_size = 0;
+ /* bytes to be sent - first as one chunk */
+ bytes_per_chunk = (bytes_per_pixel_x100 * video_params->h_active_pixels) / 100 + VIDEO_PACKET_OVERHEAD;
+ /* bytes being received through the DPI interface per byte clock cycle */
+ total_bytes = (ratio_clock_xPF * video_params->no_of_lanes * (video_params->h_total_pixels - video_params->h_back_porch_pixels - video_params->h_sync_pixels)) / PRECISION_FACTOR;
+ /* check if the in pixels actually fit on the DSI link */
+ if (total_bytes >= bytes_per_chunk)
+ {
+ chunk_overhead = total_bytes - bytes_per_chunk;
+ /* overhead higher than 1 -> enable multi packets */
+ if (chunk_overhead > 1)
+ { /* MULTI packets */
+ for (video_size = video_size_step; video_size < video_params->h_active_pixels; video_size += video_size_step)
+ { /* determine no of chunks */
+ if ((((video_params->h_active_pixels * PRECISION_FACTOR) / video_size) % PRECISION_FACTOR) == 0)
+ {
+ no_of_chunks = video_params->h_active_pixels / video_size;
+ bytes_per_chunk = (bytes_per_pixel_x100 * video_size) / 100 + VIDEO_PACKET_OVERHEAD;
+ if (total_bytes >= (bytes_per_chunk * no_of_chunks))
+ {
+ bytes_left = total_bytes - (bytes_per_chunk * no_of_chunks);
+ break;
+ }
+ }
+ }
+ /* prevent overflow (unsigned - unsigned) */
+ if (bytes_left > (NULL_PACKET_OVERHEAD * no_of_chunks))
+ {
+ null_packet_size = (bytes_left - (NULL_PACKET_OVERHEAD * no_of_chunks)) / no_of_chunks;
+ if (null_packet_size > MAX_NULL_SIZE)
+ { /* avoid register overflow */
+ null_packet_size = MAX_NULL_SIZE;
+ }
+ }
+ }
+ else
+ { /* no multi packets */
+ no_of_chunks = 1;
+#if DEBUG
+ /* D E B U G */
+ if (instance->log_info != 0)
+ {
+ instance->log_info("sprdfb: no multi no null video");
+ instance->log_info("sprdfb: h line time %ld", (uint16_t)((video_params->h_total_pixels * ratio_clock_xPF) / PRECISION_FACTOR));
+ instance->log_info("sprdfb: video_size %ld", video_size);
+ }
+ /************************/
+#endif
+ /* video size must be a multiple of 4 when not 18 loosely */
+ for (video_size = video_params->h_active_pixels; (video_size % video_size_step) != 0; video_size++)
+ {
+ ;
+ }
+ }
+ }
+ else
+ {
+ instance->log_error("sprdfb: resolution cannot be sent to display through current settings");
+ err_code = ERR_DSI_OVERFLOW;
+ }
+ }
+ err_code = err_code? err_code: mipi_dsih_hal_dpi_chunks_no(instance, no_of_chunks);
+ err_code = err_code? err_code: mipi_dsih_hal_dpi_video_packet_size(instance, video_size);
+ err_code = err_code? err_code: mipi_dsih_hal_dpi_null_packet_size(instance, null_packet_size);
+ mipi_dsih_hal_dpi_null_packet_en(instance, null_packet_size > 0? 1: 0);
+ mipi_dsih_hal_dpi_multi_packet_en(instance, (no_of_chunks > 1)? 1: 0);
+#if DEBUG
+ /* D E B U G */
+ if (instance->log_info != 0)
+ {
+ instance->log_info("sprdfb: total_bytes %d", total_bytes);
+ instance->log_info("sprdfb: bytes_per_chunk %d", bytes_per_chunk);
+ instance->log_info("sprdfb: bytes left %d", bytes_left);
+ instance->log_info("sprdfb: null packets %d", null_packet_size);
+ instance->log_info("sprdfb: chunks %ld", no_of_chunks);
+ instance->log_info("sprdfb: video_size %ld", video_size);
+ }
+ /************************/
+#endif
+ mipi_dsih_hal_dpi_video_vc(instance, video_params->virtual_channel);
+ mipi_dsih_dphy_no_of_lanes(&(instance->phy_instance), video_params->no_of_lanes);
+ /* enable high speed clock */
+ //mipi_dsih_dphy_enable_hs_clk(&(instance->phy_instance), 1);//jessica, panel not init yet, could not set to hs, or result in err to some panel
+ return err_code;
+}
+/**
+ * Send a DCS write command
+ * It sends the User Command Set commands listed in the DCS specification and
+ * not the Manufacturer Command Set. To send the Manufacturer Commands use the
+ * packet on the generic packets sending function
+ * function sets the packet data type automatically
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param vc destination virtual channel
+ * @param params byte-addressed array of command parameters, including the
+ * command itself
+ * @param param_length length of the above array
+ * @return error code
+ * @note this function has an active delay to wait for the buffer to clear.
+ * The delay is limited to DSIH_FIFO_ACTIVE_WAIT x register access time
+ */
+dsih_error_t mipi_dsih_dcs_wr_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length)
+{
+ uint8_t packet_type = 0;
+// int i = 0;
+ if (params == 0)
+ {
+ return ERR_DSI_OUT_OF_BOUND;
+ }
+#if 0
+ if (param_length > 2)
+ {
+ i = 2;
+ }
+ switch (params[i])
+ {
+ case 0x39:
+ case 0x38:
+ case 0x34:
+ case 0x29:
+ case 0x28:
+ case 0x21:
+ case 0x20:
+ case 0x13:
+ case 0x12:
+ case 0x11:
+ case 0x10:
+ case 0x01:
+ case 0x00:
+ packet_type = 0x05; /* DCS short write no param */
+ break;
+ case 0x3A:
+ case 0x36:
+ case 0x35:
+ case 0x26:
+ packet_type = 0x15; /* DCS short write 1 param */
+ break;
+ case 0x44:
+ case 0x3C:
+ case 0x37:
+ case 0x33:
+ case 0x30:
+ case 0x2D:
+ case 0x2C:
+ case 0x2B:
+ case 0x2A:
+ packet_type = 0x39; /* DCS long write/write_LUT command packet */
+ break;
+ default:
+ if (instance->log_error != 0)
+ {
+ instance->log_error("invalid DCS command");
+ }
+ return ERR_DSI_INVALID_COMMAND;
+ }
+#else
+ switch(param_length)
+ {
+ case 1:
+ packet_type = 0x05; /* DCS short write no param */
+ break;
+ case 2:
+ packet_type = 0x15; /* DCS short write 1 param */
+ break;
+ default:
+ packet_type = 0x39; /* DCS long write/write_LUT command packet */
+ break;
+ }
+#endif
+ return mipi_dsih_gen_wr_packet(instance, vc, packet_type, params, param_length);
+}
+/**
+ * Enable command mode
+ * - This function shall be explicitly called before commands are send if they
+ * are to be sent in command mode and not interlaced with video
+ * - If video mode is ON, it will be turned off automatically
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param en enable/disable
+ */
+void mipi_dsih_cmd_mode(dsih_ctrl_t * instance, int en)
+{
+ if(0 == instance)
+ {
+ return;
+ }
+
+ if (instance->status == INITIALIZED)
+ {
+ mipi_dsih_hal_gen_cmd_mode_en(instance, en);
+ return;
+ }
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: [mipi_dsih_cmd_mode] invalid instance");
+ }
+
+}
+/**
+ * Enable video mode
+ * - If command mode is ON, it will be turned off automatically
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param en enable/disable
+ */
+void mipi_dsih_video_mode(dsih_ctrl_t * instance, int en)
+{
+ if(0 == instance)
+ {
+ return;
+ }
+
+ if (instance->status == INITIALIZED)
+ {
+ mipi_dsih_hal_dpi_video_mode_en(instance, en);
+ return;
+ }
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: [mipi_dsih_video_mode] invalid instance");
+ }
+
+}
+
+/**
+ * Get the current active mode
+ * - 1 command mode
+ * - 2 DPI video mode
+ */
+int mipi_dsih_active_mode(dsih_ctrl_t * instance)
+{
+ if (mipi_dsih_hal_gen_is_cmd_mode(instance))
+ {
+ return 1;
+ }
+ else if (mipi_dsih_hal_dpi_is_video_mode(instance))
+ {
+ return 2;
+ }
+ return 0;
+}
+/**
+ * Send a generic write command
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param vc destination virtual channel
+ * @param params byte-addressed array of command parameters
+ * @param param_length length of the above array
+ * @return error code
+ * @note this function has an active delay to wait for the buffer to clear.
+ * The delay is limited to DSIH_FIFO_ACTIVE_WAIT x register access time
+ */
+dsih_error_t mipi_dsih_gen_wr_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length)
+{
+ uint8_t data_type = 0;
+ switch(param_length)
+ {
+ case 0:
+ data_type = 0x03;
+ break;
+ case 1:
+ data_type = 0x13;
+ break;
+ case 2:
+ data_type = 0x23;
+ break;
+ default:
+ data_type = 0x29;
+ break;
+ }
+ return mipi_dsih_gen_wr_packet(instance, vc, data_type, params, param_length);
+}
+/**
+ * Send a packet on the generic interface
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param vc destination virtual channel
+ * @param data_type type of command, inserted in first byte of header
+ * @param params byte array of command parameters
+ * @param param_length length of the above array
+ * @return error code
+ * @note this function has an active delay to wait for the buffer to clear.
+ * The delay is limited to:
+ * (param_length / 4) x DSIH_FIFO_ACTIVE_WAIT x register access time
+ * @note the controller restricts the sending of .
+ * This function will not be able to send Null and Blanking packets due to
+ * controller restriction
+ */
+dsih_error_t mipi_dsih_gen_wr_packet(dsih_ctrl_t * instance, uint8_t vc, uint8_t data_type, uint8_t* params, uint16_t param_length)
+{
+ dsih_error_t err_code = OK;
+ /* active delay iterator */
+ int timeout = 0;
+ /* iterators */
+ int i = 0;
+ int j = 0;
+ /* holds padding bytes needed */
+ int compliment_counter = 0;
+ uint8_t* payload = 0;
+ /* temporary variable to arrange bytes into words */
+ uint32_t temp = 0;
+ uint16_t word_count = 0;
+ if (instance == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if ((params == 0) && (param_length != 0)) /* pointer NULL */
+ {
+ return ERR_DSI_OUT_OF_BOUND;
+ }
+ if (param_length > 2)
+ { /* long packet - write word count to header, and the rest to payload */
+ payload = params + (2 * sizeof(params[0]));
+ word_count = (params[1] << 8) | params[0];
+ if ((param_length - 2) < word_count)
+ {
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: sent > input payload. complemented with zeroes");
+ }
+ compliment_counter = (param_length - 2) - word_count;
+ }
+ else if ((param_length - 2) > word_count)
+ {
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: Overflow - input > sent. payload truncated");
+ }
+ }
+ for (i = 0; i < (param_length - 2); i += j)
+ {
+ temp = 0;
+ for (j = 0; (j < 4) && ((j + i) < (param_length - 2)); j++)
+ { /* temp = (payload[i + 3] << 24) | (payload[i + 2] << 16) | (payload[i + 1] << 8) | payload[i]; */
+ temp |= payload[i + j] << (j * 8);
+ }
+ /* check if payload Tx fifo is not full */
+ for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)
+ {
+ if (!mipi_dsih_hal_gen_packet_payload(instance, temp))
+ {
+ break;
+ }
+ }
+ if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))
+ {
+ return ERR_DSI_TIMEOUT;
+ }
+ }
+ /* if word count entered by the user more than actual parameters received
+ * fill with zeroes - a fail safe mechanism, otherwise controller will
+ * want to send data from an empty buffer */
+ for (i = 0; i < compliment_counter; i++)
+ {
+ /* check if payload Tx fifo is not full */
+ for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)
+ {
+ if (!mipi_dsih_hal_gen_packet_payload(instance, 0x00))
+ {
+ break;
+ }
+ }
+ if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))
+ {
+ return ERR_DSI_TIMEOUT;
+ }
+ }
+ }
+ for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)
+ {
+ /* check if payload Tx fifo is not full */
+ if (!mipi_dsih_hal_gen_cmd_fifo_full(instance))
+ {
+ if (param_length == 0)
+ {
+ err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, 0x0, 0x0);
+ }
+ else if (param_length == 1)
+ {
+ err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, 0x0, params[0]);
+ }
+ else
+ {
+ err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, params[1], params[0]);
+ }
+ break;
+ }
+ }
+ if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))
+ {
+ err_code = ERR_DSI_TIMEOUT;
+ }
+ return err_code;
+}
+/**
+ * Send a DCS READ command to peripheral
+ * function sets the packet data type automatically
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param vc destination virtual channel
+ * @param command DCS code
+ * @param bytes_to_read no of bytes to read (expected to arrive at buffer)
+ * @param read_buffer pointer to 8-bit array to hold the read buffer words
+ * return read_buffer_length
+ * @note this function has an active delay to wait for the buffer to clear.
+ * The delay is limited to 2 x DSIH_FIFO_ACTIVE_WAIT
+ * (waiting for command buffer, and waiting for receiving)
+ * @note this function will enable BTA
+ */
+uint16_t mipi_dsih_dcs_rd_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t command, uint8_t bytes_to_read, uint8_t* read_buffer)
+{
+ if (instance == 0)
+ {
+ return 0;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return 0;
+ }
+ switch (command)
+ {
+ case 0xA8:
+ case 0xA1:
+ case 0x45:
+ case 0x3E:
+ case 0x2E:
+ case 0x0F:
+ case 0x0E:
+ case 0x0D:
+ case 0x0C:
+ case 0x0B:
+ case 0x0A:
+ case 0x08:
+ case 0x07:
+ case 0x06:
+ /* COMMAND_TYPE 0x06 - DCS Read no params refer to DSI spec p.47 */
+ return mipi_dsih_gen_rd_packet(instance, vc, 0x06, 0x0, command, bytes_to_read, read_buffer);
+ default:
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: invalid DCS command");
+ }
+ return 0;
+ }
+ return 0;
+}
+/**
+ * Send Generic READ command to peripheral
+ * - function sets the packet data type automatically
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param vc destination virtual channel
+ * @param params byte array of command parameters
+ * @param param_length length of the above array
+ * @param bytes_to_read no of bytes to read (expected to arrive at buffer)
+ * @param read_buffer pointer to 8-bit array to hold the read buffer words
+ * return read_buffer_length
+ * @note this function has an active delay to wait for the buffer to clear.
+ * The delay is limited to 2 x DSIH_FIFO_ACTIVE_WAIT
+ * (waiting for command buffer, and waiting for receiving)
+ * @note this function will enable BTA
+ */
+uint16_t mipi_dsih_gen_rd_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length, uint8_t bytes_to_read, uint8_t* read_buffer)
+{
+ uint8_t data_type = 0;
+ if (instance == 0)
+ {
+ return 0;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return 0;
+ }
+ switch(param_length)
+ {
+ case 0:
+ data_type = 0x04;
+ return mipi_dsih_gen_rd_packet(instance, vc, data_type, 0x00, 0x00, bytes_to_read, read_buffer);
+ case 1:
+ data_type = 0x14;
+ return mipi_dsih_gen_rd_packet(instance, vc, data_type, 0x00, params[0], bytes_to_read, read_buffer);
+ case 2:
+ data_type = 0x24;
+ return mipi_dsih_gen_rd_packet(instance, vc, data_type, params[1], params[0], bytes_to_read, read_buffer);
+ default:
+ return 0;
+ }
+}
+/**
+ * Send READ packet to peripheral using the generic interface
+ * This will force command mode and stop video mode (because of BTA)
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param vc destination virtual channel
+ * @param data_type generic command type
+ * @param lsb_byte first command parameter
+ * @param msb_byte second command parameter
+ * @param bytes_to_read no of bytes to read (expected to arrive at buffer)
+ * @param read_buffer pointer to 8-bit array to hold the read buffer words
+ * return read_buffer_length
+ * @note this function has an active delay to wait for the buffer to clear.
+ * The delay is limited to 2 x DSIH_FIFO_ACTIVE_WAIT
+ * (waiting for command buffer, and waiting for receiving)
+ * @note this function will enable BTA
+ */
+uint16_t mipi_dsih_gen_rd_packet(dsih_ctrl_t * instance, uint8_t vc, uint8_t data_type, uint8_t msb_byte, uint8_t lsb_byte, uint8_t bytes_to_read, uint8_t* read_buffer)
+{
+ dsih_error_t err_code = OK;
+ int timeout = 0;
+ int counter = 0;
+ int i = 0;
+ int last_count = 0;
+ uint32_t temp[1] = {0};
+ if (instance == 0)
+ {
+ return 0;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return 0;
+ }
+ if (bytes_to_read < 1)
+ {
+ return 0;
+ }
+ if (read_buffer == 0)
+ {
+ return 0;
+ }
+#ifndef FB_CHECK_ESD_IN_VFP
+ /* make sure command mode is on */
+ mipi_dsih_cmd_mode(instance, 1);
+#endif
+ /* make sure receiving is enabled */
+ mipi_dsih_hal_bta_en(instance, 1);
+ /* listen to the same virtual channel as the one sent to */
+ mipi_dsih_hal_gen_rd_vc(instance, vc);
+ for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)
+ { /* check if payload Tx fifo is not full */
+ if (!mipi_dsih_hal_gen_cmd_fifo_full(instance))
+ {
+ mipi_dsih_hal_gen_packet_header(instance, vc, data_type, msb_byte, lsb_byte);
+ break;
+ }
+ }
+ if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))
+ {
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: tx rd command timed out");
+ }
+ return 0;
+ }
+ /* loop for the number of words to be read */
+ for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)
+ { /* check if command transaction is done */
+ if (!mipi_dsih_hal_gen_rd_cmd_busy(instance))
+ {
+ if (!mipi_dsih_hal_gen_read_fifo_empty(instance))
+ {
+ for (counter = 0; (!mipi_dsih_hal_gen_read_fifo_empty(instance)); counter += 4)
+ {
+ err_code = mipi_dsih_hal_gen_read_payload(instance, temp);
+ if (err_code)
+ {
+ return 0;
+ }
+ if (counter < bytes_to_read)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if ((counter + i) < bytes_to_read)
+ {
+ /* put 32 bit temp in 4 bytes of buffer passed by user*/
+ read_buffer[counter + i] = (uint8_t)(temp[0] >> (i * 8));
+ last_count = i + counter;
+ }
+ else
+ {
+ if ((uint8_t)(temp[0] >> (i * 8)) != 0x00)
+ {
+ last_count = i + counter;
+ }
+ }
+ }
+ }
+ else
+ {
+ last_count = counter;
+ for (i = 0; i < 4; i++)
+ {
+ if ((uint8_t)(temp[0] >> (i * 8)) != 0x00)
+ {
+ last_count = i + counter;
+ }
+ }
+ }
+ }
+ return last_count + 1;
+ }
+#ifdef FB_CHECK_ESD_IN_VFP
+ else if(timeout == (DSIH_FIFO_ACTIVE_WAIT - 1))//else
+#else
+ else
+#endif
+ {
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: rx buffer empty");
+ }
+ return 0;
+ }
+ }
+#ifdef FB_CHECK_ESD_IN_VFP
+ udelay(5);
+#endif
+ }
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: rx command timed out");
+ }
+ return 0;
+}
+/**
+ * Dump values stored in the DSI host core registers
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param all whether to dump all the registers, no register_config array need
+ * be provided if dump is to standard IO
+ * @param config array of register_config_t type where addresses and values are
+ * stored
+ * @param config_length the length of the config array
+ * @return the number of the registers that were read
+ */
+uint32_t mipi_dsih_dump_register_configuration(dsih_ctrl_t * instance, int all, register_config_t *config, uint16_t config_length)
+{
+ uint32_t current0 = 0;
+ uint16_t count = 0;
+ if (instance == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (all)
+ { /* dump all registers */
+ for (current0 = R_DSI_HOST_VERSION; current0 <= R_DSI_HOST_PHY_TMR_LPCLK_CFG; count++, current0 += (R_DSI_HOST_PWR_UP - R_DSI_HOST_VERSION))
+ {
+ if ((config_length == 0) || (config == 0) || count >= config_length)
+ { /* no place to write - write to STD IO */
+ if (instance->log_info != 0)
+ {
+ instance->log_info("sprdfb: DSI 0x%lX:0x%lX", current0, mipi_dsih_read_word(instance, current0));
+ }
+ }
+ else
+ {
+ config[count].addr = current0;
+ config[count].data = mipi_dsih_read_word(instance, current0);
+ }
+ }
+ }
+ else
+ {
+ if(config == 0)
+ {
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: invalid buffer");
+ }
+ }
+ else
+ {
+ for (count = 0; count < config_length; count++)
+ {
+ config[count].data = mipi_dsih_read_word(instance, config[count].addr);
+ }
+ }
+ }
+ return count;
+}
+/**
+ * Write values to DSI host core registers
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param config array of register_config_t type where register addresses and
+ * their new values are stored
+ * @param config_length the length of the config array
+ * @return the number of the registers that were written to
+ */
+uint32_t mipi_dsih_write_register_configuration(dsih_ctrl_t * instance, register_config_t *config, uint16_t config_length)
+{
+ uint16_t count = 0;
+ if (instance == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ for (count = 0; count < config_length; count++)
+ {
+ mipi_dsih_write_word(instance, config[count].addr, config[count].data);
+ }
+ return count;
+}
+/**
+ * Register a handler for a specific event
+ * - The handler will be called when this specific event occurs
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param event enum
+ * @param handler call back to handler function to handle the event
+ * @return error code
+ */
+dsih_error_t mipi_dsih_register_event(dsih_ctrl_t * instance, dsih_event_t event, void (*handler)(dsih_ctrl_t *, void *))
+{
+ uint32_t mask = 1;
+ uint32_t temp = 0;
+ if (event >= DSI_MAX_EVENT)
+ {
+ return ERR_DSI_INVALID_EVENT;
+ }
+ if (handler == 0)
+ {
+ return ERR_DSI_INVALID_HANDLE;
+ }
+ if (instance == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ instance->event_registry[event] = handler;
+ if (event < HS_CONTENTION)
+ {
+ temp = mipi_dsih_hal_int_get_mask_0(instance, 0xffffffff);
+ temp &= ~(mask << event);
+ temp |= (0 & mask) << event;
+ mipi_dsih_hal_int_mask_0(instance, temp);
+ }
+ else
+ {
+ temp = mipi_dsih_hal_int_get_mask_1(instance, 0xffffffff);
+ temp &= ~(mask << (event - HS_CONTENTION));
+ temp |= (0 & mask) << (event - HS_CONTENTION);
+ mipi_dsih_hal_int_mask_1(instance, temp);
+ if (event == RX_CRC_ERR)
+ { /* automatically enable CRC reporting */
+ mipi_dsih_hal_gen_crc_rx_en(instance, 1);
+ }
+ }
+ return OK;
+}
+/**
+ * Clear an already registered event
+ * - Callback of the handler will be removed
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param event enum
+ * @return error code
+ */
+dsih_error_t mipi_dsih_unregister_event(dsih_ctrl_t * instance, dsih_event_t event)
+{
+ uint32_t mask = 1;
+ uint32_t temp = 0;
+ if (event >= DSI_MAX_EVENT)
+ {
+ return ERR_DSI_INVALID_EVENT;
+ }
+ if (instance == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ instance->event_registry[event] = 0;
+ if (event < HS_CONTENTION)
+ {
+ temp = mipi_dsih_hal_int_get_mask_0(instance, 0xffffffff);
+ temp &= ~(mask << event);
+ temp |= (1 & mask) << event;
+ mipi_dsih_hal_int_mask_0(instance, temp);
+ }
+ else
+ {
+ temp = mipi_dsih_hal_int_get_mask_1(instance, 0xffffffff);
+ temp &= ~(mask << (event - HS_CONTENTION));
+ temp |= (1 & mask) << (event - HS_CONTENTION);
+ mipi_dsih_hal_int_mask_1(instance, temp);
+ if (event == RX_CRC_ERR)
+ { /* automatically disable CRC reporting */
+ mipi_dsih_hal_gen_crc_rx_en(instance, 0);
+ }
+ }
+ return OK;
+}
+/**
+ * Clear all registered events at once
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return error code
+ */
+dsih_error_t mipi_dsih_unregister_all_events(dsih_ctrl_t * instance)
+{
+ int i = 0;
+ if (instance == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (instance->status != INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ for (i = 0; i < DSI_MAX_EVENT; i++)
+ {
+ instance->event_registry[i] = 0;
+ }
+ mipi_dsih_hal_int_mask_0(instance, 0xffffff);
+ mipi_dsih_hal_int_mask_1(instance, 0xffffff);
+ /* automatically disable CRC reporting */
+ mipi_dsih_hal_gen_crc_rx_en(instance, 0);
+ return OK;
+}
+/**
+ * This event handler shall be called upon receiving any event
+ * it will call the specific callback (handler) registered for the invoking
+ * event. Registration is done beforehand using mipi_dsih_register_event
+ * its signature is void * so it could be OS agnostic (for it to be
+ * registered in any OS/Interrupt controller)
+ * @param param pointer to structure holding the DSI Host core information
+ * @note This function must be registered with the DSI IRQs
+ */
+void mipi_dsih_event_handler(void * param)
+{
+ dsih_ctrl_t * instance = (dsih_ctrl_t *)(param);
+ uint8_t i = 0;
+ uint32_t status_0;
+ uint32_t status_1;
+
+ if (instance == 0)
+ {
+ return;
+ }
+
+ status_0 = mipi_dsih_hal_int_status_0(instance, 0xffffffff);
+ status_1 = mipi_dsih_hal_int_status_1(instance, 0xffffffff);
+
+ for (i = 0; i < DSI_MAX_EVENT; i++)
+ {
+ if (instance->event_registry[i] != 0)
+ {
+ if (i < HS_CONTENTION)
+ {
+ if ((status_0 & (1 << i)) != 0)
+ {
+ instance->event_registry[i](instance, &i);
+ }
+ }
+ else
+ {
+ if ((status_1 & (1 << (i - HS_CONTENTION))) != 0)
+ {
+ instance->event_registry[i](instance, &i);
+ }
+ }
+ }
+ }
+}
+/**
+ * Reset the DSI Host controller
+ * - Sends a pulse to the shut down register
+ * @param instance pointer to structure holding the DSI Host core information
+ */
+void mipi_dsih_reset_controller(dsih_ctrl_t * instance)
+{
+ mipi_dsih_hal_power(instance, 0);
+ mipi_dsih_hal_power(instance, 1);
+}
+/**
+ * Shut down the DSI Host controller
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param shutdown (1) power up (0)
+ */
+void mipi_dsih_shutdown_controller(dsih_ctrl_t * instance, int shutdown)
+{
+ mipi_dsih_hal_power(instance, !shutdown);
+}
+/**
+ * Reset the PHY module being controlled by the DSI Host controller
+ * - Sends a pulse to the PPI reset signal
+ * @param instance pointer to structure holding the DSI Host core information
+ */
+void mipi_dsih_reset_phy(dsih_ctrl_t * instance)
+{
+ mipi_dsih_dphy_reset(&(instance->phy_instance), 0);
+ mipi_dsih_dphy_reset(&(instance->phy_instance), 1);
+}
+/**
+ * Shut down the PHY module being controlled by the DSI Host controller
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param shutdown (1) power up (0)
+ */
+void mipi_dsih_shutdown_phy(dsih_ctrl_t * instance, int shutdown)
+{
+ mipi_dsih_dphy_shutdown(&(instance->phy_instance), !shutdown);
+}
+
+/*
+sprd Aoke added for power saving while suspend
+*/
+void mipi_dsih_ulps_mode(dsih_ctrl_t * instance, int en)
+{
+ mipi_dsih_dphy_ulps_data_lanes(&(instance->phy_instance),en);
+ mipi_dsih_dphy_ulps_clk_lane(&(instance->phy_instance),en);
+}
+/**
+ * Configure the eDPI interface
+ * - Programs the controller to receive pixels on the DPI interface and send them
+ * as commands (write memory start and write memory continue) instead of a
+ * video stream.
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param video_params pointer to the command mode video parameters context
+ * @param send_setup_packets whether to send the setup packets from given info. These are: 1 - set pixel format; 2 - set column address; 3 - set page address
+ * @return error code
+ */
+dsih_error_t mipi_dsih_edpi_video(dsih_ctrl_t * instance, dsih_cmd_mode_video_t *video_params, int send_setup_packets)
+{
+ dsih_error_t err_code = OK;
+ uint8_t buf[7] = {0};
+ uint32_t bytes_per_pixel_x100 = 0;
+ mipi_dsih_hal_dpi_video_vc(instance, video_params->virtual_channel);
+ mipi_dsih_cmd_mode(instance, 1);
+ err_code = mipi_dsih_hal_dpi_color_coding(instance, video_params->color_coding);
+ /* define whether write memory commands will be sent in LP or HS */
+ err_code = err_code? err_code: mipi_dsih_hal_dcs_wr_tx_type(instance, 3, video_params->lp); /* long packet*/
+ if (send_setup_packets)
+ {
+ /* define pixel packing format - 1 param */
+ buf[0] = 0x3A;
+ /* colour depth: table 6 DCS spec. 3:1| 8:2| 12:3| 16:5| 18:6| 24:7*/
+ switch (video_params->color_coding)
+ {
+ case 0:
+ case 1:
+ case 2:
+ buf[1] = 5;
+ break;
+ case 3:
+ case 4:
+ buf[1] = 6;
+ break;
+ default:
+ buf[1] = 7;
+ break;
+ }
+ err_code = err_code? err_code: mipi_dsih_dcs_wr_cmd(instance, video_params->virtual_channel, buf, 2);
+ if (err_code)
+ {
+ instance->log_error("sprdfb: error setting up command video - colour depth");
+ }
+ /* set column address (left to right) - 4 param */
+ buf[0] = 0x05; /* cmd length */
+ buf[1] = 0x00;
+ buf[2] = 0x2A; /* cmd opcode */
+ buf[3] = (uint8_t)(video_params->h_start >> 8); /* payload start */
+ buf[4] = (uint8_t)(video_params->h_start);
+ buf[5] = (uint8_t)(video_params->h_active_pixels >> 8);
+ buf[6] = (uint8_t)(video_params->h_active_pixels);
+ err_code = err_code? err_code: mipi_dsih_dcs_wr_cmd(instance, video_params->virtual_channel, buf, 7);
+ if (err_code)
+ {
+ instance->log_error("sprdfb: error setting up command video - set column address");
+ }
+ /* set page address (top to bottom) 4 - param*/
+ buf[0] = 0x05; /* cmd length */
+ buf[1] = 0x00;
+ buf[2] = 0x2B; /* cmd opcode */
+ buf[3] = (uint8_t)(video_params->v_start >> 8); /* payload start */
+ buf[4] = (uint8_t)(video_params->v_start);
+ buf[5] = (uint8_t)(video_params->v_active_lines >> 8);
+ buf[6] = (uint8_t)(video_params->v_active_lines);
+ err_code = err_code? err_code: mipi_dsih_dcs_wr_cmd(instance, video_params->virtual_channel, buf, 7);
+ if (err_code)
+ {
+ instance->log_error("sprdfb: error setting up command video - set page address");
+ }
+ }
+ switch (video_params->color_coding)
+ {
+ case COLOR_CODE_16BIT_CONFIG1:
+ case COLOR_CODE_16BIT_CONFIG2:
+ case COLOR_CODE_16BIT_CONFIG3:
+ bytes_per_pixel_x100 = 200;
+ break;
+ case COLOR_CODE_18BIT_CONFIG1:
+ case COLOR_CODE_18BIT_CONFIG2:
+ bytes_per_pixel_x100 = 225;
+ break;
+ case COLOR_CODE_24BIT:
+ bytes_per_pixel_x100 = 300;
+ break;
+ case COLOR_CODE_20BIT_YCC422_LOOSELY:
+ bytes_per_pixel_x100 = 250;
+ break;
+ case COLOR_CODE_24BIT_YCC422:
+ bytes_per_pixel_x100 = 300;
+ break;
+ case COLOR_CODE_16BIT_YCC422:
+ bytes_per_pixel_x100 = 200;
+ break;
+ case COLOR_CODE_30BIT:
+ bytes_per_pixel_x100 = 375;
+ break;
+ case COLOR_CODE_36BIT:
+ bytes_per_pixel_x100 = 450;
+ break;
+ case COLOR_CODE_12BIT_YCC420:
+ bytes_per_pixel_x100 = 150;
+ break;
+ default:
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: invalid color coding");
+ }
+ err_code = ERR_DSI_COLOR_CODING;
+ break;
+ }
+ if (video_params->te)
+ {
+ mipi_dsih_hal_bta_en(instance, video_params->te);
+ /* enable tearing effect */
+ mipi_dsih_tear_effect_ack(instance, video_params->te);
+ buf[0] = 0x35;
+ err_code = mipi_dsih_dcs_wr_cmd(instance, video_params->virtual_channel, buf, 1);
+ }
+ mipi_dsih_dphy_enable_hs_clk(&(instance->phy_instance), 1);
+ if ((((WORD_LENGTH * FIFO_DEPTH) * 100) / bytes_per_pixel_x100) > video_params->h_active_pixels)
+ {
+ mipi_dsih_hal_edpi_max_allowed_size(instance, video_params->h_active_pixels);
+ }
+ else
+ {
+ mipi_dsih_hal_edpi_max_allowed_size(instance, (((WORD_LENGTH * FIFO_DEPTH) * 100) / bytes_per_pixel_x100));
+ }
+ return err_code;
+}
+
+/* PRESP Time outs */
+/**
+ * Timeout for peripheral (for controller to stay still) after LP data
+ * transmission write requests
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the
+ * link still, after sending a low power write operation. This period is
+ * measured in cycles of lanebyteclk
+ */
+void mipi_dsih_presp_timeout_low_power_write(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ mipi_dsih_hal_presp_timeout_low_power_write(instance, no_of_byte_cycles);
+}
+/**
+ * Timeout for peripheral (for controller to stay still) after LP data
+ * transmission read requests
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the
+ * link still, after sending a low power read operation. This period is
+ * measured in cycles of lanebyteclk
+ */
+void mipi_dsih_presp_timeout_low_power_read(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ mipi_dsih_hal_presp_timeout_low_power_read(instance, no_of_byte_cycles);
+}
+/**
+ * Timeout for peripheral (for controller to stay still) after HS data
+ * transmission write requests
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the
+ * link still, after sending a high-speed write operation. This period is
+ * measured in cycles of lanebyteclk
+ */
+void mipi_dsih_presp_timeout_high_speed_write(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ mipi_dsih_hal_presp_timeout_high_speed_write(instance, no_of_byte_cycles);
+}
+/**
+ * Timeout for peripheral between HS data transmission read requests
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the
+ * link still, after sending a high-speed read operation. This period is
+ * measured in cycles of lanebyteclk
+ */
+void mipi_dsih_presp_timeout_high_speed_read(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ mipi_dsih_hal_presp_timeout_high_speed_read(instance, no_of_byte_cycles);
+}
+/**
+ * Timeout for peripheral (for controller to stay still) after bus turn around
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the
+ * link still, after sending a BTA operation. This period is
+ * measured in cycles of lanebyteclk
+ */
+void mipi_dsih_presp_timeout_bta(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ mipi_dsih_hal_presp_timeout_bta(instance, no_of_byte_cycles);
+}
+uint16_t mipi_dsih_check_dbi_fifos_state(dsih_ctrl_t * instance)
+{
+ uint16_t cnt = 0;
+ while( cnt < 5000 && mipi_dsih_read_word(instance, R_DSI_HOST_CMD_PKT_STATUS) != 0x15)
+ {
+ cnt ++;
+ }
+ return (mipi_dsih_read_word(instance, R_DSI_HOST_CMD_PKT_STATUS) != 0x15) ? -1 : 1;
+}
+uint16_t mipi_dsih_check_ulpm_mode(dsih_ctrl_t * instance)
+{
+ return (mipi_dsih_read_word(instance, R_DSI_HOST_PHY_STATUS) != 0x1528) ? -1 : 1;
+}
diff --git a/drivers/autotst/mipi_dsih_api.h b/drivers/autotst/mipi_dsih_api.h
new file mode 100644
index 00000000..5208467a
--- /dev/null
+++ b/drivers/autotst/mipi_dsih_api.h
@@ -0,0 +1,134 @@
+/**
+ * @file mipi_dsih_api.h
+ *
+ * Synopsys Inc.
+ * SG DWC PT02
+ */
+/*
+ The Synopsys Software Driver and documentation (hereinafter "Software")
+ is an unsupported proprietary work of Synopsys, Inc. unless otherwise
+ expressly agreed to in writing between Synopsys and you.
+
+ The Software IS NOT an item of Licensed Software or Licensed Product under
+ any End User Software License Agreement or Agreement for Licensed Product
+ with Synopsys or any supplement thereto. Permission is hereby granted,
+ free of charge, to any person obtaining a copy of this software annotated
+ with this license and the Software, to deal in the Software without
+ restriction, including without limitation the rights to use, copy, modify,
+ merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so, subject
+ to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+ */
+#ifndef MIPI_DSIH_API_H_
+#define MIPI_DSIH_API_H_
+
+#include "mipi_dsih_local.h"
+
+/* general configuration functions */
+
+dsih_error_t mipi_dsih_open(dsih_ctrl_t * instance);
+
+dsih_error_t mipi_dsih_close(dsih_ctrl_t * instance);
+
+void mipi_dsih_reset_controller(dsih_ctrl_t * instance);
+
+void mipi_dsih_shutdown_controller(dsih_ctrl_t * instance, int shutdown);
+
+void mipi_dsih_reset_phy(dsih_ctrl_t * instance);
+
+void mipi_dsih_shutdown_phy(dsih_ctrl_t * instance, int shutdown);
+
+void mipi_dsih_ulps_mode(dsih_ctrl_t * instance, int en);//Aoke add
+/* packet handling */
+
+dsih_error_t mipi_dsih_enable_rx(dsih_ctrl_t * instance, int enable);
+
+dsih_error_t mipi_dsih_peripheral_ack(dsih_ctrl_t * instance, int enable);
+
+dsih_error_t mipi_dsih_tear_effect_ack(dsih_ctrl_t * instance, int enable);
+
+dsih_error_t mipi_dsih_eotp_rx(dsih_ctrl_t * instance, int enable);
+
+dsih_error_t mipi_dsih_ecc_rx(dsih_ctrl_t * instance, int enable);
+
+
+dsih_error_t mipi_dsih_eotp_tx(dsih_ctrl_t * instance, int enable);
+
+/* video mode functions */
+
+dsih_error_t mipi_dsih_dpi_video(dsih_ctrl_t * instance, dsih_dpi_video_t * video_params);
+
+void mipi_dsih_allow_return_to_lp(dsih_ctrl_t * instance, int hfp, int hbp, int vactive, int vfp, int vbp, int vsync);
+
+void mipi_dsih_video_mode(dsih_ctrl_t * instance, int en);
+
+/* command mode functions */
+
+dsih_error_t mipi_dsih_dcs_wr_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length);
+
+dsih_error_t mipi_dsih_gen_wr_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length);
+
+dsih_error_t mipi_dsih_gen_wr_packet(dsih_ctrl_t * instance, uint8_t vc, uint8_t data_type, uint8_t* params, uint16_t param_length);
+
+uint16_t mipi_dsih_dcs_rd_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t command, uint8_t bytes_to_read, uint8_t* read_buffer);
+
+uint16_t mipi_dsih_gen_rd_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length, uint8_t bytes_to_read, uint8_t* read_buffer);
+
+uint16_t mipi_dsih_gen_rd_packet(dsih_ctrl_t * instance, uint8_t vc, uint8_t data_type, uint8_t msb_byte, uint8_t lsb_byte, uint8_t bytes_to_read, uint8_t* read_buffer);
+
+void mipi_dsih_cmd_mode(dsih_ctrl_t * instance, int en);
+
+int mipi_dsih_active_mode(dsih_ctrl_t * instance);
+
+void mipi_dsih_dcs_cmd_lp_transmission(dsih_ctrl_t * instance, int long_write, int short_write, int short_read);
+
+void mipi_dsih_gen_cmd_lp_transmission(dsih_ctrl_t * instance, int long_write, int short_write, int short_read);
+
+dsih_error_t mipi_dsih_edpi_video(dsih_ctrl_t * instance, dsih_cmd_mode_video_t *video_params, int send_setup_packets);
+
+/* event handling functions */
+
+dsih_error_t mipi_dsih_register_event(dsih_ctrl_t * instance, dsih_event_t event, void (*handler)(dsih_ctrl_t *, void *));
+
+dsih_error_t mipi_dsih_unregister_event(dsih_ctrl_t * instance, dsih_event_t event);
+
+dsih_error_t mipi_dsih_unregister_all_events(dsih_ctrl_t * instance);
+
+void mipi_dsih_event_handler(void * param);
+
+/* PRESP Time outs */
+void mipi_dsih_presp_timeout_low_power_write(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+
+void mipi_dsih_presp_timeout_low_power_read(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+
+void mipi_dsih_presp_timeout_high_speed_write(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+
+void mipi_dsih_presp_timeout_high_speed_read(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+
+void mipi_dsih_presp_timeout_bta(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+
+/* read/write register functions */
+uint32_t mipi_dsih_dump_register_configuration(dsih_ctrl_t * instance, int all, register_config_t *config, uint16_t config_length);
+
+uint32_t mipi_dsih_write_register_configuration(dsih_ctrl_t * instance, register_config_t *config, uint16_t config_length);
+
+uint16_t mipi_dsih_check_dbi_fifos_state(dsih_ctrl_t * instance);
+
+uint16_t mipi_dsih_check_ulpm_mode(dsih_ctrl_t * instance);
+
+#endif /* MIPI_DSIH_API_H_ */
diff --git a/drivers/autotst/mipi_dsih_dphy.c b/drivers/autotst/mipi_dsih_dphy.c
new file mode 100644
index 00000000..c137e9d5
--- /dev/null
+++ b/drivers/autotst/mipi_dsih_dphy.c
@@ -0,0 +1,1082 @@
+/**
+ * @file mipi_dsih_dphy.c
+ * @brief D-PHY driver
+ *
+ * Synopsys Inc.
+ * SG DWC PT02
+ */
+#include "mipi_dsih_dphy.h"
+#define PRECISION_FACTOR (1000)
+/* Reference clock frequency divided by Input Frequency Division Ratio LIMITS */
+#define DPHY_DIV_UPPER_LIMIT (40000)
+#ifdef GEN_2
+#define DPHY_DIV_LOWER_LIMIT (5000)
+#else
+#define DPHY_DIV_LOWER_LIMIT (1000)
+#endif
+
+#if ((defined DWC_MIPI_DPHY_BIDIR_TSMC40LP) || (defined GEN_2))
+#define MIN_OUTPUT_FREQ (80)
+#elif defined DPHY2Btql
+#define MIN_OUTPUT_FREQ (200)
+#undef GEN_2
+#endif
+
+/**
+ * Initialise D-PHY module and power up
+ * @param phy pointer to structure which holds information about the d-phy
+ * module
+ * @return error code
+ */
+dsih_error_t mipi_dsih_dphy_open(dphy_t * phy)
+{
+ if (phy == 0)
+ {
+ return ERR_DSI_PHY_INVALID;
+ }
+ else if ((phy->core_read_function == 0) || (phy->core_write_function == 0))
+ {
+ return ERR_DSI_INVALID_IO;
+ }
+ else if (phy->status == INITIALIZED)
+ {
+ return ERR_DSI_PHY_INVALID;
+ }
+ phy->status = NOT_INITIALIZED;
+#if 0
+ mipi_dsih_dphy_reset(phy, 0);
+ mipi_dsih_dphy_stop_wait_time(phy, 0x1C);
+ mipi_dsih_dphy_no_of_lanes(phy, 1);
+ mipi_dsih_dphy_clock_en(phy, 1);
+ mipi_dsih_dphy_shutdown(phy, 1);
+ mipi_dsih_dphy_reset(phy, 1);
+#endif
+ phy->status = INITIALIZED;
+ return OK;
+}
+/**
+ * Configure D-PHY and PLL module to desired operation mode
+ * @param phy pointer to structure which holds information about the d-phy
+ * module
+ * @param no_of_lanes active
+ * @param output_freq desired high speed frequency
+ * @return error code
+ */
+ #ifdef GEN_2
+dsih_error_t mipi_dsih_dphy_configure(dphy_t * phy, uint8_t no_of_lanes, uint32_t output_freq)
+{
+ uint32_t loop_divider = 0; /* (M) */
+ uint32_t input_divider = 1; /* (N) */
+ uint8_t data[4]; /* maximum data for now are 4 bytes per test mode*/
+ uint8_t no_of_bytes = 0;
+ uint8_t i = 0;
+ uint8_t n=0;/* iterator */
+ uint8_t range = 0; /* ranges iterator */
+ int flag = 0;
+ struct
+ {
+ uint32_t loop_div; /* upper limit of loop divider range */
+ uint8_t cp_current; /* icpctrl */
+ uint8_t lpf_resistor; /* lpfctrl */
+ }
+ loop_bandwidth[] =
+
+ { /* gen 2 associates the charge pump current and LPF resistor with the
+ output frequency ranges (and thus we simplify here to use the
+ counter/pointer of the following structure) */
+ { 90, 0x02, 0x02}, { 100, 0x02, 0x02}, { 110, 0x02, 0x02},
+ { 130, 0x02, 0x01}, { 140, 0x02, 0x01}, { 150, 0x02, 0x01},
+ { 170, 0x09, 0x00}, { 180, 0x09, 0x01}, { 200, 0x09, 0x01},
+ { 220, 0x09, 0x04}, { 240, 0x09, 0x04}, { 250, 0x09, 0x04},
+ { 270, 0x06, 0x04}, { 300, 0x06, 0x04}, { 330, 0x09, 0x04},
+ { 360, 0x09, 0x04}, { 400, 0x09, 0x04}, { 450, 0x06, 0x04},
+ { 500, 0x06, 0x04}, { 550, 0x06, 0x04}, { 600, 0x06, 0x04},
+ { 650, 0x0A, 0x04}, { 700, 0x0A, 0x04}, { 750, 0x0A, 0x04},
+ { 800, 0x0A, 0x04}, { 850, 0x0A, 0x04}, { 900, 0x0A, 0x04},
+ { 950, 0x0B, 0x08}, {1000, 0x0B, 0x08}, {1050, 0x0B, 0x08},
+ {1100, 0x0B, 0x08}, {1150, 0x0B, 0x08}, {1200, 0x0B, 0x08},
+ {1250, 0x0B, 0x08}, {1300, 0x0B, 0x08}, {1350, 0x0B, 0x08},
+ {1400, 0x0B, 0x08}, {1450, 0x0B, 0x08}, {1500, 0x0B, 0x08}
+ };
+ uint32_t delta = 0;
+ uint32_t tmp_loop_divider = 0;
+ unsigned step = 0;
+
+ struct
+ {
+ uint32_t freq; /* upper margin of frequency range */
+ uint8_t hs_freq; /* hsfreqrange */
+ uint8_t vco_range; /* vcorange */
+ }
+ ranges[] =
+ {
+ { 90, 0x00, 0x00}, { 100, 0x10, 0x00}, { 110, 0x20, 0x00},
+ { 130, 0x01, 0x00}, { 140, 0x11, 0x00}, { 150, 0x21, 0x00},
+ { 170, 0x02, 0x00}, { 180, 0x12, 0x00}, { 200, 0x22, 0x00},
+ { 220, 0x03, 0x01}, { 240, 0x13, 0x01}, { 250, 0x23, 0x01},
+ { 270, 0x04, 0x01}, { 300, 0x14, 0x01}, { 330, 0x05, 0x02},
+ { 360, 0x15, 0x02}, { 400, 0x25, 0x02}, { 450, 0x06, 0x02},
+ { 500, 0x16, 0x02}, { 550, 0x07, 0x03}, { 600, 0x17, 0x03},
+ { 650, 0x08, 0x03}, { 700, 0x18, 0x03}, { 750, 0x09, 0x04},
+ { 800, 0x19, 0x04}, { 850, 0x29, 0x04}, { 900, 0x39, 0x04},
+ { 950, 0x0A, 0x05}, {1000, 0x1A, 0x05}, {1050, 0x2A, 0x05},
+ {1100, 0x3A, 0x05}, {1150, 0x0B, 0x06}, {1200, 0x1B, 0x06},
+ {1250, 0x2B, 0x06}, {1300, 0x3B, 0x06}, {1350, 0x0C, 0x07},
+ {1400, 0x1C, 0x07}, {1450, 0x2C, 0x07}, {1500, 0x3C, 0x07}
+ };
+
+ if (phy == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (phy->status < INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (output_freq < MIN_OUTPUT_FREQ)
+ {
+ return ERR_DSI_PHY_FREQ_OUT_OF_BOUND;
+ }
+
+ loop_divider = ((output_freq * (phy->reference_freq / DPHY_DIV_LOWER_LIMIT)) / phy->reference_freq);
+ /* here delta will account for the rounding */
+ delta = ((loop_divider * phy->reference_freq) / (phy->reference_freq / DPHY_DIV_LOWER_LIMIT)) - output_freq;
+ for (input_divider = 1 + (phy->reference_freq / DPHY_DIV_UPPER_LIMIT); ((phy->reference_freq / input_divider) >= DPHY_DIV_LOWER_LIMIT) && (!flag); input_divider++)
+ {
+ tmp_loop_divider = ((output_freq * input_divider) / (phy->reference_freq));
+ if ((tmp_loop_divider % 2) == 0)
+ { /* if even */
+ if (output_freq == (tmp_loop_divider * (phy->reference_freq / input_divider)))
+ { /* exact values found */
+ flag = 1;
+ loop_divider = tmp_loop_divider;
+ delta = output_freq - (tmp_loop_divider * (phy->reference_freq / input_divider));
+ /* variable was incremented before exiting the loop */
+ input_divider--;
+ }
+ if ((output_freq - (tmp_loop_divider * (phy->reference_freq / input_divider))) < delta)
+ { /* values found with smaller delta */
+ loop_divider = tmp_loop_divider;
+ delta = output_freq - (tmp_loop_divider * (phy->reference_freq / input_divider));
+ step = 1;
+ }
+ }
+ else
+ {
+ tmp_loop_divider += 1;
+ if (output_freq == (tmp_loop_divider * (phy->reference_freq / input_divider)))
+ { /* exact values found */
+ flag = 1;
+ loop_divider = tmp_loop_divider;
+ delta = (tmp_loop_divider * (phy->reference_freq / input_divider)) - output_freq;
+ /* variable was incremented before exiting the loop */
+ input_divider--;
+ }
+ if (((tmp_loop_divider * (phy->reference_freq / input_divider)) - output_freq) < delta)
+ { /* values found with smaller delta */
+ loop_divider = tmp_loop_divider;
+ delta = (tmp_loop_divider * (phy->reference_freq / input_divider)) - output_freq;
+ step = 0;
+ }
+ }
+ }
+ if (!flag)
+ {
+ input_divider = step + (loop_divider * phy->reference_freq) / output_freq;
+// phy->log_info("D-PHY: Approximated Frequency: %d KHz", (loop_divider * (phy->reference_freq / input_divider)));
+ }
+#ifdef CONFIG_FB_DYNAMIC_FREQ_SCALING
+ if (phy->phy_keep_work != true)
+#endif
+ {
+ /* get the PHY in power down mode (shutdownz=0) and reset it (rstz=0) to
+ avoid transient periods in PHY operation during re-configuration procedures. */
+ mipi_dsih_dphy_reset(phy, 0);
+ mipi_dsih_dphy_clock_en(phy, 0);
+ mipi_dsih_dphy_shutdown(phy, 0);
+ /* provide an initial active-high test clear pulse in TESTCLR */
+ mipi_dsih_dphy_test_clear(phy, 1);
+ mipi_dsih_dphy_test_clear(phy, 0);
+ for(n=0;n<100;n++){
+ ;
+ }
+ }
+ /* find ranges */
+ for (range = 0; (range < (sizeof(ranges)/sizeof(ranges[0]))) && ((output_freq / 1000) > ranges[range].freq); range++)
+ {
+ ;
+ }
+ if (range >= (sizeof(ranges)/sizeof(ranges[0])))
+ {
+ return ERR_DSI_PHY_FREQ_OUT_OF_BOUND;
+ }
+ /* set up board depending on environment if any */
+ if (phy->bsp_pre_config != 0)
+ {
+ phy->bsp_pre_config(phy, 0);
+ }
+
+ /* Jessica add - begin*/
+ data[0] = 0x83;//0x44;//0x44;//0x40; //0x40: ok for 200 clock lane lpx /*about 52ns*/
+ mipi_dsih_dphy_write(phy, 0x60, data, 1);
+// data[0] = 0x0; //0xA6;//0xC6;//0xC6;//0x86; //0x48: ok for 200 prepare time
+// mipi_dsih_dphy_write(phy, 0x61, data, 1);
+
+// data[0] = 0x0;//0x6a;//0x6a;//0x4a; //0x4a: ok for 200 zero time
+// mipi_dsih_dphy_write(phy, 0x62, data, 1);
+
+ data[0] = 0x83;//0x44;//0x40;//0x40; // 0x40: ok for 200 data lane lpx /*about 52ns*/
+ mipi_dsih_dphy_write(phy, 0x70, data, 1);
+
+// data[0] = 0x0;// 0x84;//0x96;//0x96;//0x86; //0x48: ok for 200 prepare time
+// mipi_dsih_dphy_write(phy, 0x71, data, 1);
+
+// data[0] = 0x0;//0x44;//0x44;//0x40; //0x4a: ok for 200 zero time
+// mipi_dsih_dphy_write(phy, 0x72, data, 1);
+
+ //data[0] = 0x44;
+ //mipi_dsih_dphy_write(phy, 0x73, data, 1);
+
+ //data[0] = 0x7F;
+ //mipi_dsih_dphy_write(phy, 0x74, data, 1);
+
+ /* Jessica add - end*/
+
+ data[0] = 0x70;
+ mipi_dsih_dphy_write(phy, 0x16, data, 1);
+
+ /* setup digital part */
+ /* hs frequency range [7]|[6:1]|[0]*/
+ data[0] = (0 << 7) | (ranges[range].hs_freq << 1) | 0;
+ //data[0] = (0 << 7) | (0x23 << 1) | 0;
+ /*From ASIC, we need unmask this code to make the frequency correct*/
+ mipi_dsih_dphy_write(phy, 0x44, data, 1); //Jessica remove for more accurate frequency
+ /* setup PLL */
+ /* vco range [7]|[6:3]|[2:1]|[0] */
+ data[0] = (1 << 7) | (ranges[range].vco_range << 3) | (0 << 1) | 0;
+ mipi_dsih_dphy_write(phy, 0x10, data, 1); //Jessica
+#ifdef TESTCHIP
+ /* for all Gen2 testchips, bypass LP TX enable idle low power */
+ data[0] = 0x80;
+ mipi_dsih_dphy_write(phy, 0x32, data, 1);
+ mipi_dsih_dphy_write(phy, 0x42, data, 1);
+ mipi_dsih_dphy_write(phy, 0x52, data, 1);
+ mipi_dsih_dphy_write(phy, 0x82, data, 1);
+ mipi_dsih_dphy_write(phy, 0x92, data, 1);
+#endif
+ if ((loop_divider % 2) != 0)
+ { /* only odd integers are allowed (1 will be subtracted upon writing,
+ see below) */
+ loop_divider -= 1;
+
+ }
+ /* gen 2 associates the charge pump current and LPF resistor with the
+ output frequency ranges (and thus we simplify here to use the
+ counter/pointer of the following structure) */
+ i = range;
+ data[0] = (0x00 << 6) | (0x01 << 5) | (0x01 << 4);
+
+ mipi_dsih_dphy_write(phy, 0x19, data, 1); //Jessica
+
+ /* PLL Lock bypass|charge pump current [7:4]|[3:0] */
+ data[0] = (0x00 << 4) | (loop_bandwidth[i].cp_current << 0);
+ mipi_dsih_dphy_write(phy, 0x11, data, 1); //Jessica
+ /* bypass CP default|bypass LPF default| LPF resistor [7]|[6]|[5:0] */
+ data[0] = (0x01 << 7) | (0x01 << 6) |(loop_bandwidth[i].lpf_resistor << 0);
+ mipi_dsih_dphy_write(phy, 0x12, data, 1);
+ /* PLL input divider ratio [7:0] */
+ data[0] = input_divider - 1;
+ mipi_dsih_dphy_write(phy, 0x17, data, 1); //Jessica
+
+ data[0] = 0x04; //short the delay time before BTA
+ mipi_dsih_dphy_write(phy, 0x07, data, 1);
+
+// data[0] = 1;
+// mipi_dsih_dphy_write(phy, 0xB0, data, 1);
+
+ data[0] = 0x8B;
+ mipi_dsih_dphy_write(phy, 0x22, data, 1);
+// data[1] = mipi_dsih_dphy_test_data_out(phy);
+// printk("sprdfb:mipi dphy config-->0x22 write:%x,read:%x \n",data[0],data[1]);
+
+ no_of_bytes = 2; /* pll loop divider (code 0x18) takes only 2 bytes (10 bits in data) */
+ for (i = 0; i < no_of_bytes; i++)
+ {
+ data[i] = ((uint8_t)((((loop_divider - 1) >> (5 * i)) & 0x1F) | (i << 7) ));
+ /* 7 is dependent on no_of_bytes
+ make sure 5 bits only of value are written at a time */
+ }
+ /* PLL loop divider ratio - SET no|reserved|feedback divider [7]|[6:5]|[4:0] */
+ mipi_dsih_dphy_write(phy, 0x18, data, no_of_bytes);
+ mipi_dsih_dphy_no_of_lanes(phy, no_of_lanes);
+#ifdef CONFIG_FB_DYNAMIC_FREQ_SCALING
+ if (phy->phy_keep_work != true)
+#endif
+ {
+ mipi_dsih_dphy_stop_wait_time(phy, 0x1C);
+ mipi_dsih_dphy_clock_en(phy, 1);
+ for(n=0;n<100;n++){
+ ;
+ }
+ mipi_dsih_dphy_shutdown(phy, 1);
+ for(n=0;n<100;n++){
+ ;
+ }
+ mipi_dsih_dphy_reset(phy, 1);
+ }
+ return OK;
+}
+#else
+dsih_error_t mipi_dsih_dphy_configure(dphy_t * phy, uint8_t no_of_lanes, uint32_t output_freq)
+{
+ uint32_t loop_divider = 0; /* (M) */
+ uint32_t input_divider = 1; /* (N) */
+ uint8_t data[4]; /* maximum data for now are 4 bytes per test mode*/
+ uint8_t no_of_bytes = 0;
+ uint8_t i = 0; /* iterator */
+ uint8_t n=0;/* iterator */
+ uint8_t range = 0; /* ranges iterator */
+ int flag = 0;
+#ifdef DWC_MIPI_DPHY_BIDIR_TSMC40LP
+ struct
+ {
+ uint32_t freq; /* upper margin of frequency range */
+ uint8_t hs_freq; /* hsfreqrange */
+ uint8_t vco_range; /* vcorange */
+ }
+ ranges[] =
+ {
+ {90, 0x00, 0x01}, {100, 0x10, 0x01}, {110, 0x20, 0x01},
+ {125, 0x01, 0x01}, {140, 0x11, 0x01}, {150, 0x21, 0x01},
+ {160, 0x02, 0x01}, {180, 0x12, 0x03}, {200, 0x22, 0x03},
+ {210, 0x03, 0x03}, {240, 0x13, 0x03}, {250, 0x23, 0x03},
+ {270, 0x04, 0x07}, {300, 0x14, 0x07}, {330, 0x24, 0x07},
+ {360, 0x15, 0x07}, {400, 0x25, 0x07}, {450, 0x06, 0x07},
+ {500, 0x16, 0x07}, {550, 0x07, 0x0f}, {600, 0x17, 0x0f},
+ {650, 0x08, 0x0f}, {700, 0x18, 0x0f}, {750, 0x09, 0x0f},
+ {800, 0x19, 0x0f}, {850, 0x0A, 0x0f}, {900, 0x1A, 0x0f},
+ {950, 0x2A, 0x0f}, {1000, 0x3A, 0x0f}
+ };
+ struct
+ {
+ uint32_t loop_div; /* upper limit of loop divider range */
+ uint8_t cp_current; /* icpctrl */
+ uint8_t lpf_resistor; /* lpfctrl */
+ }
+ loop_bandwidth[] =
+ {
+ {32, 0x06, 0x10}, {64, 0x06, 0x10}, {128, 0x0C, 0x08},
+ {256, 0x04, 0x04}, {512, 0x00, 0x01}, {768, 0x01, 0x01},
+ {1000, 0x02, 0x01}
+ };
+#elif defined DPHY2Btql
+ struct
+ {
+ uint32_t loop_div; /* upper limit of loop divider range */
+ uint8_t cp_current; /* icpctrl */
+ uint8_t lpf_resistor; /* lpfctrl */
+ }
+ loop_bandwidth[] =
+ {
+ {32, 0x0B, 0x00}, {64, 0x0A, 0x00}, {128, 0x09, 0x01},
+ {256, 0x08, 0x03}, {512, 0x08, 0x07}, {768, 0x08, 0x0F},
+ {1000, 0x08, 0x1F}
+ };
+#endif
+ if (phy == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (phy->status < INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ if (output_freq < MIN_OUTPUT_FREQ)
+ {
+ return ERR_DSI_PHY_FREQ_OUT_OF_BOUND;
+ }
+ /* find M and N dividers */
+ for (input_divider = 1 + (phy->reference_freq / DPHY_DIV_UPPER_LIMIT); ((phy->reference_freq / input_divider) >= DPHY_DIV_LOWER_LIMIT) && (!flag); input_divider++)
+ { /* here the >= DPHY_DIV_LOWER_LIMIT is a phy constraint, formula should be above 1 MHz */
+ if (((output_freq * input_divider) % (phy->reference_freq )) == 0)
+ { /* values found */
+ loop_divider = ((output_freq * input_divider) / (phy->reference_freq ));
+ if (loop_divider >= 12)
+ {
+ flag = 1;
+ }
+ }
+ }
+ if ((!flag) || ((phy->reference_freq / input_divider) < DPHY_DIV_LOWER_LIMIT))
+ { /* no exact value found in previous for loop */
+ /* this solution is not favourable as jitter would be maximum */
+ loop_divider = output_freq / DPHY_DIV_LOWER_LIMIT;
+ input_divider = phy->reference_freq / DPHY_DIV_LOWER_LIMIT;
+ }
+ else
+ { /* variable was incremented before exiting the loop */
+ input_divider--;
+ }
+ for (i = 0; (i < (sizeof(loop_bandwidth)/sizeof(loop_bandwidth[0]))) && (loop_divider > loop_bandwidth[i].loop_div); i++)
+ {
+ ;
+ }
+ if (i >= (sizeof(loop_bandwidth)/sizeof(loop_bandwidth[0])))
+ {
+ return ERR_DSI_PHY_FREQ_OUT_OF_BOUND;
+ }
+ printk("sprdfb: Gen1 D-PHY: Approximated Frequency: %d KHz\n", (loop_divider * (phy->reference_freq / input_divider)));
+#ifdef CONFIG_FB_DYNAMIC_FREQ_SCALING
+ if (phy->phy_keep_work != true)
+#endif
+ {
+ /* get the PHY in power down mode (shutdownz=0) and reset it (rstz=0) to
+ avoid transient periods in PHY operation during re-configuration procedures. */
+ mipi_dsih_dphy_reset(phy, 0);
+ mipi_dsih_dphy_clock_en(phy, 0);
+ mipi_dsih_dphy_shutdown(phy, 0);
+ /* provide an initial active-high test clear pulse in TESTCLR */
+ mipi_dsih_dphy_test_clear(phy, 1);
+ mipi_dsih_dphy_test_clear(phy, 0);
+ }
+#ifdef DWC_MIPI_DPHY_BIDIR_TSMC40LP
+ /* find ranges */
+ for (range = 0; (range < (sizeof(ranges)/sizeof(ranges[0]))) && ((output_freq / 1000) > ranges[range].freq); range++)
+ {
+ ;
+ }
+ if (range >= (sizeof(ranges)/sizeof(ranges[0])))
+ {
+ return ERR_DSI_PHY_FREQ_OUT_OF_BOUND;
+ }
+ /* set up board depending on environment if any */
+ if (phy->bsp_pre_config != 0)
+ {
+ phy->bsp_pre_config(phy, 0);
+ }
+
+ /* Jessica add - begin*/
+ data[0] = 0x42;//0x44;//0x44;//0x40; //0x40: ok for 200 clock lane lpx /*about 52ns*/
+ mipi_dsih_dphy_write(phy, 0x60, data, 1);
+ data[0] = 0x0; //0xA6;//0xC6;//0xC6;//0x86; //0x48: ok for 200 prepare time
+ mipi_dsih_dphy_write(phy, 0x61, data, 1);
+
+ data[0] = 0x0;//0x6a;//0x6a;//0x4a; //0x4a: ok for 200 zero time
+ mipi_dsih_dphy_write(phy, 0x62, data, 1);
+
+ data[0] = 0x42;//0x44;//0x40;//0x40; // 0x40: ok for 200 data lane lpx /*about 52ns*/
+ mipi_dsih_dphy_write(phy, 0x70, data, 1);
+
+ data[0] = 0x0;// 0x84;//0x96;//0x96;//0x86; //0x48: ok for 200 prepare time
+ mipi_dsih_dphy_write(phy, 0x71, data, 1);
+
+ data[0] = 0x0;//0x44;//0x44;//0x40; //0x4a: ok for 200 zero time
+ mipi_dsih_dphy_write(phy, 0x72, data, 1);
+
+ //data[0] = 0x44;
+ //mipi_dsih_dphy_write(phy, 0x73, data, 1);
+
+ //data[0] = 0x7F;
+ //mipi_dsih_dphy_write(phy, 0x74, data, 1);
+
+ /* Jessica add - end*/
+
+ /* setup digital part */
+ /* hs frequency range [7]|[6:1]|[0]*/
+ data[0] = (0 << 7) | (ranges[range].hs_freq << 1) | 0;
+ //data[0] = (0 << 7) | (0x23 << 1) | 0;
+ /*From ASIC, we need unmask this code to make the frequency correct*/
+ mipi_dsih_dphy_write(phy, 0x44, data, 1); //Jessica remove for more accurate frequency
+ /* setup PLL */
+ /* vco range [7]|[6:3]|[2:1]|[0] */
+ data[0] = (1 << 7) | (ranges[range].vco_range << 3) | (0 << 1) | 0;
+ mipi_dsih_dphy_write(phy, 0x10, data, 1); //Jessica
+ /* PLL reserved|Input divider control|Loop Divider Control|Post Divider Ratio [7:6]|[5]|[4]|[3:0] */
+ data[0] = (0x00 << 6) | (0x01 << 5) | (0x01 << 4) | (0x03 << 0); /* post divider default = 0x03 - it is only used for clock out 2*/
+ mipi_dsih_dphy_write(phy, 0x19, data, 1); //Jessica
+#elif defined DPHY2Btql
+ /* vco range [7:5]|[4]|[3]|[2:1]|[0] */
+ data[0] = ((((output_freq / 1000) > 500 )? 1: 0) << 4) | (1 << 3) | (0 << 1) | 0;
+ mipi_dsih_dphy_write(phy, 0x10, data, 1);
+#endif
+ /* PLL Lock bypass|charge pump current [7:4]|[3:0] */
+ data[0] = (0x00 << 4) | (loop_bandwidth[i].cp_current << 0);
+ mipi_dsih_dphy_write(phy, 0x11, data, 1); //Jessica
+ /* bypass CP default|bypass LPF default| LPF resistor [7]|[6]|[5:0] */
+ data[0] = (0x01 << 7) | (0x01 << 6) |(loop_bandwidth[i].lpf_resistor << 0);
+ mipi_dsih_dphy_write(phy, 0x12, data, 1);
+ /* PLL input divider ratio [7:0] */
+ data[0] = input_divider - 1;
+ mipi_dsih_dphy_write(phy, 0x17, data, 1); //Jessica
+
+ data[0] = 0x04; //short the delay time before BTA
+ mipi_dsih_dphy_write(phy, 0x07, data, 1);
+
+// data[0] = 1;
+// mipi_dsih_dphy_write(phy, 0xB0, data, 1);
+
+ data[0] = 0x8B;
+ mipi_dsih_dphy_write(phy, 0x22, data, 1);
+ // data[1] = mipi_dsih_dphy_test_data_out(phy);
+// printk("sprdfb:mipi dphy config-->0x22 write:%x,read:%x \n",data[0],data[1]);
+
+ no_of_bytes = 2; /* pll loop divider (code 0x18) takes only 2 bytes (10 bits in data) */
+ for (i = 0; i < no_of_bytes; i++)
+ {
+ data[i] = ((uint8_t)((((loop_divider - 1) >> (5 * i)) & 0x1F) | (i << 7) ));
+ /* 7 is dependent on no_of_bytes
+ make sure 5 bits only of value are written at a time */
+ }
+ /* PLL loop divider ratio - SET no|reserved|feedback divider [7]|[6:5]|[4:0] */
+ mipi_dsih_dphy_write(phy, 0x18, data, no_of_bytes);
+ mipi_dsih_dphy_no_of_lanes(phy, no_of_lanes);
+#ifdef CONFIG_FB_DYNAMIC_FREQ_SCALING
+ if (phy->phy_keep_work != true)
+#endif
+ {
+ mipi_dsih_dphy_stop_wait_time(phy, 0x1C);
+ mipi_dsih_dphy_clock_en(phy, 1);
+ for(n=0;n<100;n++){
+ ;
+ }
+ mipi_dsih_dphy_shutdown(phy, 1);
+ for(n=0;n<100;n++){
+ ;
+ }
+ mipi_dsih_dphy_reset(phy, 1);
+ }
+ return OK;
+}
+#endif
+/**
+ * Close and power down D-PHY module
+ * @param phy pointer to structure which holds information about the d-phy
+ * module
+ * @return error code
+ */
+dsih_error_t mipi_dsih_dphy_close(dphy_t * phy)
+{
+ if (phy == 0)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ else if ((phy->core_read_function == 0) || (phy->core_write_function == 0))
+ {
+ return ERR_DSI_INVALID_IO;
+ }
+ if (phy->status < NOT_INITIALIZED)
+ {
+ return ERR_DSI_INVALID_INSTANCE;
+ }
+ mipi_dsih_dphy_reset(phy, 0);
+ mipi_dsih_dphy_reset(phy, 1);
+ mipi_dsih_dphy_shutdown(phy, 0);
+ phy->status = NOT_INITIALIZED;
+ return OK;
+}
+/**
+ * Enable clock lane module
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param en
+ */
+void mipi_dsih_dphy_clock_en(dphy_t * instance, int en)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_RSTZ, en, 2, 1);
+}
+/**
+ * Reset D-PHY module
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param reset
+ */
+void mipi_dsih_dphy_reset(dphy_t * instance, int reset)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_RSTZ, reset, 1, 1);
+}
+/**
+ * Power up/down D-PHY module
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param powerup (1) shutdown (0)
+ */
+void mipi_dsih_dphy_shutdown(dphy_t * instance, int powerup)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_RSTZ, powerup, 0, 1);
+}
+/**
+ * Force D-PHY PLL to stay on while in ULPS
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param force (1) disable (0)
+ * @note To follow the programming model, use wakeup_pll function
+ */
+void mipi_dsih_dphy_force_pll(dphy_t * instance, int force)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_RSTZ, force, 3, 1);
+}
+/**
+ * Get force D-PHY PLL module
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @return force value
+ */
+int mipi_dsih_dphy_get_force_pll(dphy_t * instance)
+{
+ return mipi_dsih_dphy_read_part(instance, R_DPHY_RSTZ, 3, 1);
+}
+/**
+ * Wake up or make sure D-PHY PLL module is awake
+ * This function must be called after going into ULPS and before exiting it
+ * to force the DPHY PLLs to wake up. It will wait until the DPHY status is
+ * locked. It follows the procedure described in the user guide.
+ * This function should be used to make sure the PLL is awake, rather than
+ * the force_pll above.
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @return error code
+ * @note this function has an active wait
+ */
+int mipi_dsih_dphy_wakeup_pll(dphy_t * instance)
+{
+ unsigned i = 0;
+ if (mipi_dsih_dphy_status(instance, 0x1) == 0)
+ {
+ mipi_dsih_dphy_force_pll(instance, 1);
+ for (i = 0; i < DSIH_PHY_ACTIVE_WAIT; i++)
+ {
+ if(mipi_dsih_dphy_status(instance, 0x1))
+ {
+ break;
+ }
+ }
+ if (mipi_dsih_dphy_status(instance, 0x1) == 0)
+ {
+ return ERR_DSI_PHY_PLL_NOT_LOCKED;
+ }
+ }
+ return OK;
+}
+/**
+ * Configure minimum wait period for HS transmission request after a stop state
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param no_of_byte_cycles [in byte (lane) clock cycles]
+ */
+void mipi_dsih_dphy_stop_wait_time(dphy_t * instance, uint8_t no_of_byte_cycles)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_IF_CFG, no_of_byte_cycles, 8, 8);
+}
+/**
+ * Set number of active lanes
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param no_of_lanes
+ */
+void mipi_dsih_dphy_no_of_lanes(dphy_t * instance, uint8_t no_of_lanes)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_IF_CFG, no_of_lanes - 1, 0, 2);
+}
+/**
+ * Get number of currently active lanes
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @return number of active lanes
+ */
+uint8_t mipi_dsih_dphy_get_no_of_lanes(dphy_t * instance)
+{
+ return mipi_dsih_dphy_read_part(instance, R_DPHY_IF_CFG, 0, 2);
+}
+
+/**
+ * SPRD ADD
+ * Set non-continuous clock mode
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param enable
+ */
+void mipi_dsih_dphy_enable_nc_clk(dphy_t * instance, int enable)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_LPCLK_CTRL, enable, 1, 1);
+}
+
+/**
+ * Request the PHY module to start transmission of high speed clock.
+ * This causes the clock lane to start transmitting DDR clock on the
+ * lane interconnect.
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param enable
+ * @note this function should be called explicitly by user always except for
+ * transmitting
+ */
+void mipi_dsih_dphy_enable_hs_clk(dphy_t * instance, int enable)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_LPCLK_CTRL, enable, 0, 1);
+}
+/**
+ * One bit is asserted in the trigger_request (4bits) to cause the lane module
+ * to cause the associated trigger to be sent across the lane interconnect.
+ * The trigger request is synchronous with the rising edge of the clock.
+ * @note: Only one bit of the trigger_request is asserted at any given time, the
+ * remaining must be left set to 0, and only when not in LPDT or ULPS modes
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param trigger_request 4 bit request
+ */
+dsih_error_t mipi_dsih_dphy_escape_mode_trigger(dphy_t * instance, uint8_t trigger_request)
+{
+ uint8_t sum = 0;
+ int i = 0;
+ for (i = 0; i < 4; i++)
+ {
+ sum += ((trigger_request >> i) & 1);
+ }
+ if (sum == 1)
+ { /* clear old trigger */
+ mipi_dsih_dphy_write_part(instance, R_DPHY_TX_TRIGGERS, 0x00, 0, 4);
+ mipi_dsih_dphy_write_part(instance, R_DPHY_TX_TRIGGERS, trigger_request, 0, 4);
+ for (i = 0; i < DSIH_PHY_ACTIVE_WAIT; i++)
+ {
+ if(mipi_dsih_dphy_status(instance, 0x0010))
+ {
+ break;
+ }
+ }
+ mipi_dsih_dphy_write_part(instance, R_DPHY_TX_TRIGGERS, 0x00, 0, 4);
+ if (i >= DSIH_PHY_ACTIVE_WAIT)
+ {
+ return ERR_DSI_TIMEOUT;
+ }
+ return OK;
+ }
+ return ERR_DSI_INVALID_COMMAND;
+}
+/**
+ * ULPS mode request/exit on all active data lanes.
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param enable (request 1/ exit 0)
+ * @return error code
+ * @note this is a blocking function. wait upon exiting the ULPS will exceed 1ms
+ */
+#ifdef GEN_2
+dsih_error_t mipi_dsih_dphy_ulps_data_lanes(dphy_t * instance, int enable)
+{
+ int timeout;
+ /* mask 1 0101 0010 0000 */
+ uint16_t data_lanes_mask = 0;
+ if (enable)
+ {
+ mipi_dsih_dphy_write_part(instance, R_DPHY_ULPS_CTRL, 1, 2, 1);
+ return OK;
+ }
+ else
+ {
+ if (mipi_dsih_dphy_status(instance, 0x1) == 0)
+ {
+ return ERR_DSI_PHY_PLL_NOT_LOCKED;
+ }
+ mipi_dsih_dphy_write_part(instance, R_DPHY_ULPS_CTRL, 1, 3, 1);
+ switch (mipi_dsih_dphy_get_no_of_lanes(instance))
+ {
+ case 3:
+ data_lanes_mask |= (1 << 12);
+ case 2:
+ data_lanes_mask |= (1 << 10);
+ case 1:
+ data_lanes_mask |= (1 << 8);
+ case 0:
+ data_lanes_mask |= (1 << 5);
+ break;
+ default:
+ data_lanes_mask = 0;
+ break;
+ }
+ for (timeout = 0; timeout < DSIH_PHY_ACTIVE_WAIT; timeout++)
+ { /* verify that the DPHY has left ULPM */
+
+ if (mipi_dsih_dphy_status(instance, data_lanes_mask) == data_lanes_mask)
+ {
+ break;
+ }
+ /* wait at least 1ms */
+ for (timeout = 0; timeout < ONE_MS_ACTIVE_WAIT; timeout++)
+ {
+ ;
+ }
+ }
+ if (mipi_dsih_dphy_status(instance, data_lanes_mask) != data_lanes_mask)
+ {
+ instance->log_info("sprdfb: stat %x, mask %x", mipi_dsih_dphy_status(instance, data_lanes_mask), data_lanes_mask);
+ return ERR_DSI_TIMEOUT;
+ }
+ mipi_dsih_dphy_write_part(instance, R_DPHY_ULPS_CTRL, 0, 2, 1);
+ mipi_dsih_dphy_write_part(instance, R_DPHY_ULPS_CTRL, 0, 3, 1);
+ }
+ return OK;
+}
+#else
+void mipi_dsih_dphy_ulps_data_lanes(dphy_t * instance, int enable)
+{
+ int timeout;
+ if (enable)
+ {
+ mipi_dsih_dphy_write_part(instance, R_DSI_HOST_PHY_IF_CTRL, 1, 3, 1);
+ }
+ else
+ {
+ mipi_dsih_dphy_write_part(instance, R_DSI_HOST_PHY_IF_CTRL, 1, 4, 1);
+ for (timeout = 0; timeout < DSIH_PHY_ACTIVE_WAIT; timeout++)
+ { /* verify that the DPHY has left ULPM */
+ /* mask 1010100100000 */
+ if (mipi_dsih_dphy_status(instance, 0x1520) == 0)
+ { /* wait at least 1ms */
+ for (timeout = 0; timeout < ONE_MS_ACTIVE_WAIT; timeout++)
+ {
+ ;
+ }
+ break;
+ }
+ }
+ mipi_dsih_dphy_write_part(instance, R_DSI_HOST_PHY_IF_CTRL, 0, 3, 1);
+ mipi_dsih_dphy_write_part(instance, R_DSI_HOST_PHY_IF_CTRL, 0, 4, 1);
+ }
+}
+#endif
+/**
+ * ULPS mode request/exit on Clock Lane.
+ * @param instance pointer to structure which holds information about the
+ * d-phy module
+ * @param enable 1 or disable 0 of the Ultra Low Power State of the clock lane
+ * @return error code
+ * @note this is a blocking function. wait upon exiting the ULPS will exceed 1ms
+ */
+#ifdef GEN_2
+dsih_error_t mipi_dsih_dphy_ulps_clk_lane(dphy_t * instance, int enable)
+{
+ int timeout;
+ /* mask 1000 */
+ uint16_t clk_lane_mask = 0x0008;
+ if (enable)
+ {
+ /* mipi_dsih_dphy_write_part(instance, R_DPHY_ULPS_CTRL, 0, 0, 1); */
+ mipi_dsih_dphy_write_part(instance, R_DPHY_ULPS_CTRL, 1, 0, 1);
+ }
+ else
+ {
+ if (mipi_dsih_dphy_status(instance, 0x1) == 0)
+ {
+ return ERR_DSI_PHY_PLL_NOT_LOCKED;
+ }
+ mipi_dsih_dphy_write_part(instance, R_DPHY_ULPS_CTRL, 1, 1, 1);
+ for (timeout = 0; timeout < DSIH_PHY_ACTIVE_WAIT; timeout++)
+ { /* verify that the DPHY has left ULPM */
+ /* mask 1010100100000 */
+ if (mipi_dsih_dphy_status(instance, clk_lane_mask) == clk_lane_mask)
+ { /* wait at least 1ms */
+ instance->log_info("sprdfb: stat %x, mask %x", mipi_dsih_dphy_status(instance, clk_lane_mask), clk_lane_mask);
+ break;
+ }
+ /* wait at least 1ms */
+ for (timeout = 0; timeout < ONE_MS_ACTIVE_WAIT; timeout++)
+ { /* dummy operation for the loop not to be optimised */
+ enable = mipi_dsih_dphy_status(instance, clk_lane_mask);
+ }
+ }
+ if (mipi_dsih_dphy_status(instance, clk_lane_mask) != clk_lane_mask)
+ {
+ return ERR_DSI_TIMEOUT;
+ }
+ mipi_dsih_dphy_write_part(instance, R_DPHY_ULPS_CTRL, 0, 0, 1);
+ mipi_dsih_dphy_write_part(instance, R_DPHY_ULPS_CTRL, 0, 1, 1);
+ }
+ return OK;
+}
+#else
+void mipi_dsih_dphy_ulps_clk_lane(dphy_t * instance, int enable)
+{
+ int timeout;
+ if (enable)
+ {
+ mipi_dsih_dphy_write_part(instance, R_DSI_HOST_PHY_IF_CTRL, 0, 0, 1);
+ mipi_dsih_dphy_write_part(instance, R_DSI_HOST_PHY_IF_CTRL, 1, 1, 1);
+ }
+ else
+ {
+ mipi_dsih_dphy_write_part(instance, R_DSI_HOST_PHY_IF_CTRL, 1, 2, 1);
+ for (timeout = 0; timeout < DSIH_PHY_ACTIVE_WAIT; timeout++)
+ { /* verify that the DPHY has left ULPM */
+ /* mask 1010100100000 */
+ if (mipi_dsih_dphy_status(instance, 0x0004) == 0)
+ { /* wait at least 1ms */
+ for (timeout = 0; timeout < ONE_MS_ACTIVE_WAIT; timeout++)
+ {
+ ;
+ }
+ break;
+ }
+ }
+ mipi_dsih_dphy_write_part(instance, R_DSI_HOST_PHY_IF_CTRL, 0, 1, 1);
+ mipi_dsih_dphy_write_part(instance, R_DSI_HOST_PHY_IF_CTRL, 0, 2, 1);
+ }
+}
+#endif
+/**
+ * Get D-PHY PPI status
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param mask
+ * @return status
+ */
+uint32_t mipi_dsih_dphy_status(dphy_t * instance, uint16_t mask)
+{
+ return mipi_dsih_dphy_read_word(instance, R_DPHY_STATUS) & mask;
+}
+/**
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param value
+ */
+void mipi_dsih_dphy_test_clock(dphy_t * instance, int value)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_TST_CRTL0, value, 1, 1);
+}
+/**
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param value
+ */
+void mipi_dsih_dphy_test_clear(dphy_t * instance, int value)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_TST_CRTL0, value, 0, 1);
+}
+/**
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param on_falling_edge
+ */
+void mipi_dsih_dphy_test_en(dphy_t * instance, uint8_t on_falling_edge)
+{
+ mipi_dsih_dphy_write_part(instance, R_DPHY_TST_CRTL1, on_falling_edge, 16, 1);
+}
+/**
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ */
+uint8_t mipi_dsih_dphy_test_data_out(dphy_t * instance)
+{
+ return mipi_dsih_dphy_read_part(instance, R_DPHY_TST_CRTL1, 8, 8);
+}
+/**
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param test_data
+ */
+void mipi_dsih_dphy_test_data_in(dphy_t * instance, uint8_t test_data)
+{
+ mipi_dsih_dphy_write_word(instance, R_DPHY_TST_CRTL1, test_data);
+}
+/**
+ * Write to D-PHY module (encapsulating the digital interface)
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param address offset inside the D-PHY digital interface
+ * @param data array of bytes to be written to D-PHY
+ * @param data_length of the data array
+ */
+void mipi_dsih_dphy_write(dphy_t * instance, uint8_t address, uint8_t * data, uint8_t data_length)
+{
+ unsigned i = 0;
+ if (data != 0)
+ {
+#if ((defined DWC_MIPI_DPHY_BIDIR_TSMC40LP) || (defined DPHY2Btql) || (defined GEN_2))
+ /* set the TESTCLK input high in preparation to latch in the desired test mode */
+ mipi_dsih_dphy_test_clock(instance, 1);
+ /* set the desired test code in the input 8-bit bus TESTDIN[7:0] */
+ mipi_dsih_dphy_test_data_in(instance, address);
+ /* set TESTEN input high */
+ mipi_dsih_dphy_test_en(instance, 1);
+ /* drive the TESTCLK input low; the falling edge captures the chosen test code into the transceiver */
+ mipi_dsih_dphy_test_clock(instance, 0);
+ /* set TESTEN input low to disable further test mode code latching */
+ mipi_dsih_dphy_test_en(instance, 0);
+ /* start writing MSB first */
+ for (i = data_length; i > 0; i--)
+ { /* set TESTDIN[7:0] to the desired test data appropriate to the chosen test mode */
+ mipi_dsih_dphy_test_data_in(instance, data[i - 1]);
+ /* pulse TESTCLK high to capture this test data into the macrocell; repeat these two steps as necessary */
+ mipi_dsih_dphy_test_clock(instance, 1);
+ mipi_dsih_dphy_test_clock(instance, 0);
+ }
+#endif
+ }
+}
+
+
+
+/* abstracting BSP */
+/**
+ * Write to whole register to D-PHY module (encapsulating the bus interface)
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param reg_address offset
+ * @param data 32-bit word
+ */
+void mipi_dsih_dphy_write_word(dphy_t * instance, uint32_t reg_address, uint32_t data)
+{
+ if (instance->core_write_function != 0)
+ {
+ instance->core_write_function(instance->address, reg_address, data);
+ }
+}
+/**
+ * Write bit field to D-PHY module (encapsulating the bus interface)
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param reg_address offset
+ * @param data bits to be written to D-PHY
+ * @param shift from the right hand side of the register (big endian)
+ * @param width of the bit field
+ */
+void mipi_dsih_dphy_write_part(dphy_t * instance, uint32_t reg_address, uint32_t data, uint8_t shift, uint8_t width)
+{
+ uint32_t mask = 0;
+ uint32_t temp = 0;
+ if (instance->core_read_function != 0)
+ {
+ mask = (1 << width) - 1;
+ temp = mipi_dsih_dphy_read_word(instance, reg_address);
+ temp &= ~(mask << shift);
+ temp |= (data & mask) << shift;
+ mipi_dsih_dphy_write_word(instance, reg_address, temp);
+ }
+}
+/**
+ * Read whole register from D-PHY module (encapsulating the bus interface)
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param reg_address offset
+ * @return data 32-bit word
+ */
+uint32_t mipi_dsih_dphy_read_word(dphy_t * instance, uint32_t reg_address)
+{
+ if (instance->core_read_function == 0)
+ {
+ return ERR_DSI_INVALID_IO;
+ }
+ return instance->core_read_function(instance->address, reg_address);
+}
+/**
+ * Read bit field from D-PHY module (encapsulating the bus interface)
+ * @param instance pointer to structure which holds information about the d-phy
+ * module
+ * @param reg_address offset
+ * @param shift from the right hand side of the register (big endian)
+ * @param width of the bit field
+ * @return data bits to be written to D-PHY
+ */
+uint32_t mipi_dsih_dphy_read_part(dphy_t * instance, uint32_t reg_address, uint8_t shift, uint8_t width)
+{
+ return (mipi_dsih_dphy_read_word(instance, reg_address) >> shift) & ((1 << width) - 1);
+}
diff --git a/drivers/autotst/mipi_dsih_dphy.h b/drivers/autotst/mipi_dsih_dphy.h
new file mode 100644
index 00000000..c171fe28
--- /dev/null
+++ b/drivers/autotst/mipi_dsih_dphy.h
@@ -0,0 +1,67 @@
+/*
+ * @file mipi_dsih_dphy.h
+ *
+ * Synopsys Inc.
+ * SG DWC PT02
+ */
+
+#ifndef MIPI_DSIH_DPHY_H_
+#define MIPI_DSIH_DPHY_H_
+
+#include "mipi_dsih_local.h"
+
+#define R_DPHY_LPCLK_CTRL (0x94)
+#define R_DPHY_RSTZ (0xA0)
+#define R_DPHY_IF_CFG (0xA4)
+#define R_DPHY_ULPS_CTRL (0xA8)
+#define R_DPHY_TX_TRIGGERS (0xAC)
+#define R_DPHY_STATUS (0xB0)
+#define R_DPHY_TST_CRTL0 (0xB4)
+#define R_DPHY_TST_CRTL1 (0xB8)
+
+#ifdef FB_DSIH_VERSION_1P21A
+#define R_DSI_HOST_PHY_IF_CTRL 0x5CUL
+#endif
+
+
+
+/* obligatory functions - code can be changed for different phys*/
+dsih_error_t mipi_dsih_dphy_open(dphy_t * phy);
+dsih_error_t mipi_dsih_dphy_configure(dphy_t * phy, uint8_t no_of_lanes, uint32_t output_freq);
+dsih_error_t mipi_dsih_dphy_close(dphy_t * phy);
+
+void mipi_dsih_dphy_clock_en(dphy_t * instance, int en);
+void mipi_dsih_dphy_reset(dphy_t * instance, int reset);
+void mipi_dsih_dphy_shutdown(dphy_t * instance, int powerup);
+int mipi_dsih_dphy_get_force_pll(dphy_t * instance);
+void mipi_dsih_dphy_force_pll(dphy_t * instance, int force);
+int mipi_dsih_dphy_wakeup_pll(dphy_t * instance);
+
+void mipi_dsih_dphy_stop_wait_time(dphy_t * instance, uint8_t no_of_byte_cycles);
+void mipi_dsih_dphy_no_of_lanes(dphy_t * instance, uint8_t no_of_lanes);
+uint8_t mipi_dsih_dphy_get_no_of_lanes(dphy_t * instance);
+void mipi_dsih_dphy_enable_nc_clk(dphy_t * instance, int enable);
+void mipi_dsih_dphy_enable_hs_clk(dphy_t * instance, int enable);
+dsih_error_t mipi_dsih_dphy_escape_mode_trigger(dphy_t * instance, uint8_t trigger_request);
+#ifdef GEN_2
+dsih_error_t mipi_dsih_dphy_ulps_data_lanes(dphy_t * instance, int enable);
+dsih_error_t mipi_dsih_dphy_ulps_clk_lane(dphy_t * instance, int enable);
+#else
+void mipi_dsih_dphy_ulps_data_lanes(dphy_t * instance, int enable);
+void mipi_dsih_dphy_ulps_clk_lane(dphy_t * instance, int enable);
+#endif
+uint32_t mipi_dsih_dphy_status(dphy_t * instance, uint16_t mask);
+/* end of obligatory functions*/
+void mipi_dsih_dphy_test_clock(dphy_t * instance, int value);
+void mipi_dsih_dphy_test_clear(dphy_t * instance, int value);
+void mipi_dsih_dphy_test_en(dphy_t * instance, uint8_t on_falling_edge);
+uint8_t mipi_dsih_dphy_test_data_out(dphy_t * instance);
+void mipi_dsih_dphy_test_data_in(dphy_t * instance, uint8_t test_data);
+
+void mipi_dsih_dphy_write(dphy_t * instance, uint8_t address, uint8_t * data, uint8_t data_length);
+
+void mipi_dsih_dphy_write_word(dphy_t * instance, uint32_t reg_address, uint32_t data);
+void mipi_dsih_dphy_write_part(dphy_t * instance, uint32_t reg_address, uint32_t data, uint8_t shift, uint8_t width);
+uint32_t mipi_dsih_dphy_read_word(dphy_t * instance, uint32_t reg_address);
+uint32_t mipi_dsih_dphy_read_part(dphy_t * instance, uint32_t reg_address, uint8_t shift, uint8_t width);
+#endif /* MIPI_DSIH_DPHY_H_ */
diff --git a/drivers/autotst/mipi_dsih_hal.c b/drivers/autotst/mipi_dsih_hal.c
new file mode 100644
index 00000000..d20693f5
--- /dev/null
+++ b/drivers/autotst/mipi_dsih_hal.c
@@ -0,0 +1,1114 @@
+/**
+ * @file mipi_dsih_hal.c
+ * @brief Hardware Abstraction Level of DWC MIPI DSI HOST controller
+ *
+ * Synopsys Inc.
+ * SG DWC PT02
+ */
+#include "mipi_dsih_hal.h"
+
+/**
+ * Write a 32-bit word to the DSI Host core
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param reg_address register offset in core
+ * @param data 32-bit word to be written to register
+ */
+void mipi_dsih_write_word(dsih_ctrl_t * instance, uint32_t reg_address, uint32_t data)
+{
+
+ instance->core_write_function(instance->address, reg_address, data);
+}
+/**
+ * Write a bit field o a 32-bit word to the DSI Host core
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param reg_address register offset in core
+ * @param data to be written to register
+ * @param shift bit shift from the left (system is BIG ENDIAN)
+ * @param width of bit field
+ */
+void mipi_dsih_write_part(dsih_ctrl_t * instance, uint32_t reg_address, uint32_t data, uint8_t shift, uint8_t width)
+{
+ uint32_t mask = (1 << width) - 1;
+ uint32_t temp = mipi_dsih_read_word(instance, reg_address);
+
+ temp &= ~(mask << shift);
+ temp |= (data & mask) << shift;
+ mipi_dsih_write_word(instance, reg_address, temp);
+}
+/**
+ * Write a 32-bit word to the DSI Host core
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param reg_address offset of register
+ * @return 32-bit word value stored in register
+ */
+uint32_t mipi_dsih_read_word(dsih_ctrl_t * instance, uint32_t reg_address)
+{
+ return instance->core_read_function(instance->address, reg_address);
+}
+/**
+ * Write a 32-bit word to the DSI Host core
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param reg_address offset of register in core
+ * @param shift bit shift from the left (system is BIG ENDIAN)
+ * @param width of bit field
+ * @return bit field read from register
+ */
+uint32_t mipi_dsih_read_part(dsih_ctrl_t * instance, uint32_t reg_address, uint8_t shift, uint8_t width)
+{
+ return (mipi_dsih_read_word(instance, reg_address) >> shift) & ((1 << width) - 1);
+}
+/**
+ * Get DSI Host core version
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return ascii number of the version
+ */
+uint32_t mipi_dsih_hal_get_version(dsih_ctrl_t * instance)
+{
+ return mipi_dsih_read_word(instance, R_DSI_HOST_VERSION);
+}
+/**
+ * Modify power status of DSI Host core
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param on (1) or off (0)
+ */
+void mipi_dsih_hal_power(dsih_ctrl_t * instance, int on)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_PWR_UP, on, 0, 1);
+}
+/**
+ * Get the power status of the DSI Host core
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return power status
+ */
+int mipi_dsih_hal_get_power(dsih_ctrl_t * instance)
+{
+ return (int)(mipi_dsih_read_part(instance, R_DSI_HOST_PWR_UP, 0, 1));
+}
+/**
+ * Write transmission escape timeout
+ * a safe guard so that the state machine would reset if transmission
+ * takes too long
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param tx_escape_division
+ */
+void mipi_dsih_hal_tx_escape_division(dsih_ctrl_t * instance, uint8_t tx_escape_division)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_CLK_MGR, tx_escape_division, 0, 8);
+}
+/**
+ * Write the DPI video virtual channel destination
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param vc virtual channel
+ */
+void mipi_dsih_hal_dpi_video_vc(dsih_ctrl_t * instance, uint8_t vc)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_DPI_VCID, (uint32_t)(vc), 0, 2);
+}
+/**
+ * Get the DPI video virtual channel destination
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return virtual channel
+ */
+uint8_t mipi_dsih_hal_dpi_get_video_vc(dsih_ctrl_t * instance)
+{
+ return mipi_dsih_read_part(instance, R_DSI_HOST_DPI_VCID, 0, 2);
+}
+/**
+ * Set DPI video color coding
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param color_coding enum (configuration and color depth)
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_dpi_color_coding(dsih_ctrl_t * instance, dsih_color_coding_t color_coding)
+{
+ dsih_error_t err = OK;
+ if (color_coding > COLOR_CODE_MAX)
+ {
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: invalid colour configuration");
+ }
+ err = ERR_DSI_COLOR_CODING;
+ }
+ else
+ {
+ mipi_dsih_write_part(instance, R_DSI_HOST_DPI_COLOR_CODE, color_coding, 0, 4);
+ }
+ return err;
+}
+/**
+ * Get DPI video color coding
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return color coding enum (configuration and color depth)
+ */
+dsih_color_coding_t mipi_dsih_hal_dpi_get_color_coding(dsih_ctrl_t * instance)
+{
+ return (dsih_color_coding_t)(mipi_dsih_read_part(instance, R_DSI_HOST_DPI_COLOR_CODE, 0, 4));
+}
+/**
+ * Get DPI video color depth
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return number of bits per pixel
+ */
+uint8_t mipi_dsih_hal_dpi_get_color_depth(dsih_ctrl_t * instance)
+{
+ uint8_t color_depth = 0;
+ switch (mipi_dsih_read_part(instance, R_DSI_HOST_DPI_COLOR_CODE, 0, 4))
+ {
+ case 0:
+ case 1:
+ case 2:
+ color_depth = 16;
+ break;
+ case 3:
+ case 4:
+ color_depth = 18;
+ break;
+ case 5:
+ color_depth = 24;
+ break;
+ case 6:
+ color_depth = 20;
+ break;
+ case 7:
+ color_depth = 24;
+ break;
+ case 8:
+ color_depth = 16;
+ break;
+ case 9:
+ color_depth = 30;
+ break;
+ case 10:
+ color_depth = 36;
+ break;
+ case 11:
+ color_depth = 12;
+ break;
+ default:
+ break;
+ }
+ return color_depth;
+}
+/**
+ * Get DPI video pixel configuration
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return pixel configuration
+ */
+uint8_t mipi_dsih_hal_dpi_get_color_config(dsih_ctrl_t * instance)
+{
+ uint8_t color_config = 0;
+ switch (mipi_dsih_read_part(instance, R_DSI_HOST_DPI_COLOR_CODE, 0, 4))
+ {
+ case 0:
+ color_config = 1;
+ break;
+ case 1:
+ color_config = 2;
+ break;
+ case 2:
+ color_config = 3;
+ break;
+ case 3:
+ color_config = 1;
+ break;
+ case 4:
+ color_config = 2;
+ break;
+ default:
+ color_config = 0;
+ break;
+ }
+ return color_config;
+}
+/**
+ * Set DPI loosely packetisation video (used only when color depth = 18
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable
+ */
+void mipi_dsih_hal_dpi_18_loosely_packet_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_DPI_COLOR_CODE, enable, 8, 1);
+}
+/**
+ * Set DPI color mode pin polarity
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param active_low (1) or active high (0)
+ */
+void mipi_dsih_hal_dpi_color_mode_pol(dsih_ctrl_t * instance, int active_low)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_DPI_CFG_POL, active_low, 4, 1);
+}
+/**
+ * Set DPI shut down pin polarity
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param active_low (1) or active high (0)
+ */
+void mipi_dsih_hal_dpi_shut_down_pol(dsih_ctrl_t * instance, int active_low)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_DPI_CFG_POL, active_low, 3, 1);
+}
+/**
+ * Set DPI horizontal sync pin polarity
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param active_low (1) or active high (0)
+ */
+void mipi_dsih_hal_dpi_hsync_pol(dsih_ctrl_t * instance, int active_low)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_DPI_CFG_POL, active_low, 2, 1);
+}
+/**
+ * Set DPI vertical sync pin polarity
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param active_low (1) or active high (0)
+ */
+void mipi_dsih_hal_dpi_vsync_pol(dsih_ctrl_t * instance, int active_low)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_DPI_CFG_POL, active_low, 1, 1);
+}
+/**
+ * Set DPI data enable pin polarity
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param active_low (1) or active high (0)
+ */
+void mipi_dsih_hal_dpi_dataen_pol(dsih_ctrl_t * instance, int active_low)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_DPI_CFG_POL, active_low, 0, 1);
+}
+/**
+ * Enable FRAME BTA ACK
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_dpi_frame_ack_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_MODE_CFG, enable, 14, 1);
+}
+/**
+ * Enable null packets (value in null packet size will be taken in calculations)
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ * @note function retained for backward compatibility (not used from 1.20a on)
+ */
+void mipi_dsih_hal_dpi_null_packet_en(dsih_ctrl_t * instance, int enable)
+{
+}
+/**
+ * Enable multi packets (value in no of chunks will be taken in calculations)
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_dpi_multi_packet_en(dsih_ctrl_t * instance, int enable)
+{
+}
+/**
+ * Enable return to low power mode inside horizontal front porch periods when
+ * timing allows
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_dpi_lp_during_hfp(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_MODE_CFG, enable, 13, 1);
+}
+/**
+ * Enable return to low power mode inside horizontal back porch periods when
+ * timing allows
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_dpi_lp_during_hbp(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_MODE_CFG, enable, 12, 1);
+}
+/**
+ * Enable return to low power mode inside vertical active lines periods when
+ * timing allows
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_dpi_lp_during_vactive(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_MODE_CFG, enable, 11, 1);
+}
+/**
+ * Enable return to low power mode inside vertical front porch periods when
+ * timing allows
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_dpi_lp_during_vfp(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_MODE_CFG, enable, 10, 1);
+}
+/**
+ * Enable return to low power mode inside vertical back porch periods when
+ * timing allows
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_dpi_lp_during_vbp(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_MODE_CFG, enable, 9, 1);
+}
+/**
+ * Enable return to low power mode inside vertical sync periods when
+ * timing allows
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_dpi_lp_during_vsync(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_MODE_CFG, enable, 8, 1);
+}
+/**
+ * Set DPI video mode type (burst/non-burst - with sync pulses or events)
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param type
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_dpi_video_mode_type(dsih_ctrl_t * instance, dsih_video_mode_t type)
+{
+ if (type < 3)
+ {
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_MODE_CFG, type, 0, 2);
+ return OK;
+ }
+ else
+ {
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: undefined type");
+ }
+ return ERR_DSI_OUT_OF_BOUND;
+ }
+}
+/**
+ * Enable/disable DPI video mode
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_dpi_video_mode_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_MODE_CFG, enable? 0: 1, 0, 1);
+}
+/**
+ * Get the status of video mode, whether enabled or not in core
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return status
+ */
+int mipi_dsih_hal_dpi_is_video_mode(dsih_ctrl_t * instance)
+{
+ return (mipi_dsih_read_part(instance, R_DSI_HOST_MODE_CFG, 0, 1) == 0);
+}
+/**
+ * Write the null packet size - will only be taken into account when null
+ * packets are enabled.
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param size of null packet
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_dpi_null_packet_size(dsih_ctrl_t * instance, uint16_t size)
+{
+ if (size < (1 << 13)) /* 13-bit field */
+ {
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_NULL_SIZE, size, 0, 13);
+ return OK;
+ }
+ else
+ {
+ return ERR_DSI_OUT_OF_BOUND;
+ }
+}
+/**
+ * Write no of chunks to core - taken into consideration only when multi packet
+ * is enabled
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no of chunks
+ */
+dsih_error_t mipi_dsih_hal_dpi_chunks_no(dsih_ctrl_t * instance, uint16_t no)
+{
+ if (no < (1 << 13))
+ {
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_NUM_CHUNKS, no, 0, 13);
+ return OK;
+ }
+ else
+ {
+ return ERR_DSI_OUT_OF_BOUND;
+ }
+}
+/**
+ * Write video packet size. obligatory for sending video
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param size of video packet - containing information
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_dpi_video_packet_size(dsih_ctrl_t * instance, uint16_t size)
+{
+ if (size < (1 << 14)) /* 14-bit field */
+ {
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_PKT_SIZE, size, 0, 14);
+ return OK;
+ }
+ else
+ {
+ return ERR_DSI_OUT_OF_BOUND;
+ }
+}
+/**
+ * function retained for backward compatibility (not used from 1.20a on)
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_edpi_enable(dsih_ctrl_t * instance, int enable)
+{
+}
+/**
+ * Specifiy the size of the packet memory write start/continue
+ * @param instance pointer to structure holding the DSI Host core information
+ * @ size of the packet
+ * @note when different than zero (0) eDPI is enabled
+ */
+void mipi_dsih_hal_edpi_max_allowed_size(dsih_ctrl_t * instance, uint16_t size)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_EDPI_CMD_SIZE, size, 0, 16);
+}
+/**
+ * Enable tear effect acknowledge
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_tear_effect_ack_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, enable, 0, 1);
+}
+/**
+ * Enable packets acknowledge request after each packet transmission
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable (1) - disable (0)
+ */
+void mipi_dsih_hal_cmd_ack_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, enable, 1, 1);
+}
+/**
+ * Set DCS command packet transmission to transmission type
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_param of command
+ * @param lp transmit in low power
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_dcs_wr_tx_type(dsih_ctrl_t * instance, unsigned no_of_param, int lp)
+{
+ switch (no_of_param)
+ {
+ case 0:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 16, 1);
+ break;
+ case 1:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 17, 1);
+ break;
+ default:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 19, 1);
+ break;
+ }
+ return OK;
+}
+/**
+ * Set DCS read command packet transmission to transmission type
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_param of command
+ * @param lp transmit in low power
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_dcs_rd_tx_type(dsih_ctrl_t * instance, unsigned no_of_param, int lp)
+{
+ dsih_error_t err = OK;
+ switch (no_of_param)
+ {
+ case 0:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 18, 1);
+ break;
+ default:
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: undefined DCS Read packet type");
+ }
+ err = ERR_DSI_OUT_OF_BOUND;
+ break;
+ }
+ return err;
+}
+
+/*Jessica add begin: to support max read packet size command */
+dsih_error_t mipi_dsih_hal_max_rd_packet_size_type(dsih_ctrl_t * instance, int lp)
+{
+ dsih_error_t err = OK;
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 10, 1);
+ return err;
+}
+/*Jessica add end*/
+
+/**
+ * Set generic write command packet transmission to transmission type
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_param of command
+ * @param lp transmit in low power
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_gen_wr_tx_type(dsih_ctrl_t * instance, unsigned no_of_param, int lp)
+{
+ switch (no_of_param)
+ {
+ case 0:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 8, 1);
+ break;
+ case 1:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 9, 1);
+ break;
+ case 2:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 10, 1);
+ break;
+ default:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 14, 1);
+ break;
+ }
+ return OK;
+}
+/**
+ * Set generic command packet transmission to transmission type
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_param of command
+ * @param lp transmit in low power
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_gen_rd_tx_type(dsih_ctrl_t * instance, unsigned no_of_param, int lp)
+{
+ dsih_error_t err = OK;
+ switch (no_of_param)
+ {
+ case 0:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 11, 1);
+ break;
+ case 1:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 12, 1);
+ break;
+ case 2:
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 13, 1);
+ break;
+ default:
+ if (instance->log_error != 0)
+ {
+ instance->log_error("sprdfb: undefined Generic Read packet type");
+ }
+ err = ERR_DSI_OUT_OF_BOUND;
+ break;
+ }
+ return err;
+}
+/**
+ * Configure maximum read packet size command transmission type
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param lp set to low power
+ */
+void mipi_dsih_hal_max_rd_size_tx_type(dsih_ctrl_t * instance, int lp)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_CMD_MODE_CFG, lp, 24, 1);
+}
+/**
+ * Enable command mode (Generic interface)
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable
+ */
+void mipi_dsih_hal_gen_cmd_mode_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_MODE_CFG, enable? 1: 0, 0, 1);
+}
+/**
+ * Retrieve the controller's status of whether command mode is ON or not
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return whether command mode is ON
+ */
+int mipi_dsih_hal_gen_is_cmd_mode(dsih_ctrl_t * instance)
+{
+ return (mipi_dsih_read_part(instance, R_DSI_HOST_MODE_CFG, 0, 1) == 1);
+}
+/**
+ * Configure the Horizontal Line time
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param time taken to transmit the total of the horizontal line
+ */
+void mipi_dsih_hal_dpi_hline(dsih_ctrl_t * instance, uint16_t time)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_HLINE_TIME, time, 0, 15);
+}
+/**
+ * Configure the Horizontal back porch time
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param time taken to transmit the horizontal back porch
+ */
+void mipi_dsih_hal_dpi_hbp(dsih_ctrl_t * instance, uint16_t time)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_HBP_TIME, time, 0, 12);
+}
+/**
+ * Configure the Horizontal sync time
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param time taken to transmit the horizontal sync
+ */
+void mipi_dsih_hal_dpi_hsa(dsih_ctrl_t * instance, uint16_t time)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_HSA_TIME, time, 0, 12);
+}
+/**
+ * Configure the vertical active lines of the video stream
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param lines
+ */
+void mipi_dsih_hal_dpi_vactive(dsih_ctrl_t * instance, uint16_t lines)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_VACTIVE_LINES, lines, 0, 14);
+}
+/**
+ * Configure the vertical front porch lines of the video stream
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param lines
+ */
+void mipi_dsih_hal_dpi_vfp(dsih_ctrl_t * instance, uint16_t lines)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_VFP_LINES, lines, 0, 10);
+}
+/**
+ * Configure the vertical back porch lines of the video stream
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param lines
+ */
+void mipi_dsih_hal_dpi_vbp(dsih_ctrl_t * instance, uint16_t lines)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_VBP_LINES, lines, 0, 10);
+}
+/**
+ * Configure the vertical sync lines of the video stream
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param lines
+ */
+void mipi_dsih_hal_dpi_vsync(dsih_ctrl_t * instance, uint16_t lines)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_VID_VSA_LINES, lines, 0, 10);
+}
+/**
+ * configure timeout divisions (so they would have more clock ticks)
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param byte_clk_division_factor no of hs cycles before transiting back to LP in
+ * (lane_clk / byte_clk_division_factor)
+ */
+void mipi_dsih_hal_timeout_clock_division(dsih_ctrl_t * instance, uint8_t byte_clk_division_factor)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_CLK_MGR, byte_clk_division_factor, 8, 8);
+}
+/**
+ * Configure the Low power receive time out
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param count (of byte cycles)
+ */
+void mipi_dsih_hal_lp_rx_timeout(dsih_ctrl_t * instance, uint16_t count)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_TO_CNT_CFG, count, 0, 16);
+}
+/**
+ * Configure a high speed transmission time out7
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param count (byte cycles)
+ */
+void mipi_dsih_hal_hs_tx_timeout(dsih_ctrl_t * instance, uint16_t count)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_TO_CNT_CFG, count, 16, 16);
+}
+/**
+ * Get the error 0 interrupt register status
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param mask the mask to be read from the register
+ * @return error status 0 value
+ */
+uint32_t mipi_dsih_hal_int_status_0(dsih_ctrl_t * instance, uint32_t mask)
+{
+ return (mipi_dsih_read_word(instance, R_DSI_HOST_INT_ST0) & mask);
+}
+/**
+ * Get the error 1 interrupt register status
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param mask the mask to be read from the register
+ * @return error status 1 value
+ */
+uint32_t mipi_dsih_hal_int_status_1(dsih_ctrl_t * instance, uint32_t mask)
+{
+ return (mipi_dsih_read_word(instance, R_DSI_HOST_INT_ST1) & mask);
+}
+/**
+ * Configure MASK (hiding) of interrupts coming from error 0 source
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param mask to be written to the register
+ */
+void mipi_dsih_hal_int_mask_0(dsih_ctrl_t * instance, uint32_t mask)
+{
+ mipi_dsih_write_word(instance, R_DSI_HOST_INT_MSK0, mask);
+}
+/**
+ * Get the ERROR MASK 0 register status
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param mask the bits to read from the mask register
+ */
+uint32_t mipi_dsih_hal_int_get_mask_0(dsih_ctrl_t * instance, uint32_t mask)
+{
+ return (mipi_dsih_read_word(instance, R_DSI_HOST_INT_MSK0) & mask);
+}
+/**
+ * Configure MASK (hiding) of interrupts coming from error 0 source
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param mask the mask to be written to the register
+ */
+void mipi_dsih_hal_int_mask_1(dsih_ctrl_t * instance, uint32_t mask)
+{
+ mipi_dsih_write_word(instance, R_DSI_HOST_INT_MSK1, mask);
+}
+/**
+ * Get the ERROR MASK 1 register status
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param mask the bits to read from the mask register
+ */
+uint32_t mipi_dsih_hal_int_get_mask_1(dsih_ctrl_t * instance, uint32_t mask)
+{
+ return (mipi_dsih_read_word(instance, R_DSI_HOST_INT_MSK1) & mask);
+}
+/* DBI NOT IMPLEMENTED */
+void mipi_dsih_hal_dbi_out_color_coding(dsih_ctrl_t * instance, uint8_t color_depth, uint8_t option);
+void mipi_dsih_hal_dbi_in_color_coding(dsih_ctrl_t * instance, uint8_t color_depth, uint8_t option);
+void mipi_dsih_hal_dbi_lut_size(dsih_ctrl_t * instance, uint8_t size);
+void mipi_dsih_hal_dbi_partitioning_en(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dbi_dcs_vc(dsih_ctrl_t * instance, uint8_t vc);
+void mipi_dsih_hal_dbi_max_cmd_size(dsih_ctrl_t * instance, uint16_t size);
+void mipi_dsih_hal_dbi_cmd_size(dsih_ctrl_t * instance, uint16_t size);
+void mipi_dsih_hal_dbi_max_cmd_size(dsih_ctrl_t * instance, uint16_t size);
+int mipi_dsih_hal_dbi_rd_cmd_busy(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_read_fifo_full(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_read_fifo_empty(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_write_fifo_full(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_write_fifo_empty(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_cmd_fifo_full(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_cmd_fifo_empty(dsih_ctrl_t * instance);
+
+/**
+ * Write command header in the generic interface
+ * (which also sends DCS commands) as a subset
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param vc of destination
+ * @param packet_type (or type of DCS command)
+ * @param ls_byte (if DCS, it is the DCS command)
+ * @param ms_byte (only parameter of short DCS packet)
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_gen_packet_header(dsih_ctrl_t * instance, uint8_t vc, uint8_t packet_type, uint8_t ms_byte, uint8_t ls_byte)
+{
+ if (vc < 4)
+ {
+ mipi_dsih_write_part(instance, R_DSI_HOST_GEN_HDR, (ms_byte << 16) | (ls_byte << 8 ) | ((vc << 6) | packet_type), 0, 24);
+ return OK;
+ }
+ return ERR_DSI_OVERFLOW;
+}
+/**
+ * Write the payload of the long packet commands
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param payload array of bytes of payload
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_gen_packet_payload(dsih_ctrl_t * instance, uint32_t payload)
+{
+ if (mipi_dsih_hal_gen_write_fifo_full(instance))
+ {
+ return ERR_DSI_OVERFLOW;
+ }
+ mipi_dsih_write_word(instance, R_DSI_HOST_GEN_PLD_DATA, payload);
+ return OK;
+
+}
+/**
+ * Write the payload of the long packet commands
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param payload pointer to 32-bit array to hold read information
+ * @return error code
+ */
+dsih_error_t mipi_dsih_hal_gen_read_payload(dsih_ctrl_t * instance, uint32_t* payload)
+{
+ *payload = mipi_dsih_read_word(instance, R_DSI_HOST_GEN_PLD_DATA);
+ return OK;
+}
+
+/**
+ * Configure the read back virtual channel for the generic interface
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param vc to listen to on the line
+ */
+void mipi_dsih_hal_gen_rd_vc(dsih_ctrl_t * instance, uint8_t vc)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_GEN_VCID, vc, 0, 2);
+}
+/**
+ * Enable EOTp reception
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable
+ */
+void mipi_dsih_hal_gen_eotp_rx_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_PCKHDL_CFG, enable, 1, 1);
+}
+/**
+ * Enable EOTp transmission
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable
+ */
+void mipi_dsih_hal_gen_eotp_tx_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_PCKHDL_CFG, enable, 0, 1);
+}
+/**
+ * Enable Bus Turn-around request
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable
+ */
+void mipi_dsih_hal_bta_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_PCKHDL_CFG, enable, 2, 1);
+}
+/**
+ * Enable ECC reception, error correction and reporting
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable
+ */
+void mipi_dsih_hal_gen_ecc_rx_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_PCKHDL_CFG, enable, 3, 1);
+}
+/**
+ * Enable CRC reception, error reporting
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable
+ */
+void mipi_dsih_hal_gen_crc_rx_en(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_PCKHDL_CFG, enable, 4, 1);
+}
+/**
+ * Get status of read command
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return 1 if busy
+ */
+int mipi_dsih_hal_gen_rd_cmd_busy(dsih_ctrl_t * instance)
+{
+ return mipi_dsih_read_part(instance, R_DSI_HOST_CMD_PKT_STATUS, 6, 1);
+}
+/**
+ * Get the FULL status of generic read payload fifo
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return 1 if fifo full
+ */
+int mipi_dsih_hal_gen_read_fifo_full(dsih_ctrl_t * instance)
+{
+ return mipi_dsih_read_part(instance, R_DSI_HOST_CMD_PKT_STATUS, 5, 1);
+}
+/**
+ * Get the EMPTY status of generic read payload fifo
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return 1 if fifo empty
+ */
+int mipi_dsih_hal_gen_read_fifo_empty(dsih_ctrl_t * instance)
+{
+ return mipi_dsih_read_part(instance, R_DSI_HOST_CMD_PKT_STATUS, 4, 1);
+}
+/**
+ * Get the FULL status of generic write payload fifo
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return 1 if fifo full
+ */
+int mipi_dsih_hal_gen_write_fifo_full(dsih_ctrl_t * instance)
+{
+ return mipi_dsih_read_part(instance, R_DSI_HOST_CMD_PKT_STATUS, 3, 1);
+}
+/**
+ * Get the EMPTY status of generic write payload fifo
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return 1 if fifo empty
+ */
+int mipi_dsih_hal_gen_write_fifo_empty(dsih_ctrl_t * instance)
+{
+ return mipi_dsih_read_part(instance, R_DSI_HOST_CMD_PKT_STATUS, 2, 1);
+}
+/**
+ * Get the FULL status of generic command fifo
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return 1 if fifo full
+ */
+int mipi_dsih_hal_gen_cmd_fifo_full(dsih_ctrl_t * instance)
+{
+ return mipi_dsih_read_part(instance, R_DSI_HOST_CMD_PKT_STATUS, 1, 1);
+}
+/**
+ * Get the EMPTY status of generic command fifo
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return 1 if fifo empty
+ */
+int mipi_dsih_hal_gen_cmd_fifo_empty(dsih_ctrl_t * instance)
+{
+ return mipi_dsih_read_part(instance, R_DSI_HOST_CMD_PKT_STATUS, 0, 1);
+}
+/* only if DPI */
+/**
+ * Configure how many cycles of byte clock would the PHY module take
+ * to switch data lane from high speed to low power
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles
+ * @return error code
+ */
+dsih_error_t mipi_dsih_phy_hs2lp_config(dsih_ctrl_t * instance, uint8_t no_of_byte_cycles)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_PHY_TMR_CFG, no_of_byte_cycles, 24, 8);
+ return OK;
+}
+/**
+ * Configure how many cycles of byte clock would the PHY module take
+ * to switch the data lane from to low power high speed
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles
+ * @return error code
+ */
+dsih_error_t mipi_dsih_phy_lp2hs_config(dsih_ctrl_t * instance, uint8_t no_of_byte_cycles)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_PHY_TMR_CFG, no_of_byte_cycles, 16, 8);
+ return OK;
+}
+/**
+ * Configure how many cycles of byte clock would the PHY module take
+ * to switch clock lane from high speed to low power
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles
+ * @return error code
+ */
+dsih_error_t mipi_dsih_phy_clk_hs2lp_config(dsih_ctrl_t * instance, uint8_t no_of_byte_cycles)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_PHY_TMR_LPCLK_CFG, no_of_byte_cycles, 16, 10);
+ return OK;
+}
+/**
+ * Configure how many cycles of byte clock would the PHY module take
+ * to switch clock lane from to low power high speed
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles
+ * @return error code
+ */
+dsih_error_t mipi_dsih_phy_clk_lp2hs_config(dsih_ctrl_t * instance, uint8_t no_of_byte_cycles)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_PHY_TMR_LPCLK_CFG, no_of_byte_cycles, 0, 10);
+ return OK;
+}
+/**
+ * Configure how many cycles of byte clock would the PHY module take
+ * to turn the bus around to start receiving
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles
+ * @return error code
+ */
+dsih_error_t mipi_dsih_phy_bta_time(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ /*Jessica modified: From ASIC, the second table in spec is correct, this 15 bits are max rd time*/
+ if (no_of_byte_cycles < 0x8000) /* 15-bit field */
+ {
+ //mipi_dsih_write_part(instance, R_DSI_HOST_PHY_TMR_CFG, no_of_byte_cycles, 0, 12);
+ mipi_dsih_write_part(instance, R_DSI_HOST_PHY_TMR_CFG, no_of_byte_cycles, 0, 15);
+ }
+ else
+ {
+ return ERR_DSI_OVERFLOW;
+ }
+ return OK;
+}
+/**
+ * Enable the automatic mechanism to stop providing clock in the clock
+ * lane when time allows
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param enable
+ * @return error code
+ */
+void mipi_dsih_non_continuous_clock(dsih_ctrl_t * instance, int enable)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_LPCLK_CTRL, enable, 1, 1);
+}
+/**
+ * Get the status of the automatic mechanism to stop providing clock in the
+ * clock lane when time allows
+ * @param instance pointer to structure holding the DSI Host core information
+ * @return status 1 (enabled) 0 (disabled)
+ */
+int mipi_dsih_non_continuous_clock_status(dsih_ctrl_t * instance)
+{
+ return mipi_dsih_read_part(instance, R_DSI_HOST_LPCLK_CTRL, 1, 1);
+}
+/* PRESP Time outs */
+/**
+ * Timeout for peripheral (for controller to stay still) after LP data
+ * transmission write requests
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the
+ * link still, after sending a low power write operation. This period is
+ * measured in cycles of lanebyteclk
+ */
+void mipi_dsih_hal_presp_timeout_low_power_write(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_LP_WR_TO_CNT, no_of_byte_cycles, 0, 16);
+}
+/**
+ * Timeout for peripheral (for controller to stay still) after LP data
+ * transmission read requests
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the
+ * link still, after sending a low power read operation. This period is
+ * measured in cycles of lanebyteclk
+ */
+void mipi_dsih_hal_presp_timeout_low_power_read(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_LP_RD_TO_CNT, no_of_byte_cycles, 0, 16);
+}
+/**
+ * Timeout for peripheral (for controller to stay still) after HS data
+ * transmission write requests
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the
+ * link still, after sending a high-speed write operation. This period is
+ * measured in cycles of lanebyteclk
+ */
+void mipi_dsih_hal_presp_timeout_high_speed_write(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_HS_WR_TO_CNT, no_of_byte_cycles, 0, 16);
+}
+/**
+ * Timeout for peripheral between HS data transmission read requests
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the
+ * link still, after sending a high-speed read operation. This period is
+ * measured in cycles of lanebyteclk
+ */
+void mipi_dsih_hal_presp_timeout_high_speed_read(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_HS_RD_TO_CNT, no_of_byte_cycles, 0, 16);
+}
+/**
+ * Timeout for peripheral (for controller to stay still) after bus turn around
+ * @param instance pointer to structure holding the DSI Host core information
+ * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the
+ * link still, after sending a BTA operation. This period is
+ * measured in cycles of lanebyteclk
+ */
+void mipi_dsih_hal_presp_timeout_bta(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)
+{
+ mipi_dsih_write_part(instance, R_DSI_HOST_BTA_TO_CNT, no_of_byte_cycles, 0, 16);
+}
diff --git a/drivers/autotst/mipi_dsih_hal.h b/drivers/autotst/mipi_dsih_hal.h
new file mode 100644
index 00000000..72c6ff75
--- /dev/null
+++ b/drivers/autotst/mipi_dsih_hal.h
@@ -0,0 +1,1804 @@
+/*
+ * @file mipi_dsih_hal.h
+ *
+ * Synopsys Inc.
+ * SG DWC PT02
+ */
+/*
+ The Synopsys Software Driver and documentation (hereinafter "Software")
+ is an unsupported proprietary work of Synopsys, Inc. unless otherwise
+ expressly agreed to in writing between Synopsys and you.
+
+ The Software IS NOT an item of Licensed Software or Licensed Product under
+ any End User Software License Agreement or Agreement for Licensed Product
+ with Synopsys or any supplement thereto. Permission is hereby granted,
+ free of charge, to any person obtaining a copy of this software annotated
+ with this license and the Software, to deal in the Software without
+ restriction, including without limitation the rights to use, copy, modify,
+ merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so, subject
+ to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+ */
+
+#ifndef MIPI_DSIH_HAL_H_
+#define MIPI_DSIH_HAL_H_
+
+#include "mipi_dsih_local.h"
+
+#define R_DSI_HOST_VERSION (0x00)
+#define R_DSI_HOST_PWR_UP (0x04)
+#define R_DSI_HOST_CLK_MGR (0x08)
+#define R_DSI_HOST_DPI_VCID (0x0C)
+#define R_DSI_HOST_DPI_COLOR_CODE (0x10)
+#define R_DSI_HOST_DPI_CFG_POL (0x14)
+#define R_DSI_HOST_DPI_LP_CMD_TIM (0x18)
+#define R_DSI_HOST_DBI_VCID (0x1C)
+#define R_DSI_HOST_DBI_CFG (0x20)
+#define R_DSI_HOST_DBI_PARTITION_EN (0x24)
+#define R_DSI_HOST_DBI_CMDSIZE (0x28)
+#define R_DSI_HOST_PCKHDL_CFG (0x2C)
+#define R_DSI_HOST_GEN_VCID (0x30)
+#define R_DSI_HOST_MODE_CFG (0x34)
+#define R_DSI_HOST_VID_MODE_CFG (0x38)
+#define R_DSI_HOST_VID_PKT_SIZE (0x3C)
+#define R_DSI_HOST_VID_NUM_CHUNKS (0x40)
+#define R_DSI_HOST_VID_NULL_SIZE (0x44)
+#define R_DSI_HOST_VID_HSA_TIME (0x48)
+#define R_DSI_HOST_VID_HBP_TIME (0x4C)
+#define R_DSI_HOST_VID_HLINE_TIME (0x50)
+#define R_DSI_HOST_VID_VSA_LINES (0x54)
+#define R_DSI_HOST_VID_VBP_LINES (0x58)
+#define R_DSI_HOST_VID_VFP_LINES (0x5C)
+#define R_DSI_HOST_VID_VACTIVE_LINES (0x60)
+#define R_DSI_HOST_EDPI_CMD_SIZE (0x64)
+#define R_DSI_HOST_CMD_MODE_CFG (0x68)
+#define R_DSI_HOST_GEN_HDR (0x6C)
+#define R_DSI_HOST_GEN_PLD_DATA (0x70)
+#define R_DSI_HOST_CMD_PKT_STATUS (0x74)
+#define R_DSI_HOST_TO_CNT_CFG (0x78)
+#define R_DSI_HOST_HS_RD_TO_CNT (0x7C)
+#define R_DSI_HOST_LP_RD_TO_CNT (0x80)
+#define R_DSI_HOST_HS_WR_TO_CNT (0x84)
+#define R_DSI_HOST_LP_WR_TO_CNT (0x88)
+#define R_DSI_HOST_BTA_TO_CNT (0x8C)
+
+#define R_DSI_HOST_SDF_3D (0x90)
+
+#define R_DSI_HOST_LPCLK_CTRL (0x94)
+#define R_DSI_HOST_PHY_TMR_LPCLK_CFG (0x98)
+#define R_DSI_HOST_PHY_TMR_CFG (0x9C)
+#define R_DSI_HOST_INT_ST0 (0xBC)
+#define R_DSI_HOST_INT_ST1 (0xC0)
+#define R_DSI_HOST_INT_MSK0 (0xC4)
+#define R_DSI_HOST_INT_MSK1 (0xC8)
+#define R_DSI_HOST_PHY_STATUS (0xB0)
+
+
+
+typedef enum _Dsi_Int0_Type_ {
+ ack_with_err_0,
+ ack_with_err_1,
+ ack_with_err_2,
+ ack_with_err_3,
+ ack_with_err_4,
+ ack_with_err_5,
+ ack_with_err_6,
+ ack_with_err_7,
+ ack_with_err_8,
+ ack_with_err_9,
+ ack_with_err_10,
+ ack_with_err_11,
+ ack_with_err_12,
+ ack_with_err_13,
+ ack_with_err_14,
+ ack_with_err_15,
+ dphy_errors_0,
+ dphy_errors_1,
+ dphy_errors_2,
+ dphy_errors_3,
+ dphy_errors_4,
+ DSI_INT0_MAX,
+}Dsi_Int0_Type;
+
+typedef enum _Dsi_Int1_Type_ {
+ to_hs_tx,
+ to_lp_rx,
+ ecc_single_err,
+ ecc_multi_err,
+ crc_err,
+ pkt_size_err,
+ eopt_err,
+ dpi_pld_wr_err,
+ gen_cmd_wr_err,
+ gen_pld_wr_err,
+ gen_pld_send_err,
+ gen_pld_rd_err,
+ gen_pld_recv_err,
+ dbi_cmd_wr_err,
+ dbi_pld_wr_err,
+ dbi_pld_rd_err,
+ dbi_pld_recv_err,
+ dbi_illegal_comm_err,
+ DSI_INT1_MAX,
+}Dsi_Int1_Type;
+#define DSI_INT_MASK0_SET(bit,val)\
+{\
+ uint32_t reg_val = dsi_core_read_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_INT_MSK0);\
+ reg_val = (val == 1)?(reg_val | (1UL<<bit)):(reg_val & (~(1UL<<bit)));\
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_INT_MSK0, reg_val);\
+}
+
+#define DSI_INT_MASK1_SET(bit,val)\
+{\
+ uint32_t reg_val = dsi_core_read_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_INT_MSK1);\
+ reg_val = (val == 1)?(reg_val | (1UL<<bit)):(reg_val & (~(1UL<<bit)));\
+ dsi_core_write_function(SPRD_MIPI_DSIC_BASE, R_DSI_HOST_INT_MSK1, reg_val);\
+}
+
+
+//base :0x2180 0000
+typedef struct _DSIH1P21A_REG_T_
+{
+ union _DSIH1P21A_VERSION_tag_t {
+ struct _DSIH1P21A_VERSION_map_t
+ {
+volatile unsigned int version :
+ 32; //0x3132302A
+ }
+ mBits;
+ volatile unsigned int dwVersion;
+ }VERSION;// 0x0000
+
+ union _DSIH1P21A_PWR_UP_tag_t {
+ struct _DSIH1P21A_PWR_UP_map_t
+ {
+volatile unsigned int power_up :
+ 1; //[0] 1 power up , 0 reset core
+volatile unsigned int reserved_0 :
+ 31; //[31:1] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }PWR_UP;// 0x0004
+
+
+ union _DSIH1P21A_CLKMGR_CFG_tag_t {
+ struct _DSIH1P21A_CLKMGR_CFG_map_t
+ {
+volatile unsigned int tx_esc_clk_division :
+ 8; //[7:0] This field indicates the division factor for the TX Escape clock source (lanebyteclk). The values 0 and 1 stop the TX_ESC clock generation
+volatile unsigned int to_clk_division :
+ 8; //[15:8] This field indicates the division factor for the Time Out clock used as the timing unit in the configuration of HS to LP and LP to HS transition error.
+volatile unsigned int reserved_0 :
+ 16; //[31:16] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }CLKMGR_CFG;// 0x0008
+
+ union _DSIH1P21A_DPI_VCID_tag_t {
+ struct _DSIH1P21A_DPI_VCID_map_t
+ {
+volatile unsigned int dpi_vcid :
+ 2; //[1:0] This field configures the DPI virtual channel id that is indexed to the Video mode packets.
+volatile unsigned int reserved_0 :
+ 30; //[31:2] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }DPI_VCID;// 0x000C
+ //======================
+
+ union _DSIH1P21A_DPI_COLOR_CODING_tag_t {
+ struct _DSIH1P21A_DPI_COLOR_CODING_map_t
+ {
+volatile unsigned int dpi_color_coding :
+ 4; //[3:0]
+ /*
+ This field configures the DPI color coding as follows:
+ 0000: 16-bit configuration 1
+ 0001: 16-bit configuration 2
+ 0010: 16-bit configuration 3
+ 0011: 18-bit configuration 1
+ 0100: 18-bit configuration 2
+ 0101: 24-bit
+ 0110: 20-bit YCbCr 4:2:2 loosely packed
+ 0111: 24-bit YCbCr 4:2:2
+ 1000: 16-bit YCbCr 4:2:2
+ 1001: 30-bit
+ 1010: 36-bit
+ 1011-1111: 12-bit YCbCr 4:2:0
+ Note: If the eDPI interface is chosen and currently works in the
+ Command mode (cmd_video_mode = 1), then
+ 0110-1111: 24-bit
+ */
+volatile unsigned int reserved_0 :
+ 4; //[7:4] Reserved
+volatile unsigned int loosely18_en :
+ 1; //[8] When set to 1, this bit activates loosely packed variant to 18-bit configurations.
+volatile unsigned int reserved_1 :
+ 23; //[31:9] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }DPI_COLOR_CODING;// 0x0010
+
+
+ union _DSIH1P21A_DPI_CFG_POL_tag_t {
+ struct _DSIH1P21A_DPI_CFG_POL_map_t
+ {
+volatile unsigned int dataen_active_low :
+ 1; //[0] When set to 1, this bit configures the data enable pin (dpidataen) asactive low.
+volatile unsigned int vsync_active_low :
+ 1; //[1] When set to 1, this bit configures the vertical synchronism pin (dpivsync) as active low.
+volatile unsigned int hsync_active_low :
+ 1; //[2] When set to 1, this bit configures the horizontal synchronism pin (dpihsync) as active low.
+volatile unsigned int shutd_active_low :
+ 1; //[3] When set to 1, this bit configures the shutdown pin (dpishutdn) as active low
+volatile unsigned int colorm_active_low :
+ 1; //[4] When set to 1, this bit configures the color mode pin (dpicolorm) as active low.
+volatile unsigned int reserved_0 :
+ 27; //[31:5]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }DPI_CFG_POL;// 0x0014
+
+
+ union _DSIH1P21A_DPI_LP_CMD_TIM_tag_t {
+ struct _DSIH1P21A_DPI_LP_CMD_TIM_map_t
+ {
+volatile unsigned int invact_lpcmd_time :
+ 8; //[7:0] This field is used for the transmission of commands in low-power mode. It defines the size, in bytes, of the largest packet that can fit in a line during the VACT region.
+volatile unsigned int reserved_0 :
+ 8; //[15:8] Reserved
+volatile unsigned int outvact_lpcmd_time :
+ 8; //[23:16] This field is used for the transmission of commands in low-power mode. It defines the size, in bytes, of the largest packet that can fit in a line during the VSA, VBP, and VFP regions.
+volatile unsigned int reserved_1 :
+ 8; //[31:24] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }DPI_LP_CMD_TIM;// 0x0018
+
+ union _DSIH1P21A_DBI_VCID_tag_t {
+ struct _DSIH1P21A_DBI_VCID_map_t
+ {
+volatile unsigned int dbi_vcid :
+ 2; //[1:0] This field configures the virtual channel id that is indexed to the DCS packets from DBI.
+volatile unsigned int reserved_0 :
+ 30; //[31:2] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }DBI_VCID;// 0x001C
+
+ union _DSIH1P21A_DBI_CFG_tag_t {
+ struct _DSIH1P21A_DBI_CFG_map_t
+ {
+volatile unsigned int in_dbi_conf :
+ 4; //[3:0]
+ /*
+ This field configures the DBI input pixel data as follows:
+ 0000: 8-bit 8 bpp
+ 0001: 8-bit 12 bpp
+ 0010: 8-bit 16 bpp
+ 0011: 8-bit 18 bpp
+ 0100: 8-bit 24 bpp
+ 0101: 9-bit 18 bpp
+ 0110: 16-bit 8 bpp
+ 0111: 16-bit 12 bpp
+ 1000: 16-bit 16 bpp
+ 1001: 16-bit 18 bpp, option 1
+ 1010: 16-bit 18 bpp, option 2
+ 1011: 16-bit 24 bpp, option 1
+ 1100: 16-bit 24 bpp, option 2
+ */
+volatile unsigned int reserved_0 :
+ 4; //[7:4] Reserved
+volatile unsigned int out_dbi_conf :
+ 4; //[11:8]
+ /*
+ This field configures the DBI output pixel data as follows:
+ 0000: 8-bit 8 bpp
+ 0001: 8-bit 12 bpp
+ 0010: 8-bit 16 bpp
+ 0011: 8-bit 18 bpp
+ 0100: 8-bit 24 bpp
+ 0101: 9-bit 18 bpp
+ 0110: 16-bit 8 bpp
+ 0111: 16-bit 12 bpp
+ 1000: 16-bit 16 bpp
+ 1001: 16-bit 18 bpp, option 1
+ 1010: 16-bit 18 bpp, option 2
+ 1011: 16-bit 24 bpp, option 1
+ 1100: 16-bit 24 bpp, option 2
+ */
+volatile unsigned int reserved_1 :
+ 4; //[15:12] Reserved
+
+volatile unsigned int lut_size_conf :
+ 2; //[17:16]
+ /*
+ This field configures the size used to transport the write Lut
+ commands as follows:
+ 00: 16-bit color display
+ 01: 18-bit color display
+ 10: 24-bit color display
+ 11: 16-bit color display
+ */
+
+volatile unsigned int reserved_2 :
+ 14; //[31:18] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }DBI_CFG;// 0x0020
+
+ union _DSIH1P21A_DBI_PARTITIONING_EN_tag_t {
+ struct _DSIH1P21A_DBI_PARTITIONING_EN_map_t
+ {
+volatile unsigned int partitioning_en :
+ 1; //[0]
+ /*
+ When set to 1, this bit enables the use of write_memory_continue
+ input commands (system needs to ensure correct partitioning of Long
+ Write commands). When not set, partitioning is automatically
+ performed in the DWC_mipi_dsi_host.
+ */
+volatile unsigned int reserved_0 :
+ 31; //[31:1] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }DBI_PARTITIONING_EN;// 0x0024
+
+ union _DSIH1P21A_DBI_CMDSIZE_tag_t {
+ struct _DSIH1P21A_DBI_CMDSIZE_map_t
+ {
+volatile unsigned int wr_cmd_size :
+ 16; //[15:0]
+ /*
+ This field configures the size of the DCS write memory commands.
+ The size of DSI packet payload is the actual payload size minus 1,
+ because the DCS command is in the DSI packet payload
+ */
+volatile unsigned int allowed_cmd_size :
+ 16; //[31:16]
+ /*
+ This field configures the maximum allowed size for a DCS write
+ memory command. This field is used to partition a write memory
+ command into one write_memory_start and a variable number of
+ write_memory_continue commands. It is only used if the
+ partitioning_en bit of the DBI_CFG register is disabled.
+ The size of the DSI packet payload is the actual payload size minus 1,
+ because the DCS command is in the DSI packet payload.
+ */
+
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }DBI_CMDSIZE;// 0x0028
+
+ union _DSIH1P21A_PCKHDL_CFG_tag_t {
+ struct _DSIH1P21A_PCKHDL_CFG_map_t
+ {
+volatile unsigned int eotp_tx_en :
+ 1; //[0] When set to 1, this bit enables the EoTp transmission
+volatile unsigned int eotp_rx_en :
+ 1; //[1] When set to 1, this bit enables the EoTp reception.
+volatile unsigned int bta_en :
+ 1; //[2] When set to 1, this bit enables the Bus Turn-Around (BTA) request.
+volatile unsigned int ecc_rx_en :
+ 1; //[3] When set to 1, this bit enables the ECC reception, error correction, and reporting.
+volatile unsigned int crc_rx_en :
+ 1; //[4] When set to 1, this bit enables the CRC reception and error reporting. Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3 or DSI_GENERIC = 1. Otherwise, this bit is reserved.
+volatile unsigned int reserved_0 :
+ 27; //[31:5]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }PCKHDL_CFG;// 0x002C
+
+ union _DSIH1P21A_GEN_VCID_tag_t {
+ struct _DSIH1P21A_GEN_VCID_map_t
+ {
+volatile unsigned int gen_vcid_rx :
+ 2; //[1:0] This field indicates the Generic interface read-back virtual channel identification.
+volatile unsigned int reserved_0 :
+ 30; //[31:2] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }GEN_VCID;// 0x0030
+
+ union _DSIH1P21A_MODE_CFG_tag_t {
+ struct _DSIH1P21A_MODE_CFG_map_t
+ {
+volatile unsigned int cmd_video_mode :
+ 1; //[0] This bit configures the operation mode:0: Video mode ; 1: Command mode
+volatile unsigned int reserved_0 :
+ 31; //[31:1] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }MODE_CFG;// 0x0034
+
+ union _DSIH1P21A_VID_MODE_CFG_tag_t {
+ struct _DSIH1P21A_VID_MODE_CFG_map_t
+ {
+volatile unsigned int vid_mode_type :
+ 2; //[1:0]
+ /*
+ This field indicates the video mode transmission type as follows:
+ 00: Non-burst with sync pulses
+ 01: Non-burst with sync events
+ 10 and 11: Burst mode
+ */
+volatile unsigned int reserved_0 :
+ 6; //[7:2]
+volatile unsigned int lp_vsa_en :
+ 1; //[8] When set to 1, this bit enables the return to low-power inside the VSA period when timing allows.
+volatile unsigned int lp_vbp_en :
+ 1; //[9] When set to 1, this bit enables the return to low-power inside the VBP period when timing allows.
+volatile unsigned int lp_vfp_en :
+ 1; //[10] When set to 1, this bit enables the return to low-power inside the VFP period when timing allows.
+volatile unsigned int lp_vact_en :
+ 1; //[11] When set to 1, this bit enables the return to low-power inside the VACT period when timing allows.
+volatile unsigned int lp_hbp_en :
+ 1; //[12] When set to 1, this bit enables the return to low-power inside the HBP period when timing allows.
+volatile unsigned int lp_hfp_en :
+ 1; //[13] When set to 1, this bit enables the return to low-power inside the HFP period when timing allows.
+volatile unsigned int frame_bta_ack_en :
+ 1; //[14] When set to 1, this bit enables the request for an acknowledgeresponse at the end of a frame
+volatile unsigned int lp_cmd_en :
+ 1; //[15] When set to 1, this bit enables the command transmission only in lowpower mode.
+volatile unsigned int reserved_1 :
+ 16; //[31:16]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_MODE_CFG;// 0x0038
+
+ union _DSIH1P21A_VID_PKT_SIZE_tag_t {
+ struct _DSIH1P21A_VID_PKT_SIZE_map_t
+ {
+volatile unsigned int vid_pkt_size :
+ 14; //[13:0] This field configures the number of pixels in a single video packet. For 18-bit not loosely packed data types, this number must be a multiple of 4. For YCbCr data types, it must be a multiple of 2, as described in the DSI specification.
+volatile unsigned int reserved_0 :
+ 18; //[31:14] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_PKT_SIZE;// 0x003C
+
+ union _DSIH1P21A_VID_NUM_CHUNKS_tag_t {
+ struct _DSIH1P21A_VID_NUM_CHUNKS_map_t
+ {
+volatile unsigned int vid_num_chunks :
+ 13; //[12:0]
+ /*
+ This register configures the number of chunks to be transmitted during
+ a Line period (a chunk consists of a video packet and a null packet).
+ If set to 0 or 1, the video line is transmitted in a single packet.
+ If set to 1, the packet is part of a chunk, so a null packet follows it if
+ vid_null_size > 0. Otherwise, multiple chunks are used to transmit each video line.
+ */
+volatile unsigned int reserved_0 :
+ 19; //[31:13] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_NUM_CHUNKS;// 0x0040
+
+ union _DSIH1P21A_VID_NULL_SIZE_tag_t {
+ struct _DSIH1P21A_VID_NULL_SIZE_map_t
+ {
+volatile unsigned int vid_null_size :
+ 13; //[12:0]
+ /*
+ This register configures the number of bytes inside a null packet.
+ Setting it to 0 disables the null packets.
+ */
+volatile unsigned int reserved_0 :
+ 19; //[31:13] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_NULL_SIZE;// 0x0044
+
+ union _DSIH1P21A_VID_HSA_TIME_tag_t {
+ struct _DSIH1P21A_VID_HSA_TIME_map_t
+ {
+volatile unsigned int vid_hsa_time :
+ 12; //[11:0] This field configures the Horizontal Synchronism Active period in lane byte clock cycles
+volatile unsigned int reserved_0 :
+ 20; //[31:12] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_HSA_TIME;// 0x0048
+
+ union _DSIH1P21A_VID_HBP_TIME_tag_t {
+ struct _DSIH1P21A_VID_HBP_TIME_map_t
+ {
+volatile unsigned int vid_hbp_time :
+ 12; //[11:0] This field configures the Horizontal Back Porch period in lane byte clock cycles.
+volatile unsigned int reserved_0 :
+ 20; //[31:12] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_HBP_TIME;// 0x004C
+
+ union _DSIH1P21A_VID_HLINE_TIME_tag_t {
+ struct _DSIH1P21A_VID_HLINE_TIME_map_t
+ {
+volatile unsigned int vid_hline_time :
+ 15; //[14:0] This field configures the size of the total line time (HSA+HBP+HACT+HFP) counted in lane byte clock cycles.
+volatile unsigned int reserved_0 :
+ 17; //[31:15] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_HLINE_TIME;// 0x0050
+
+ union _DSIH1P21A_VID_VSA_LINES_tag_t {
+ struct _DSIH1P21A_VID_VSA_LINES_map_t
+ {
+volatile unsigned int vsa_lines :
+ 10; //[9:0] This field configures the Vertical Synchronism Active period measured in number of horizontal lines
+volatile unsigned int reserved_0 :
+ 22; //[31:10] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_VSA_LINES;// 0x0054
+
+ union _DSIH1P21A_VID_VBP_LINES_tag_t {
+ struct _DSIH1P21A_VID_VBP_LINES_map_t
+ {
+volatile unsigned int vbp_lines :
+ 10; //[9:0] This field configures the Vertical Back Porch period measured in number of horizontal lines.
+volatile unsigned int reserved_0 :
+ 22; //[31:10] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_VBP_LINES;// 0x0058
+
+ union _DSIH1P21A_VID_VFP_LINES_tag_t {
+ struct _DSIH1P21A_VID_VFP_LINES_map_t
+ {
+volatile unsigned int vfp_lines :
+ 10; //[9:0] This field configures the Vertical Front Porch period measured in number of horizontal lines.
+volatile unsigned int reserved_0 :
+ 22; //[31:10] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_VFP_LINES;// 0x005C
+
+ union _DSIH1P21A_VID_VACTIVE_LINES_tag_t {
+ struct _DSIH1P21A_VID_VACTIVE_LINES_map_t
+ {
+volatile unsigned int v_active_lines :
+ 14; //[13:0] This field configures the Vertical Active period measured in number of horizontal lines.
+volatile unsigned int reserved_0 :
+ 18; //[31:14] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }VID_VACTIVE_LINES;// 0x0060
+
+ union _DSIH1P21A_EDPI_CMD_SIZE_tag_t {
+ struct _DSIH1P21A_EDPI_CMD_SIZE_map_t
+ {
+volatile unsigned int edpi_allowed_cmd_size :
+ 16; //[15:0] This field configures the maximum allowed size for an eDPI write memory command, measured in pixels. Automatic partitioning of data obtained from eDPI is permanently enabled.
+volatile unsigned int reserved_0 :
+ 16; //[31:16] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }EDPI_CMD_SIZE;// 0x0064
+
+ union _DSIH1P21A_CMD_MODE_CFG_tag_t {
+ struct _DSIH1P21A_CMD_MODE_CFG_map_t
+ {
+volatile unsigned int tear_fx_en :
+ 1; //[0] When set to 1, this bit enables the tearing effect acknowledge request.
+volatile unsigned int ack_rqst_en :
+ 1; //[1] When set to 1, this bit enables the acknowledge request after each packet transmission.
+volatile unsigned int reserved_0 :
+ 6; //[7:2]
+volatile unsigned int gen_sw_0p_tx :
+ 1; //[8] This bit configures the Generic short write packet with zero parameter command transmission type:0: High-speed 1: Low-power
+volatile unsigned int gen_sw_1p_tx :
+ 1; //[9] This bit configures the Generic short write packet with one parameter command transmission type: 0: High-speed 1: Low-power
+volatile unsigned int gen_sw_2p_tx :
+ 1; //[10] This bit configures the Generic short write packet with two parameters command transmission type:0: High-speed 1: Low-power
+volatile unsigned int gen_sr_0p_tx :
+ 1; //[11] This bit configures the Generic short read packet with zero parameter command transmission type:0: High-speed 1: Low-power
+volatile unsigned int gen_sr_1p_tx :
+ 1; //[12] This bit configures the Generic short read packet with one parameter command transmission type:0: High-speed 1: Low-power
+volatile unsigned int gen_sr_2p_tx :
+ 1; //[13] This bit configures the Generic short read packet with two parameters command transmission type:0: High-speed 1: Low-power
+volatile unsigned int gen_lw_tx :
+ 1; //[14] This bit configures the Generic long write packet command transmission type:0: High-speed 1: Low-power
+volatile unsigned int reserved_1 :
+ 1; //[15]
+volatile unsigned int dcs_sw_0p_tx :
+ 1; //[16] This bit configures the DCS short write packet with zero parameter command transmission type:0: High-speed 1: Low-power
+volatile unsigned int dcs_sw_1p_tx :
+ 1; //[17] This bit configures the DCS short write packet with one parameter command transmission type:0: High-speed 1: Low-power
+volatile unsigned int dcs_sr_0p_tx :
+ 1; //[18] This bit configures the DCS short read packet with zero parameter command transmission type:0: High-speed 1: Low-power
+volatile unsigned int dcs_lw_tx :
+ 1; //[19] This bit configures the DCS long write packet command transmission type:0: High-speed 1: Low-power
+volatile unsigned int reserved_2 :
+ 4; //[23:20]
+volatile unsigned int max_rd_pkt_size :
+ 1; //[24] This bit configures the maximum read packet size command transmission type:0: High-speed 1: Low-power
+volatile unsigned int reserved_3 :
+ 7; //[31:25]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }CMD_MODE_CFG;// 0x0068
+
+ union _DSIH1P21A_GEN_HDR_tag_t {
+ struct _DSIH1P21A_GEN_HDR_map_t
+ {
+volatile unsigned int gen_dt :
+ 6; //[5:0] This field configures the packet data type of the header packet.
+volatile unsigned int gen_vc :
+ 2; //[7:6] Reserved
+volatile unsigned int gen_wc_lsbyte :
+ 8; //[15:8] This field configures the least significant byte of the header packet's Word count for long packets or data 0 for short packets.
+volatile unsigned int gen_wc_msbyte :
+ 8; //[23:16] This field configures the most significant byte of the header packet's word count for long packets or data 1 for short packets.
+volatile unsigned int reserved_0 :
+ 8; //[31:24] Reserved
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }GEN_HDR;// 0x006C
+
+ union _DSIH1P21A_GEN_PLD_DATA_tag_t {
+ struct _DSIH1P21A_GEN_PLD_DATA_map_t
+ {
+volatile unsigned int gen_pld_b1 :
+ 8; //[7:0] This field indicates byte 1 of the packet payload.
+volatile unsigned int gen_pld_b2 :
+ 8; //[15:8] This field indicates byte 2 of the packet payload.
+volatile unsigned int gen_pld_b3 :
+ 8; //[23:16] This field indicates byte 3 of the packet payload.
+volatile unsigned int gen_pld_b4 :
+ 8; //[31:24] This field indicates byte 4 of the packet payload.
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }GEN_PLD_DATA;// 0x0070
+
+ union _DSIH1P21A_CMD_PKT_STATUS_tag_t {
+ struct _DSIH1P21A_CMD_PKT_STATUS_map_t
+ {
+volatile unsigned int gen_cmd_empty :
+ 1; //[0]
+ /*
+ This bit indicates the empty status of the generic command FIFO.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ Value after reset: 0x1
+ */
+volatile unsigned int gen_cmd_full :
+ 1; //[1]
+ /*
+ This bit indicates the full status of the generic command FIFO.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ Value after reset: 0x0
+ */
+volatile unsigned int gen_pld_w_empty :
+ 1; //[2]
+ /*
+ This bit indicates the empty status of the generic write payload FIFO.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ Value after reset: 0x1
+ */
+volatile unsigned int gen_pld_w_full :
+ 1; //[3]
+ /*
+ This bit indicates the full status of the generic write payload FIFO.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ Value after reset: 0x0
+ */
+volatile unsigned int gen_pld_r_empty :
+ 1; //[4]
+ /*
+ This bit indicates the empty status of the generic read payload FIFO.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ Value after reset: 0x1
+ */
+volatile unsigned int gen_pld_r_full :
+ 1; //[5]
+ /*
+ This bit indicates the full status of the generic read payload FIFO.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ Value after reset: 0x0
+ */
+volatile unsigned int gen_rd_cmd_busy :
+ 1; //[6]
+ /*
+ This bit is set when a read command is issued and cleared when the
+ entire response is stored in the FIFO.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ Value after reset: 0x0
+ */
+volatile unsigned int reserved_0 :
+ 1; //[7]
+ /*
+ */
+volatile unsigned int dbi_cmd_empy :
+ 1; //[8]
+ /*
+ This bit indicates the empty status of the DBI command FIFO.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ Value after reset: 0x1
+ */
+volatile unsigned int dbi_cmd_full :
+ 1; //[9]
+ /*
+ This bit indicates the full status of the DBI command FIFO.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ Value after reset: 0x0
+ */
+volatile unsigned int dbi_pld_w_empty :
+ 1; //[10]
+ /*
+ This bit indicates the empty status of the DBI write payload FIFO.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ Value after reset: 0x1
+ */
+volatile unsigned int dbi_pld_w_full :
+ 1; //[11]
+ /*
+ This bit indicates the full status of the DBI write payload FIFO.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ Value after reset: 0x0
+ */
+volatile unsigned int dbi_pld_r_empty :
+ 1; //[12]
+ /*
+ This bit indicates the empty status of the DBI read payload FIFO.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ Value after reset: 0x1
+ */
+volatile unsigned int dbi_pld_r_full :
+ 1; //[13]
+ /*
+ This bit indicates the full status of the DBI read payload FIFO.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ Value after reset: 0x0
+ */
+volatile unsigned int dbi_rd_cmd_busy :
+ 1; //[14]
+ /*
+ This bit is set when a read command is issued and cleared when the
+ entire response is stored in the FIFO.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ Value after reset: 0x0
+ */
+volatile unsigned int reserved_1 :
+ 17; //[31:15]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ CMD_PKT_STATUS;// 0x0074
+
+ union _DSIH1P21A_TO_CNT_CFG_tag_t {
+ struct _DSIH1P21A_TO_CNT_CFG_map_t
+ {
+volatile unsigned int lprx_to_cnt :
+ 16; //[15:0]
+ /*
+ This field configures the timeout counter that triggers a low-power
+ reception timeout contention detection (measured in
+ TO_CLK_DIVISION cycles).
+ */
+volatile unsigned int hstx_to_cnt :
+ 16; //[31:16]
+ /*
+ This field configures the timeout counter that triggers a high-speed
+ transmission timeout contention detection (measured in
+ TO_CLK_DIVISION cycles).
+ If using the non-burst mode and there is no sufficient time to switch
+ from HS to LP and back in the period which is from one line data
+ finishing to the next line sync start, the DSI link returns the LP state
+ once per frame, then you should configure the TO_CLK_DIVISION
+ and hstx_to_cnt to be in accordance with:
+ hstx_to_cnt * lanebyteclkperiod * TO_CLK_DIVISION >= the time of
+ one FRAME data transmission * (1 + 10%)
+ In burst mode, RGB pixel packets are time-compressed, leaving more
+ time during a scan line. Therefore, if in burst mode and there is
+ sufficient time to switch from HS to LP and back in the period of time
+ from one line data finishing to the next line sync start, the DSI link can
+ return LP mode and back in this time interval to save power. For this,
+ configure the TO_CLK_DIVISION and hstx_to_cnt to be in accordance
+ with:
+ hstx_to_cnt * lanebyteclkperiod * TO_CLK_DIVISION >= the time of
+ one LINE data transmission * (1 + 10%)
+ */
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ TO_CNT_CFG;// 0x0078
+
+ union _DSIH1P21A_HS_RD_TO_CNT_tag_t {
+ struct _DSIH1P21A_HS_RD_TO_CNT_map_t
+ {
+volatile unsigned int hs_rd_to_cnt :
+ 16; //[15:0]
+ /*
+ This field sets a period for which the DWC_mipi_dsi_host keeps the
+ link still, after sending a high-speed read operation. This period is
+ measured in cycles of lanebyteclk. The counting starts when the
+ D-PHY enters the Stop state and causes no interrupts.
+ */
+volatile unsigned int reserved_0 :
+ 16; //[31:16]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ HS_RD_TO_CNT;// 0x007C
+
+ union _DSIH1P21A_LP_RD_TO_CNT_tag_t {
+ struct _DSIH1P21A_LP_RD_TO_CNT_map_t
+ {
+volatile unsigned int lp_rd_to_cnt :
+ 16; //[15:0]
+ /*
+ This field sets a period for which the DWC_mipi_dsi_host keeps the
+ link still, after sending a low-power read operation. This period is
+ measured in cycles of lanebyteclk. The counting starts when the
+ D-PHY enters the Stop state and causes no interrupts.
+ */
+volatile unsigned int reserved_0 :
+ 16; //[31:16]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ LP_RD_TO_CNT;// 0x0080
+
+ union _DSIH1P21A_HS_WR_TO_CNT_tag_t {
+ struct _DSIH1P21A_HS_WR_TO_CNT_map_t
+ {
+volatile unsigned int hs_wr_to_cnt :
+ 16; //[15:0]
+ /*
+ This field sets a period for which the DWC_mipi_dsi_host keeps the
+ link inactive after sending a high-speed write operation. This period is
+ measured in cycles of lanebyteclk. The counting starts when the
+ D-PHY enters the Stop state and causes no interrupts.
+ */
+volatile unsigned int reserved_0 :
+ 8; //[23:16]
+volatile unsigned int presp_to_mode :
+ 1; //[24]
+ /*
+ When set to 1, this bit ensures that the peripheral response timeout
+ caused by hs_wr_to_cnt is used only once per eDPI frame, when both
+ the following conditions are met:
+ dpivsync_edpiwms has risen and fallen.
+ Packets originated from eDPI have been transmitted and its FIFO
+ is empty again.
+ In this scenario no non-eDPI requests are sent to the D-PHY, even if
+ there is traffic from generic or DBI ready to be sent, making it return to
+ stop state. When it does so, PRESP_TO counter is activated and only
+ when it finishes does the controller send any other traffic that is ready.
+ Dependency: DSI_DATAINTERFACE = 4. Otherwise, this bit is
+ reserved.
+ */
+volatile unsigned int reserved_1 :
+ 7; //[31:25]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ HS_WR_TO_CNT;// 0x0084
+
+ union _DSIH1P21A_LP_WR_TO_CNT_tag_t {
+ struct _DSIH1P21A_LP_WR_TO_CNT_map_t
+ {
+volatile unsigned int lp_wr_to_cnt :
+ 16; //[15:0]
+ /*
+ This field sets a period for which the DWC_mipi_dsi_host keeps the
+ link still, after sending a low-power write operation. This period is
+ measured in cycles of lanebyteclk. The counting starts when the
+ D-PHY enters the Stop state and causes no interrupts
+ */
+volatile unsigned int reserved_0 :
+ 16; //[31:16]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ LP_WR_TO_CNT;// 0x0088
+
+ union _DSIH1P21A_BTA_TO_CNT_tag_t {
+ struct _DSIH1P21A_BTA_TO_CNT_map_t
+ {
+volatile unsigned int bta_to_cnt :
+ 16; //[15:0]
+ /*
+ This field sets a period for which the DWC_mipi_dsi_host keeps the
+ link still, after completing a Bus Turn-Around. This period is measured
+ in cycles of lanebyteclk. The counting starts when the D-PHY enters
+ the Stop state and causes no interrupts.
+ */
+volatile unsigned int reserved_0 :
+ 16; //[31:16]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ BTA_TO_CNT;// 0x008C
+
+ union _DSIH1P21A_SDF_3D_tag_t {
+ struct _DSIH1P21A_SDF_3D_map_t
+ {
+volatile unsigned int mode_3d :
+ 2; //[1:0]
+ /*
+ This field defines the 3D mode on/off and display orientation:
+ 00: 3D mode off (2D mode on)
+ 01: 3D mode on, portrait orientation
+ 10: 3D mode on, landscape orientation
+ 11: Reserved
+
+ */
+volatile unsigned int ormat_3d :
+ 2; //[3:2]
+ /*
+ This field defines the 3D image format:
+ 00: Line (alternating lines of left and right data)
+ 01: Frame (alternating frames of left and right data)
+ 10: Pixel (alternating pixels of left and right data)
+ 11: Reserved
+
+ */
+volatile unsigned int second_vsync :
+ 1; //[4]
+ /*
+ This field defines whether there is a second VSYNC pulse between
+ Left and Right Images, when 3D Image Format is Frame-based:
+ 0: No sync pulses between left and right data
+ 1: Sync pulse (HSYNC, VSYNC, blanking) between left and right
+ data
+ */
+volatile unsigned int right_first :
+ 1; //[5]
+ /*
+ This bit defines the left or right order:
+ 0: Left eye data is sent first, and then the right eye data is sent.
+ 1: Right eye data is sent first, and then the left eye data is sent.
+ */
+volatile unsigned int reserved_0 :
+ 10; //[15:6]
+volatile unsigned int send_3d_cfg :
+ 1; //[16]
+ /*
+ When set, causes the next VSS packet to include 3D control payload
+ in every VSS packet.
+ */
+volatile unsigned int reserved_1 :
+ 15; //[31:17]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ SDF_3D;// 0x0090
+
+ union _DSIH1P21A_LPCLK_CTRL_tag_t {
+ struct _DSIH1P21A_LPCLK_CTRL_map_t
+ {
+volatile unsigned int phy_txrequestclkhs :
+ 1; //[0] This bit controls the D-PHY PPI txrequestclkhs signal
+volatile unsigned int auto_clklane_ctrl :
+ 1; //[0] This bit enables the automatic mechanism to stop providing clock in the clock lane when time allows
+volatile unsigned int reserved_0 :
+ 30; //[31:2]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ LPCLK_CTRL;// 0x0094
+
+ union _DSIH1P21A_PHY_TMR_LPCLK_CFG_tag_t {
+ struct _DSIH1P21A_PHY_TMR_LPCLK_CFG_map_t
+ {
+volatile unsigned int phy_clklp2hs_time :
+ 10; //[9:0]
+ /*
+ This field configures the maximum time that the D-PHY clock lane
+ takes to go from low-power to high-speed transmission measured in
+ lane byte clock cycles.
+ */
+volatile unsigned int reserved_0 :
+ 6; //[15:10]
+volatile unsigned int phy_clkhs2lp_time :
+ 10; //[25:16]
+ /*
+ This field configures the maximum time that the D-PHY clock lane
+ takes to go from high-speed to low-power transmission measured in
+ lane byte clock cycles.
+ */
+volatile unsigned int reserved_1 :
+ 6; //[31:26]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ PHY_TMR_LPCLK_CFG;// 0x0098
+
+ union _DSIH1P21A_PHY_TMR_CFG_tag_t {
+ struct _DSIH1P21A_PHY_TMR_CFG_map_t
+ {
+volatile unsigned int max_rd_time :
+ 15; //[14:0]
+ /*
+ This field configures the maximum time required to perform a read
+ command in lane byte clock cycles. This register can only be modified
+ when no read command is in progress.
+ */
+volatile unsigned int reserved_0 :
+ 1; //[15]
+volatile unsigned int phy_lp2hs_time :
+ 8; //[23:16]
+ /*
+ This field configures the maximum time that the D-PHY data lanes
+ take to go from low-power to high-speed transmission measured in
+ lane byte clock cycles.
+ */
+volatile unsigned int phy_hs2lp_time :
+ 8; //[31:24]
+ /*
+ This field configures the maximum time that the D-PHY data lanes
+ take to go from high-speed to low-power transmission measured in
+ lane byte clock cycles.
+ */
+ }
+ mBits;
+ volatile unsigned int dValue;
+ } PHY_TMR_CFG;// 0x009C
+
+ union _DSIH1P21A_PHY_RSTZ_tag_t {
+ struct _DSIH1P21A_PHY_RSTZ_map_t
+ {
+volatile unsigned int phy_shutdownz :
+ 1; //[0] When set to 0, this bit places the D-PHY macro in power-down state
+volatile unsigned int phy_rstz :
+ 1; //[1] When set to 0, this bit places the digital section of the D-PHY in the reset state.
+volatile unsigned int phy_enableclk :
+ 1; //[2] When set to1, this bit enables the D-PHY Clock Lane module.
+volatile unsigned int phy_forcepll :
+ 1; //[3]
+ /*
+ When the D-PHY is in ULPS, this bit enables the D-PHY PLL.
+ Dependency: DSI_HOST_FPGA = 0. Otherwise, this bit is reserved
+ */
+volatile unsigned int reserved_0 :
+ 28; //[31:4]
+ }
+ mBits;
+ volatile unsigned int dValue;
+
+ } PHY_RSTZ;// 0x00A0
+
+ union _DSIH1P21A_PHY_IF_CFG_tag_t {
+ struct _DSIH1P21A_PHY_IF_CFG_map_t
+ {
+volatile unsigned int n_lanes :
+ 2; //[1:0]
+ /*
+ This field configures the number of active data lanes:
+ 00: One data lane (lane 0)
+ 01: Two data lanes (lanes 0 and 1)
+ 10: Three data lanes (lanes 0, 1, and 2)
+ 11: Four data lanes (lanes 0, 1, 2, and 3)
+ */
+volatile unsigned int reserved_0 :
+ 6; //[7:2]
+volatile unsigned int phy_stop_wait_time :
+ 8; //[15:8] This field configures the minimum wait period to request a high-speed transmission after the Stop state.
+volatile unsigned int reserved_1 :
+ 16; //[31:16]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }PHY_IF_CFG;// 0x00A4
+
+ union _DSIH1P21A_PHY_ULPS_CTRL_tag_t {
+ struct _DSIH1P21A_PHY_ULPS_CTRL_map_t
+ {
+volatile unsigned int phy_txrequlpsclk :
+ 1; //[0] ULPS mode Request on clock lane.
+volatile unsigned int phy_txexitulpsclk :
+ 1; //[1] ULPS mode Exit on clock lane.
+volatile unsigned int phy_txrequlpslan :
+ 1; //[2] ULPS mode Request on all active data lanes.
+volatile unsigned int phy_txexitulpslan :
+ 1; //[3] ULPS mode Exit on all active data lanes.
+volatile unsigned int reserved_0 :
+ 28; //[31:4]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ PHY_ULPS_CTRL;// 0x00A8
+
+ union _DSIH1P21A_PHY_TX_TRIGGERS_tag_t {
+ struct _DSIH1P21A_PHY_TX_TRIGGERS_map_t
+ {
+volatile unsigned int phy_tx_triggers :
+ 4; //[3:0] This field controls the trigger transmissions
+volatile unsigned int reserved_0 :
+ 28; //[31:4]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ PHY_TX_TRIGGERS;// 0x00AC
+
+ union _DSIH1P21A_PHY_STATUS_tag_t {
+ struct _DSIH1P21A_PHY_STATUS_map_t
+ {
+volatile unsigned int phy_lock :
+ 1; //[0] This bit indicates the status of phylock D-PHY signal.
+volatile unsigned int phy_direction :
+ 1; //[1] This bit indicates the status of phydirection D-PHY signal.
+volatile unsigned int phy_stopstateclklane :
+ 1; //[2] This bit indicates the status of phystopstateclklane D-PHY signal.
+volatile unsigned int phy_ulpsactivenotclk :
+ 1; //[3] This bit indicates the status of phyulpsactivenotclk D-PHY signal.
+volatile unsigned int phy_stopstate0lane :
+ 1; //[4] This bit indicates the status of phystopstate0lane D-PHY signal.
+volatile unsigned int phy_ulpsactivenot0lane :
+ 1; //[5] This bit indicates the status of ulpsactivenot0lane D-PHY signal.
+volatile unsigned int phy_rxulpsesc0lane :
+ 1; //[6] This bit indicates the status of rxulpsesc0lane D-PHY signal.
+volatile unsigned int phy_stopstate1lane :
+ 1; //[7]
+ /*
+ This bit indicates the status of phystopstate1lane D-PHY signal.
+ Dependency: DSI_HOST_NUMBER_OF_LANES > 1
+ If DSI_HOST_NUMBER_OF_LANES <= 1, this bit is reserved.
+ */
+volatile unsigned int phy_ulpsactivenot1lane :
+ 1; //[8]
+ /*
+ This bit indicates the status of ulpsactivenot1lane D-PHY signal.
+ Dependency: DSI_HOST_NUMBER_OF_LANES > 1
+ If DSI_HOST_NUMBER_OF_LANES <= 1, this bit is reserved.
+ */
+volatile unsigned int phy_stopstate2lane :
+ 1; //[9]
+ /*
+ This bit indicates the status of phystopstate2lane D-PHY signal.
+ Dependency: DSI_HOST_NUMBER_OF_LANES > 2
+ If DSI_HOST_NUMBER_OF_LANES <= 2, this bit is reserved.
+ */
+volatile unsigned int phy_ulpsactivenot2lane :
+ 1; //[10]
+ /*
+ This bit indicates the status of ulpsactivenot2lane D-PHY signal.
+ Dependency: DSI_HOST_NUMBER_OF_LANES > 2
+ If DSI_HOST_NUMBER_OF_LANES <= 2, this bit is reserved.
+ */
+volatile unsigned int phy_stopstate3lane :
+ 1; //[11]
+ /*
+ This bit indicates the status of phystopstate3lane D-PHY signal.
+ Dependency: DSI_HOST_NUMBER_OF_LANES > 3
+ If DSI_HOST_NUMBER_OF_LANES <= 3, this bit is reserved
+ */
+volatile unsigned int phy_ulpsactivenot3lane :
+ 1; //[12]
+ /*
+ This bit indicates the status of ulpsactivenot3lane D-PHY signal.
+ Dependency: DSI_HOST_NUMBER_OF_LANES > 3
+ If DSI_HOST_NUMBER_OF_LANES <= 3, this bit is reserved
+ */
+volatile unsigned int reserved_0 :
+ 19; //[31:13]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ } PHY_STATUS;// 0x00B0
+
+ union _DSIH1P21A_PHY_TST_CTRL0_tag_t {
+ struct _DSIH1P21A_PHY_TST_CTRL0_map_t
+ {
+volatile unsigned int phy_testclr :
+ 1; //[0] PHY test interface clear (active high).
+volatile unsigned int phy_testclk :
+ 1; //[1] This bit is used to clock the TESTDIN bus into the D-PHY.
+volatile unsigned int reserved_0 :
+ 30; //[31:2]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ PHY_TST_CTRL0;// 0x00B4
+
+ union _DSIH1P21A_PHY_TST_CTRL1_tag_t {
+ struct _DSIH1P21A_PHY_TST_CTRL1_map_t
+ {
+volatile unsigned int phy_testdin :
+ 8; //[7:0] PHY test interface input 8-bit data bus for internal register programming and test functionalities access.
+volatile unsigned int pht_testdout :
+ 8; //[15:8] PHY output 8-bit data bus for read-back and internal probing functionalities.
+volatile unsigned int phy_testen :
+ 1; //[16]
+ /*
+ PHY test interface operation selector:
+ 1: The address write operation is set on the falling edge of the testclk signal.
+ 0: The data write operation is set on the rising edge of the testclk signal.
+ */
+volatile unsigned int reserved_0 :
+ 15; //[31:17]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ PHY_TST_CTRL1;// 0x00B8
+
+ union _DSIH1P21A_INT_ST0_tag_t {
+ struct _DSIH1P21A_INT_ST0_map_t
+ {
+volatile unsigned int ack_with_err_0 :
+ 1; //[0] This bit retrieves the SoT error from the Acknowledge error report.
+volatile unsigned int ack_with_err_1 :
+ 1; //[1] This bit retrieves the SoT Sync error from the Acknowledge error report.
+volatile unsigned int ack_with_err_2 :
+ 1; //[2] This bit retrieves the EoT Sync error from the Acknowledge error report.
+volatile unsigned int ack_with_err_3 :
+ 1; //[3] This bit retrieves the Escape Mode Entry Command error from the Acknowledge error report.
+volatile unsigned int ack_with_err_4 :
+ 1; //[4] This bit retrieves the LP Transmit Sync error from the Acknowledge error report.
+volatile unsigned int ack_with_err_5 :
+ 1; //[5] This bit retrieves the Peripheral Timeout error from the Acknowledge Error report.
+volatile unsigned int ack_with_err_6 :
+ 1; //[6] This bit retrieves the False Control error from the Acknowledge error report.
+volatile unsigned int ack_with_err_7 :
+ 1; //[7] This bit retrieves the reserved (specific to device) from the Acknowledge error report.
+volatile unsigned int ack_with_err_8 :
+ 1; //[8] This bit retrieves the ECC error, single-bit (detected and corrected) from the Acknowledge error report.
+volatile unsigned int ack_with_err_9 :
+ 1; //[9] This bit retrieves the ECC error, multi-bit (detected, not corrected) from the Acknowledge error report.
+volatile unsigned int ack_with_err_10 :
+ 1; //[10]This bit retrieves the checksum error (long packet only) from the Acknowledge error report.
+volatile unsigned int ack_with_err_11 :
+ 1; //[11] This bit retrieves the not recognized DSI data type from the Acknowledge error report.
+volatile unsigned int ack_with_err_12 :
+ 1; //[12] This bit retrieves the DSI VC ID Invalid from the Acknowledge error report.
+volatile unsigned int ack_with_err_13 :
+ 1; //[13] This bit retrieves the invalid transmission length from the Acknowledge error report.
+volatile unsigned int ack_with_err_14 :
+ 1; //[14] This bit retrieves the reserved (specific to device) from the Acknowledge error report
+volatile unsigned int ack_with_err_15 :
+ 1; //[15] This bit retrieves the DSI protocol violation from the Acknowledge error report.
+volatile unsigned int dphy_errors_0 :
+ 1; //[16] This bit indicates ErrEsc escape entry error from Lane 0.
+volatile unsigned int dphy_errors_1 :
+ 1; //[17] This bit indicates ErrSyncEsc low-power data transmission synchronization error from Lane 0.
+volatile unsigned int dphy_errors_2 :
+ 1; //[18] This bit indicates the ErrControl error from Lane 0.
+volatile unsigned int dphy_errors_3 :
+ 1; //[19] This bit indicates the LP0 contention error ErrContentionLP0 from Lane 0.
+volatile unsigned int dphy_errors_4 :
+ 1; //[20] This bit indicates the LP1 contention error ErrContentionLP1 from Lane 0.
+volatile unsigned int reserved_0 :
+ 11; //[31:21]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ INT_ST0;// 0x00BC
+
+ union _DSIH1P21A_INT_ST1_tag_t {
+ struct _DSIH1P21A_INT_ST1_map_t
+ {
+volatile unsigned int to_hs_tx :
+ 1; //[0]
+ /*
+ This bit indicates that the high-speed transmission timeout counter
+ reached the end and contention is detected.
+ */
+volatile unsigned int to_lp_rx :
+ 1; //[1]
+ /*
+ This bit indicates that the low-power reception timeout counter reached
+ the end and contention is detected.
+ */
+volatile unsigned int ecc_single_err :
+ 1; //[2]
+ /*
+ This bit indicates that the ECC single error is detected and corrected in a
+ received packet.
+ */
+volatile unsigned int ecc_multi_err :
+ 1; //[3]
+ /*
+ This bit indicates that the ECC multiple error is detected in a received
+ packet.
+ */
+volatile unsigned int crc_err :
+ 1; //[4]
+ /*
+ This bit indicates that the CRC error is detected in the received packet
+ payload.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3 or
+ DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ */
+volatile unsigned int pkt_size_err :
+ 1; //[5]
+ /*
+ This bit indicates that the packet size error is detected during the packet
+ reception.
+ */
+volatile unsigned int eopt_err :
+ 1; //[6]
+ /*
+ This bit indicates that the EoTp packet is not received at the end of the
+ incoming peripheral transmission
+ */
+volatile unsigned int dpi_pld_wr_err :
+ 1; //[7]
+ /*
+ This bit indicates that during a DPI pixel line storage, the payload FIFO
+ becomes full and the data stored is corrupted.
+ Dependency: DSI_DATAINTERFACE = 2 or DSI_DATAINTERFACE = 3 or
+ DSI_DATAINTERFACE = 4. Otherwise, this bit is reserved.
+ */
+volatile unsigned int gen_cmd_wr_err :
+ 1; //[8]
+ /*
+ This bit indicates that the system tried to write a command through the
+ Generic interface and the FIFO is full. Therefore, the command is not
+ written.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved
+ */
+volatile unsigned int gen_pld_wr_err :
+ 1; //[9]
+ /*
+ This bit indicates that the system tried to write a payload data through the
+ Generic interface and the FIFO is full. Therefore, the payload is not
+ written.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved
+ */
+volatile unsigned int gen_pld_send_err :
+ 1; //[10]
+ /*
+ This bit indicates that during a Generic interface packet build, the payload
+ FIFO becomes empty and corrupt data is sent.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved
+ */
+volatile unsigned int gen_pld_rd_err :
+ 1; //[11]
+ /*
+ This bit indicates that during a DCS read data, the payload FIFO becomes
+ empty and the data sent to the interface is corrupted.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ */
+volatile unsigned int gen_pld_recev_err :
+ 1; //[12]
+ /*
+ This bit indicates that during a generic interface packet read back, the
+ payload FIFO becomes full and the received data is corrupted.
+ Dependency: DSI_GENERIC = 1
+ If DSI_GENERIC = 0, this bit is reserved.
+ */
+volatile unsigned int dbi_cmd_wr_err :
+ 1; //[13]
+ /*
+ This bit indicates that the system tried to write a command through the
+ DBI but the command FIFO is full. Therefore, the command is not written.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ */
+volatile unsigned int dbi_pld_wr_err :
+ 1; //[14]
+ /*
+ This bit indicates that the system tried to write the payload data through
+ the DBI interface and the FIFO is full. Therefore, the command is not
+ written.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ */
+volatile unsigned int dbi_pld_rd_err :
+ 1; //[15]
+ /*
+ This bit indicates that during a DCS read data, the payload FIFO goes
+ empty and the data sent to the interface is corrupted.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ */
+volatile unsigned int dbi_pld_recv_err :
+ 1; //[16]
+ /*
+ This bit indicates that during a DBI read back packet, the payload FIFO
+ becomes full and the received data is corrupted.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ */
+
+volatile unsigned int dbi_ilegal_comm_err :
+ 1; //[17]
+ /*
+ This bit indicates that an attempt to write an illegal command on the DBI
+ interface is made and the core is blocked by transmission.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ */
+volatile unsigned int reserved_0 :
+ 14; //[31:18]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ INT_ST1;// 0x00C0
+
+
+ union _DSIH1P21A_INT_MSK0_tag_t {
+ struct _DSIH1P21A_INT_MSK0_map_t
+ {
+volatile unsigned int ack_with_err_0 :
+ 1; //[0] This bit retrieves the SoT error from the Acknowledge error report.
+volatile unsigned int ack_with_err_1 :
+ 1; //[1] This bit retrieves the SoT Sync error from the Acknowledge error report.
+volatile unsigned int ack_with_err_2 :
+ 1; //[2] This bit retrieves the EoT Sync error from the Acknowledge error report.
+volatile unsigned int ack_with_err_3 :
+ 1; //[3] This bit retrieves the Escape Mode Entry Command error from the Acknowledge error report.
+volatile unsigned int ack_with_err_4 :
+ 1; //[4] This bit retrieves the LP Transmit Sync error from the Acknowledge error report.
+volatile unsigned int ack_with_err_5 :
+ 1; //[5] This bit retrieves the Peripheral Timeout error from the Acknowledge Error report.
+volatile unsigned int ack_with_err_6 :
+ 1; //[6] This bit retrieves the False Control error from the Acknowledge error report.
+volatile unsigned int ack_with_err_7 :
+ 1; //[7] This bit retrieves the reserved (specific to device) from the Acknowledge error report.
+volatile unsigned int ack_with_err_8 :
+ 1; //[8] This bit retrieves the ECC error, single-bit (detected and corrected) from the Acknowledge error report.
+volatile unsigned int ack_with_err_9 :
+ 1; //[9] This bit retrieves the ECC error, multi-bit (detected, not corrected) from the Acknowledge error report.
+volatile unsigned int ack_with_err_10 :
+ 1; //[10]This bit retrieves the checksum error (long packet only) from the Acknowledge error report.
+volatile unsigned int ack_with_err_11 :
+ 1; //[11] This bit retrieves the not recognized DSI data type from the Acknowledge error report.
+volatile unsigned int ack_with_err_12 :
+ 1; //[12] This bit retrieves the DSI VC ID Invalid from the Acknowledge error report.
+volatile unsigned int ack_with_err_13 :
+ 1; //[13] This bit retrieves the invalid transmission length from the Acknowledge error report.
+volatile unsigned int ack_with_err_14 :
+ 1; //[14] This bit retrieves the reserved (specific to device) from the Acknowledge error report
+volatile unsigned int ack_with_err_15 :
+ 1; //[15] This bit retrieves the DSI protocol violation from the Acknowledge error report.
+volatile unsigned int dphy_errors_0 :
+ 1; //[16] This bit indicates ErrEsc escape entry error from Lane 0.
+volatile unsigned int dphy_errors_1 :
+ 1; //[17] This bit indicates ErrSyncEsc low-power data transmission synchronization error from Lane 0.
+volatile unsigned int dphy_errors_2 :
+ 1; //[18] This bit indicates the ErrControl error from Lane 0.
+volatile unsigned int dphy_errors_3 :
+ 1; //[19] This bit indicates the LP0 contention error ErrContentionLP0 from Lane 0.
+volatile unsigned int dphy_errors_4 :
+ 1; //[20] This bit indicates the LP1 contention error ErrContentionLP1 from Lane 0.
+volatile unsigned int reserved_0 :
+ 11; //[31:21]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ INT_MSK0;// 0x00C4
+
+
+ union _DSIH1P21A_INT_MSK1_tag_t {
+ struct _DSIH1P21A_INT_MSK1_map_t
+ {
+volatile unsigned int to_hs_tx :
+ 1; //[0]
+ /*
+ This bit indicates that the high-speed transmission timeout counter
+ reached the end and contention is detected.
+ */
+volatile unsigned int to_lp_rx :
+ 1; //[1]
+ /*
+ This bit indicates that the low-power reception timeout counter reached
+ the end and contention is detected.
+ */
+volatile unsigned int ecc_single_err :
+ 1; //[2]
+ /*
+ This bit indicates that the ECC single error is detected and corrected in a
+ received packet.
+ */
+volatile unsigned int ecc_multi_err :
+ 1; //[3]
+ /*
+ This bit indicates that the ECC multiple error is detected in a received
+ packet.
+ */
+volatile unsigned int crc_err :
+ 1; //[4]
+ /*
+ This bit indicates that the CRC error is detected in the received packet
+ payload.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3 or
+ DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ */
+volatile unsigned int pkt_size_err :
+ 1; //[5]
+ /*
+ This bit indicates that the packet size error is detected during the packet
+ reception.
+ */
+volatile unsigned int eopt_err :
+ 1; //[6]
+ /*
+ This bit indicates that the EoTp packet is not received at the end of the
+ incoming peripheral transmission
+ */
+volatile unsigned int dpi_pld_wr_err :
+ 1; //[7]
+ /*
+ This bit indicates that during a DPI pixel line storage, the payload FIFO
+ becomes full and the data stored is corrupted.
+ Dependency: DSI_DATAINTERFACE = 2 or DSI_DATAINTERFACE = 3 or
+ DSI_DATAINTERFACE = 4. Otherwise, this bit is reserved.
+ */
+volatile unsigned int gen_cmd_wr_err :
+ 1; //[8]
+ /*
+ This bit indicates that the system tried to write a command through the
+ Generic interface and the FIFO is full. Therefore, the command is not
+ written.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved
+ */
+volatile unsigned int gen_pld_wr_err :
+ 1; //[9]
+ /*
+ This bit indicates that the system tried to write a payload data through the
+ Generic interface and the FIFO is full. Therefore, the payload is not
+ written.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved
+ */
+volatile unsigned int gen_pld_send_err :
+ 1; //[10]
+ /*
+ This bit indicates that during a Generic interface packet build, the payload
+ FIFO becomes empty and corrupt data is sent.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved
+ */
+volatile unsigned int gen_pld_rd_err :
+ 1; //[11]
+ /*
+ This bit indicates that during a DCS read data, the payload FIFO becomes
+ empty and the data sent to the interface is corrupted.
+ Dependency: DSI_GENERIC = 1. Otherwise, this bit is reserved.
+ */
+volatile unsigned int gen_pld_recev_err :
+ 1; //[12]
+ /*
+ This bit indicates that during a generic interface packet read back, the
+ payload FIFO becomes full and the received data is corrupted.
+ Dependency: DSI_GENERIC = 1
+ If DSI_GENERIC = 0, this bit is reserved.
+ */
+volatile unsigned int dbi_cmd_wr_err :
+ 1; //[13]
+ /*
+ This bit indicates that the system tried to write a command through the
+ DBI but the command FIFO is full. Therefore, the command is not written.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ */
+volatile unsigned int dbi_pld_wr_err :
+ 1; //[14]
+ /*
+ This bit indicates that the system tried to write the payload data through
+ the DBI interface and the FIFO is full. Therefore, the command is not
+ written.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ */
+volatile unsigned int dbi_pld_rd_err :
+ 1; //[15]
+ /*
+ This bit indicates that during a DCS read data, the payload FIFO goes
+ empty and the data sent to the interface is corrupted.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ */
+volatile unsigned int dbi_pld_recv_err :
+ 1; //[16]
+ /*
+ This bit indicates that during a DBI read back packet, the payload FIFO
+ becomes full and the received data is corrupted.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ */
+
+volatile unsigned int dbi_ilegal_comm_err :
+ 1; //[17]
+ /*
+ This bit indicates that an attempt to write an illegal command on the DBI
+ interface is made and the core is blocked by transmission.
+ Dependency: DSI_DATAINTERFACE = 1 or DSI_DATAINTERFACE = 3.
+ Otherwise, this bit is reserved.
+ */
+volatile unsigned int reserved_0 :
+ 14; //[31:18]
+ }
+ mBits;
+ volatile unsigned int dValue;
+ }
+ INT_MSK1;// 0x00C8
+}DSIH1P21A_REG_T;
+
+uint32_t mipi_dsih_hal_get_version(dsih_ctrl_t * instance);
+
+void mipi_dsih_hal_power(dsih_ctrl_t * instance, int on);
+
+int mipi_dsih_hal_get_power(dsih_ctrl_t * instance);
+
+void mipi_dsih_hal_tx_escape_division(dsih_ctrl_t * instance, uint8_t tx_escape_division);
+
+void mipi_dsih_hal_dpi_video_vc(dsih_ctrl_t * instance, uint8_t vc);
+
+uint8_t mipi_dsih_hal_dpi_get_video_vc(dsih_ctrl_t * instance);
+
+dsih_error_t mipi_dsih_hal_dpi_color_coding(dsih_ctrl_t * instance, dsih_color_coding_t color_coding);
+dsih_color_coding_t mipi_dsih_hal_dpi_get_color_coding(dsih_ctrl_t * instance);
+uint8_t mipi_dsih_hal_dpi_get_color_depth(dsih_ctrl_t * instance);
+uint8_t mipi_dsih_hal_dpi_get_color_config(dsih_ctrl_t * instance);
+void mipi_dsih_hal_dpi_18_loosely_packet_en(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dpi_color_mode_pol(dsih_ctrl_t * instance, int active_low);
+void mipi_dsih_hal_dpi_shut_down_pol(dsih_ctrl_t * instance, int active_low);
+void mipi_dsih_hal_dpi_hsync_pol(dsih_ctrl_t * instance, int active_low);
+void mipi_dsih_hal_dpi_vsync_pol(dsih_ctrl_t * instance, int active_low);
+void mipi_dsih_hal_dpi_dataen_pol(dsih_ctrl_t * instance, int active_low);
+void mipi_dsih_hal_dpi_frame_ack_en(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dpi_null_packet_en(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dpi_multi_packet_en(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dpi_lp_during_hfp(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dpi_lp_during_hbp(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dpi_lp_during_vactive(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dpi_lp_during_vfp(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dpi_lp_during_vbp(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dpi_lp_during_vsync(dsih_ctrl_t * instance, int enable);
+
+dsih_error_t mipi_dsih_hal_dpi_video_mode_type(dsih_ctrl_t * instance, dsih_video_mode_t type);
+void mipi_dsih_hal_dpi_video_mode_en(dsih_ctrl_t * instance, int enable);
+int mipi_dsih_hal_dpi_is_video_mode(dsih_ctrl_t * instance);
+dsih_error_t mipi_dsih_hal_dpi_null_packet_size(dsih_ctrl_t * instance, uint16_t size);
+dsih_error_t mipi_dsih_hal_dpi_chunks_no(dsih_ctrl_t * instance, uint16_t no);
+dsih_error_t mipi_dsih_hal_dpi_video_packet_size(dsih_ctrl_t * instance, uint16_t size);
+
+void mipi_dsih_hal_tear_effect_ack_en(dsih_ctrl_t * instance, int enable);
+
+void mipi_dsih_hal_cmd_ack_en(dsih_ctrl_t * instance, int enable);
+dsih_error_t mipi_dsih_hal_dcs_wr_tx_type(dsih_ctrl_t * instance, unsigned no_of_param, int lp);
+dsih_error_t mipi_dsih_hal_dcs_rd_tx_type(dsih_ctrl_t * instance, unsigned no_of_param, int lp);
+/*Jessica add to support max rd packet size command*/
+dsih_error_t mipi_dsih_hal_max_rd_packet_size_type(dsih_ctrl_t * instance, int lp);
+dsih_error_t mipi_dsih_hal_gen_wr_tx_type(dsih_ctrl_t * instance, unsigned no_of_param, int lp);
+dsih_error_t mipi_dsih_hal_gen_rd_tx_type(dsih_ctrl_t * instance, unsigned no_of_param, int lp);
+void mipi_dsih_hal_max_rd_size_type(dsih_ctrl_t * instance, int lp);
+void mipi_dsih_hal_gen_cmd_mode_en(dsih_ctrl_t * instance, int enable);
+int mipi_dsih_hal_gen_is_cmd_mode(dsih_ctrl_t * instance);
+
+void mipi_dsih_hal_dpi_hline(dsih_ctrl_t * instance, uint16_t time);
+void mipi_dsih_hal_dpi_hbp(dsih_ctrl_t * instance, uint16_t time);
+void mipi_dsih_hal_dpi_hsa(dsih_ctrl_t * instance, uint16_t time);
+void mipi_dsih_hal_dpi_vactive(dsih_ctrl_t * instance, uint16_t lines);
+void mipi_dsih_hal_dpi_vfp(dsih_ctrl_t * instance, uint16_t lines);
+void mipi_dsih_hal_dpi_vbp(dsih_ctrl_t * instance, uint16_t lines);
+void mipi_dsih_hal_dpi_vsync(dsih_ctrl_t * instance, uint16_t lines);
+
+void mipi_dsih_hal_edpi_max_allowed_size(dsih_ctrl_t * instance, uint16_t size);
+
+dsih_error_t mipi_dsih_hal_gen_packet_header(dsih_ctrl_t * instance, uint8_t vc, uint8_t packet_type, uint8_t ms_byte, uint8_t ls_byte);
+dsih_error_t mipi_dsih_hal_gen_packet_payload(dsih_ctrl_t * instance, uint32_t payload);
+dsih_error_t mipi_dsih_hal_gen_read_payload(dsih_ctrl_t * instance, uint32_t* payload);
+
+void mipi_dsih_hal_timeout_clock_division(dsih_ctrl_t * instance, uint8_t byte_clk_division_factor);
+void mipi_dsih_hal_lp_rx_timeout(dsih_ctrl_t * instance, uint16_t count);
+void mipi_dsih_hal_hs_tx_timeout(dsih_ctrl_t * instance, uint16_t count);
+
+uint32_t mipi_dsih_hal_int_status_0(dsih_ctrl_t * instance, uint32_t mask);
+uint32_t mipi_dsih_hal_int_status_1(dsih_ctrl_t * instance, uint32_t mask);
+void mipi_dsih_hal_int_mask_0(dsih_ctrl_t * instance, uint32_t mask);
+void mipi_dsih_hal_int_mask_1(dsih_ctrl_t * instance, uint32_t mask);
+uint32_t mipi_dsih_hal_int_get_mask_0(dsih_ctrl_t * instance, uint32_t mask);
+uint32_t mipi_dsih_hal_int_get_mask_1(dsih_ctrl_t * instance, uint32_t mask);
+/* DBI command interface */
+void mipi_dsih_hal_dbi_out_color_coding(dsih_ctrl_t * instance, uint8_t color_depth, uint8_t option);
+void mipi_dsih_hal_dbi_in_color_coding(dsih_ctrl_t * instance, uint8_t color_depth, uint8_t option);
+void mipi_dsih_hal_dbi_lut_size(dsih_ctrl_t * instance, uint8_t size);
+void mipi_dsih_hal_dbi_partitioning_en(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_dbi_dcs_vc(dsih_ctrl_t * instance, uint8_t vc);
+
+void mipi_dsih_hal_dbi_cmd_size(dsih_ctrl_t * instance, uint16_t size);
+void mipi_dsih_hal_dbi_max_cmd_size(dsih_ctrl_t * instance, uint16_t size);
+int mipi_dsih_hal_dbi_rd_cmd_busy(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_read_fifo_full(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_read_fifo_empty(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_write_fifo_full(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_write_fifo_empty(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_cmd_fifo_full(dsih_ctrl_t * instance);
+int mipi_dsih_hal_dbi_cmd_fifo_empty(dsih_ctrl_t * instance);
+/* Generic command interface */
+void mipi_dsih_hal_gen_rd_vc(dsih_ctrl_t * instance, uint8_t vc);
+void mipi_dsih_hal_gen_eotp_rx_en(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_gen_eotp_tx_en(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_bta_en(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_gen_ecc_rx_en(dsih_ctrl_t * instance, int enable);
+void mipi_dsih_hal_gen_crc_rx_en(dsih_ctrl_t * instance, int enable);
+int mipi_dsih_hal_gen_rd_cmd_busy(dsih_ctrl_t * instance);
+int mipi_dsih_hal_gen_read_fifo_full(dsih_ctrl_t * instance);
+int mipi_dsih_hal_gen_read_fifo_empty(dsih_ctrl_t * instance);
+int mipi_dsih_hal_gen_write_fifo_full(dsih_ctrl_t * instance);
+int mipi_dsih_hal_gen_write_fifo_empty(dsih_ctrl_t * instance);
+int mipi_dsih_hal_gen_cmd_fifo_full(dsih_ctrl_t * instance);
+int mipi_dsih_hal_gen_cmd_fifo_empty(dsih_ctrl_t * instance);
+
+/* only if DPI */
+dsih_error_t mipi_dsih_phy_hs2lp_config(dsih_ctrl_t * instance, uint8_t no_of_byte_cycles);
+dsih_error_t mipi_dsih_phy_lp2hs_config(dsih_ctrl_t * instance, uint8_t no_of_byte_cycles);
+dsih_error_t mipi_dsih_phy_clk_lp2hs_config(dsih_ctrl_t * instance, uint8_t no_of_byte_cycles);
+dsih_error_t mipi_dsih_phy_clk_hs2lp_config(dsih_ctrl_t * instance, uint8_t no_of_byte_cycles);
+dsih_error_t mipi_dsih_phy_bta_time(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+void mipi_dsih_non_continuous_clock(dsih_ctrl_t * instance, int enable);
+int mipi_dsih_non_continuous_clock_status(dsih_ctrl_t * instance);
+/* PRESP Time outs */
+void mipi_dsih_hal_presp_timeout_low_power_write(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+void mipi_dsih_hal_presp_timeout_low_power_read(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+void mipi_dsih_hal_presp_timeout_high_speed_write(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+void mipi_dsih_hal_presp_timeout_high_speed_read(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+void mipi_dsih_hal_presp_timeout_bta(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles);
+/* bsp abstraction */
+void mipi_dsih_write_word(dsih_ctrl_t * instance, uint32_t reg_address, uint32_t data);
+void mipi_dsih_write_part(dsih_ctrl_t * instance, uint32_t reg_address, uint32_t data, uint8_t shift, uint8_t width);
+uint32_t mipi_dsih_read_word(dsih_ctrl_t * instance, uint32_t reg_address);
+uint32_t mipi_dsih_read_part(dsih_ctrl_t * instance, uint32_t reg_address, uint8_t shift, uint8_t width);
+
+#endif /* MIPI_DSI_API_H_ */
diff --git a/drivers/autotst/mipi_dsih_local.h b/drivers/autotst/mipi_dsih_local.h
new file mode 100644
index 00000000..a2d98944
--- /dev/null
+++ b/drivers/autotst/mipi_dsih_local.h
@@ -0,0 +1,362 @@
+/**
+ * @file mipi_dsih_local.h
+ * @brief instance context structure and enumerator definitions:
+ * errors, events, color coding, video modes and driver state
+ *
+ * Synopsys Inc.
+ * SG DWC PT02
+ */
+/*
+ The Synopsys Software Driver and documentation (hereinafter "Software")
+ is an unsupported proprietary work of Synopsys, Inc. unless otherwise
+ expressly agreed to in writing between Synopsys and you.
+
+ The Software IS NOT an item of Licensed Software or Licensed Product under
+ any End User Software License Agreement or Agreement for Licensed Product
+ with Synopsys or any supplement thereto. Permission is hereby granted,
+ free of charge, to any person obtaining a copy of this software annotated
+ with this license and the Software, to deal in the Software without
+ restriction, including without limitation the rights to use, copy, modify,
+ merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so, subject
+ to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+ */
+
+#ifndef MIPI_DSIH_LOCAL_H_
+#define MIPI_DSIH_LOCAL_H_
+
+//#include <stdint.h>
+#include <linux/kernel.h>
+
+
+#define FB_DSIH_VERSION_1P21A
+
+#define SPRD_MIPI_DPHY_GEN2
+
+//typedef unsigned char uint8_t;
+//typedef unsigned short uint16_t;
+//typedef unsigned int uint32_t;
+
+#define DSIH_PIXEL_TOLERANCE (2)
+#define DSIH_FIFO_ACTIVE_WAIT (5000) /* no of tries to access the fifo */
+#define DSIH_PHY_ACTIVE_WAIT (50000)
+#define ONE_MS_ACTIVE_WAIT (50000) /* 50MHz processor */
+#define DEFAULT_BYTE_CLOCK (432000) /* a value to start PHY PLL - random */
+#define MAX_NULL_SIZE (1023)
+#define FIFO_DEPTH (1096)
+#define WORD_LENGTH (4) /* bytes (32bit registers) */
+
+/** Define D-PHY type */
+
+#ifdef SPRD_MIPI_DPHY_GEN1
+/** DWC_MIPI_DPHY_BIDIR_TSMC40LP 4 Lanes Gen 1 1GHz */
+#define DWC_MIPI_DPHY_BIDIR_TSMC40LP
+#endif
+#ifdef SPRD_MIPI_DPHY_GEN2
+/** DWC_MIPI_DPHY_BIDIR_TSMC40LP / GF28LP 4 Lanes Gen 2 1.5GHz */
+#define GEN_2
+#endif
+/** 4 Lanes Gen 2 1.5GHz testchips */
+//#define TESTCHIP
+/** TQL 2 Lane test chip */
+/* #define DPHY2Btql */
+
+/**
+ * Errors generated by the DSI Host controller driver
+ */
+typedef enum
+{
+ OK = 0,
+ ERR_DSI_COLOR_CODING,
+ ERR_DSI_OUT_OF_BOUND,
+ ERR_DSI_OVERFLOW,
+ ERR_DSI_INVALID_INSTANCE,
+ ERR_DSI_INVALID_IO,
+ ERR_DSI_CORE_INCOMPATIBLE,
+ ERR_DSI_VIDEO_MODE,
+ ERR_DSI_INVALID_COMMAND,
+ ERR_DSI_INVALID_EVENT,
+ ERR_DSI_INVALID_HANDLE,
+ ERR_DSI_PHY_POWERUP,
+ ERR_DSI_PHY_INVALID,
+ ERR_DSI_PHY_FREQ_OUT_OF_BOUND,
+//#ifdef GEN_2
+ ERR_DSI_PHY_PLL_NOT_LOCKED,
+//#endif
+ ERR_DSI_TIMEOUT
+}
+dsih_error_t;
+/**
+ * Video stream type
+ */
+typedef enum
+{
+ VIDEO_NON_BURST_WITH_SYNC_PULSES = 0,
+ VIDEO_NON_BURST_WITH_SYNC_EVENTS,
+ VIDEO_BURST_WITH_SYNC_PULSES
+}
+dsih_video_mode_t;
+/**
+ * Color coding type (depth and pixel configuration)
+ */
+typedef enum
+{
+ COLOR_CODE_16BIT_CONFIG1 = 0,
+ COLOR_CODE_16BIT_CONFIG2 = 1,
+ COLOR_CODE_16BIT_CONFIG3 = 2,
+ COLOR_CODE_18BIT_CONFIG1 = 3,
+ COLOR_CODE_18BIT_CONFIG2 = 4,
+ COLOR_CODE_24BIT = 5,
+ COLOR_CODE_20BIT_YCC422_LOOSELY = 6,
+ COLOR_CODE_24BIT_YCC422 = 7,
+ COLOR_CODE_16BIT_YCC422 = 8,
+ COLOR_CODE_30BIT = 9,
+ COLOR_CODE_36BIT = 10,
+ COLOR_CODE_12BIT_YCC420 = 11,
+ COLOR_CODE_MAX
+}
+dsih_color_coding_t;
+/**
+ * Events generated by the DSI Host controller
+ */
+typedef enum
+{
+ ACK_SOT_ERR = 0,
+ ACK_SOT_SYNC,
+ ACK_EOT_SYNC,
+ ACK_ESCAPE_CMD_ERR,
+ ACK_LP_TX_SYNC_ERR,
+ ACK_HS_RX_TIMEOUT_ERR,
+ ACK_FALSE_CONTROL_ERR,
+ ACK_RSVD_DEVICE_ERR_7,
+ ACK_ECC_SINGLE_BIT_ERR,
+ ACK_ECC_MULTI_BIT_ERR,
+ ACK_CHECKSUM_ERR,
+ ACK_DSI_TYPE_NOT_RECOGNIZED_ERR,
+ ACK_VC_ID_INVALID_ERR,
+ ACK_INVALID_TX_LENGTH_ERR,
+ ACK_RSVD_DEVICE_ERR_14,
+ ACK_DSI_PROTOCOL_ERR,
+
+ DPHY_ESC_ENTRY_ERR,
+ DPHY_SYNC_ESC_LP_ERR,
+ DPHY_CONTROL_LANE0_ERR,
+ DPHY_CONTENTION_LP0_ERR,
+ DPHY_CONTENTION_LP1_ERR,
+ /* start of st1 */
+ HS_CONTENTION,
+ LP_CONTENTION,
+ RX_ECC_SINGLE_ERR,
+ RX_ECC_MULTI_ERR,
+ RX_CRC_ERR,
+ RX_PKT_SIZE_ERR,
+ RX_EOTP_ERR,
+ DPI_PLD_FIFO_FULL_ERR,
+ GEN_TX_CMD_FIFO_FULL_ERR,
+ GEN_TX_PLD_FIFO_FULL_ERR,
+ GEN_TX_PLD_FIFO_EMPTY_ERR,
+ GEN_RX_PLD_FIFO_EMPTY_ERR,
+ GEN_RX_PLD_FIFO_FULL_ERR,
+
+ DBI_TX_CMD_FIFO_FULL_ERR,
+ DBI_TX_PLD_FIFO_FULL_ERR,
+ DBI_RX_PLD_FIFO_EMPTY_ERR,
+ DBI_RX_PLD_FIFO_FULL_ERR,
+ DBI_ILLEGAL_CMD_ERR,
+ DSI_MAX_EVENT
+}
+dsih_event_t;
+/**
+ * DSI Host state machine states
+ * Holds the mapping of D-PHY to the OS, logging I/O, and hardware access layer.
+ */
+typedef enum
+{
+ NOT_INITIALIZED = 0,
+ INITIALIZED,
+ ON,
+ OFF
+}
+dsih_state_t;
+
+/**
+ * MIPI D-PHY
+ * Holds the mapping of API to the OS, logging I/O, and hardware access layer
+ * and HW module information.
+ */
+typedef struct dphy_t
+{
+ /** Physical base address of PHY module - REQUIRED */
+ uint32_t address;
+ /** Reference frequency provided to PHY module [KHz] - REQUIRED */
+ uint32_t reference_freq;
+#ifdef CONFIG_FB_DYNAMIC_FREQ_SCALING
+ /** mark if D-PHY should keep work or not */
+ uint32_t phy_keep_work;
+#endif
+ /** D-PHY driver state - used internally by driver */
+ dsih_state_t status;
+ /** Function handle of any board function that needs to be called
+ * in order to set up the environment for the D-PHY before it is
+ * configured. */
+ void (*bsp_pre_config)(struct dphy_t *instance, void* param);
+ /** Register read access function handle - REQUIRED */
+ uint32_t (*core_read_function)(uint32_t addr, uint32_t offset);
+ /** Register write access function handle - REQUIRED */
+ void (*core_write_function)(uint32_t addr, uint32_t offset, uint32_t data);
+ /** Log errors function handle */
+ void (*log_error)(const char * string);
+ /** Log information function handle */
+ void (*log_info)(const char *fmt, ...);
+}
+dphy_t;
+
+/**
+ * MIPI DSI Host Controller
+ * Holds important information for the functioning of the DSI Host Controller API
+ * Holds the mapping of API to the OS, logging I/O, and hardware access layer.
+ * It also holds important information set by the user about the HW considerations
+ * and internal state variables.
+ */
+typedef struct dsih_ctrl_t
+{
+ /** Physical base address of controller - REQUIRED */
+ uint32_t address;
+ /** D-PHY instance associated with the DSI host controller - REQUIRED */
+ dphy_t phy_instance;
+ /** Number of lanes physically connected to controller - REQUIRED */
+ uint8_t max_lanes;
+ /** Maximum number of byte clock cycles needed by the PHY to perform
+ * the Bus Turn Around operation - REQUIRED */
+ uint16_t max_bta_cycles;
+ /** Describe the color mode pin (dpicolorm) whether it is active high or low - REQUIRED */
+ int color_mode_polarity;
+ /** Describe the shut down pin (dpishutdn) whether it is active high or low - REQUIRED */
+ int shut_down_polarity;
+ /** initialised or not */
+ dsih_state_t status;
+ /** Register read access function handle - REQUIRED */
+ uint32_t (*core_read_function)(uint32_t addr, uint32_t offset);
+ /** Register write access function handle - REQUIRED */
+ void (*core_write_function)(uint32_t addr, uint32_t offset, uint32_t data);
+ /** Log errors function handle */
+ void (*log_error)(const char * string);
+ /** Log information function handle */
+ void (*log_info)(const char *fmt, ...);
+ /** Event registry holds handlers of the callbacks of registered events */
+ void (*event_registry[DSI_MAX_EVENT])(struct dsih_ctrl_t *instance, void *handler);
+}
+dsih_ctrl_t;
+/**
+ * Video configurations
+ * Holds information about the video stream to be sent through the DPI interface.
+ */
+typedef struct
+{
+ /** Number of lanes used to send current video */
+ uint8_t no_of_lanes;
+ /** Virtual channel number to send this video stream */
+ uint8_t virtual_channel;
+ /** Video mode, whether burst with sync pulses, or packets with either sync pulses or events */
+ dsih_video_mode_t video_mode;
+ /** Maximum number of byte clock cycles needed by the PHY to transition
+ * the data lanes from high speed to low power - REQUIRED */
+ uint8_t max_hs_to_lp_cycles;
+ /** Maximum number of byte clock cycles needed by the PHY to transition
+ * the data lanes from low power to high speed - REQUIRED */
+ uint8_t max_lp_to_hs_cycles;
+ /** Maximum number of byte clock cycles needed by the PHY to transition
+ * the clock lane from high speed to low power - REQUIRED */
+ uint8_t max_clk_hs_to_lp_cycles;
+ /** Maximum number of byte clock cycles needed by the PHY to transition
+ * the clock lane from low power to high speed - REQUIRED */
+ uint8_t max_clk_lp_to_hs_cycles;
+ /** Enable non coninuous clock for energy saving
+ * - Clock lane will go to LS while not transmitting video */
+ int non_continuous_clock;
+ /** Enable receiving of ack packets */
+ int receive_ack_packets;
+ /** Byte (lane) clock [KHz] */
+ uint32_t byte_clock;
+ /** Pixel (DPI) Clock [KHz]*/
+ uint32_t pixel_clock;
+ /** Colour coding - BPP and Pixel configuration */
+ dsih_color_coding_t color_coding;
+ /** Is 18-bit loosely packets (valid only when BPP == 18) */
+ int is_18_loosely;
+ /** Data enable signal (dpidaten) whether it is active high or low */
+ int data_en_polarity;
+ /** Horizontal synchronisation signal (dpihsync) whether it is active high or low */
+ int h_polarity;
+ /** Horizontal resolution or Active Pixels */
+ uint16_t h_active_pixels; /* hadr */
+ /** Horizontal Sync Pixels - min 4 for best performance */
+ uint16_t h_sync_pixels;
+ /** Horizontal back porch pixels */
+ uint16_t h_back_porch_pixels; /* hbp */
+ /** Total Horizontal pixels */
+ uint16_t h_total_pixels; /* h_total */
+ /** Vertical synchronisation signal (dpivsync) whether it is active high or low */
+ int v_polarity;
+ /** Vertical active lines (resolution) */
+ uint16_t v_active_lines; /* vadr */
+ /** Vertical sync lines */
+ uint16_t v_sync_lines;
+ /** Vertical back porch lines */
+ uint16_t v_back_porch_lines; /* vbp */
+ /** Total no of vertical lines */
+ uint16_t v_total_lines; /* v_total */
+}
+dsih_dpi_video_t;
+
+typedef struct
+{
+ /** virtual channel */
+ uint8_t virtual_channel;
+ /** Commands to be sent in high speed or low power */
+ int lp;
+ /** Colour coding - BPP and Pixel configuration */
+ dsih_color_coding_t color_coding;
+ /** Top horizontal pixel position in the display */
+ uint16_t h_start;
+ /** Horizontal resolution or Active Pixels */
+ uint16_t h_active_pixels; /* hadr */
+ /** Left most line position in the display */
+ uint16_t v_start;
+ /** Vertical active lines (resolution) */
+ uint16_t v_active_lines; /* vadr */
+ /** Whether Tearing effect should be requested */
+ int te;
+ /** packet size of write memory command -
+ * 0 is default (optimum usage of RAM) */
+ uint16_t packet_size;
+}
+dsih_cmd_mode_video_t;
+/**
+ * Register configurations
+ */
+typedef struct
+{
+ /** Register offset */
+ uint32_t addr;
+ /** Register data [in or out] */
+ uint32_t data;
+}
+register_config_t;
+
+#endif /* MIPI_DSIH_LOCAL_H_ */
diff --git a/drivers/autotst/pinmap_gpio.h b/drivers/autotst/pinmap_gpio.h
new file mode 100644
index 00000000..7f761582
--- /dev/null
+++ b/drivers/autotst/pinmap_gpio.h
@@ -0,0 +1,116 @@
+
+#ifndef _PINMAP_GPIO_20130207_H__
+#define _PINMAP_GPIO_20130207_H__
+
+#include <soc/sprd/pinmap.h>
+#include <soc/sprd/adi.h>
+#include <linux/regulator/consumer.h>
+#include <soc/sprd/regulator.h>
+#include <soc/sprd/sci_glb_regs.h>
+
+//LCD
+#define gpio101 REG_PIN_LCD_CSN1
+#define gpio102 REG_PIN_LCD_CSN0
+#define gpio103 REG_PIN_LCD_RSTN
+#define gpio105 REG_PIN_LCD_FMARK
+
+//CAM
+#define gpio173 REG_PIN_CCIRMCLK
+#define gpio186 REG_PIN_CCIRRST
+#define gpio187 REG_PIN_CCIRPD1
+#define gpio188 REG_PIN_CCIRPD0
+
+#define gpio189 REG_PIN_SCL0
+#define gpio190 REG_PIN_SDA0
+#define gpio236 REG_PIN_TRACEDAT4
+
+//CTP&KEYPAD
+#define gpio73 REG_PIN_SCL1
+#define gpio74 REG_PIN_SDA1
+#define gpio81 REG_PIN_SIMCLK2
+#define gpio82 REG_PIN_SIMDA2
+#define gpio191 REG_PIN_KEYOUT0
+#define gpio192 REG_PIN_KEYOUT1
+#define gpio193 REG_PIN_KEYOUT2
+#define gpio199 REG_PIN_KEYIN0
+#define gpio200 REG_PIN_KEYIN1
+#define gpio201 REG_PIN_KEYIN2
+
+//SIM
+#define gpio75 REG_PIN_SIMCLK0
+#define gpio76 REG_PIN_SIMDA0
+#define gpio77 REG_PIN_SIMRST0
+#define gpio78 REG_PIN_SIMCLK1
+#define gpio79 REG_PIN_SIMDA1
+#define gpio80 REG_PIN_SIMRST1
+
+//TCARD
+#define gpio94 REG_PIN_SD0_CLK0
+#define gpio95 REG_PIN_SD0_CLK1
+#define gpio96 REG_PIN_SD0_CMD
+#define gpio97 REG_PIN_SD0_D0
+#define gpio98 REG_PIN_SD0_D1
+#define gpio99 REG_PIN_SD0_D2
+#define gpio100 REG_PIN_SD0_D3
+#define gpio71 REG_PIN_EXTINT0
+
+//
+
+typedef struct {
+ int num;
+ uint32_t reg;
+} pinmap_gpio_t;
+
+pinmap_gpio_t pinmap_gpio[] = {
+//LCD
+{101, gpio101,},
+{102, gpio102,},
+{103, gpio103,},
+{105, gpio105,},
+
+//CAM
+{173, gpio173,},
+{186, gpio186,},
+{187, gpio187,},
+{188, gpio188,},
+{189, gpio189,},
+{190, gpio190,},
+{236, gpio236,},
+
+//CTP
+{73, gpio73,},
+{74, gpio74,},
+
+{81, gpio81,},
+{82, gpio82,},
+{191, gpio191,},
+{192, gpio192,},
+{193, gpio193,},
+{199, gpio199,},
+{200, gpio200,},
+{201, gpio201,},
+
+//SIM
+{75, gpio75,},
+{76, gpio76,},
+{77, gpio77,},
+{78, gpio78,},
+{79, gpio79,},
+{80, gpio80,},
+
+//TCARD
+{94, gpio94,},
+{95, gpio95,},
+{96, gpio96,},
+{97, gpio97,},
+{98, gpio98,},
+{99, gpio99,},
+{100, gpio100,},
+{71, gpio71,},
+};
+struct regulator *autotest_regulator = NULL;
+
+#define ANA_REG_BIC(_r, _b) sci_adi_write(_r, 0, _b)
+
+
+#endif // _PINMAP_GPIO_20130207_H__