lcd: lut_dma driver support [2/2]

PD#SWPL-124798

Problem:
lut flush dma is better than cpu

Solution:
add lut dma driver

Verify:
ay301

Change-Id: Id8d9faf309767f6a7f6ac665081f1d27d34108ad
Signed-off-by: Jie Dai <jie.dai@amlogic.com>
This commit is contained in:
Jie Dai
2023-06-16 14:20:48 +08:00
committed by gerrit autosubmit
parent cf648bb6aa
commit 77713835a4
35 changed files with 509 additions and 79 deletions
@@ -42,7 +42,8 @@
pinctrl-9 = <&ST5461D18_2_pins>;
pinctrl-10 = <&ST5461D18_2_off_pins>;
pinctrl_version = <2>; /* for uboot */
memory-region = <&lcd_tcon_reserved>;
memory-region = <&lcd_tcon_reserved &lcd_cma_reserved>;
memory-region-names = "lcd_tcon_reserved","lcd_cma_reserved";
/* power type:(0=cpu_gpio, 2=signal, 3=extern, 0xff=ending) */
/* power index:(gpios_index, or extern_index, 0xff=invalid) */
@@ -42,7 +42,8 @@
pinctrl-9 = <&ST5461D18_2_pins>;
pinctrl-10 = <&ST5461D18_2_off_pins>;
pinctrl_version = <2>; /* for uboot */
memory-region = <&lcd_tcon_reserved>;
memory-region = <&lcd_tcon_reserved &lcd_cma_reserved>;
memory-region-names = "lcd_tcon_reserved", "lcd_cma_reserved";
/* power type:(0=cpu_gpio, 2=signal, 3=extern, 0xff=ending) */
/* power index:(gpios_index, or extern_index, 0xff=invalid) */
@@ -42,7 +42,8 @@
pinctrl-9 = <&ST5461D18_2_pins>;
pinctrl-10 = <&ST5461D18_2_off_pins>;
pinctrl_version = <2>; /* for uboot */
memory-region = <&lcd_tcon_reserved>;
memory-region = <&lcd_tcon_reserved &lcd_cma_reserved>;
memory-region-names = "lcd_tcon_reserved", "lcd_cma_reserved";
/* power type:(0=cpu_gpio, 2=signal, 3=extern, 0xff=ending) */
/* power index:(gpios_index, or extern_index, 0xff=invalid) */
@@ -42,7 +42,8 @@
pinctrl-9 = <&ST5461D18_2_pins>;
pinctrl-10 = <&ST5461D18_2_off_pins>;
pinctrl_version = <2>; /* for uboot */
memory-region = <&lcd_tcon_reserved>;
memory-region = <&lcd_tcon_reserved &lcd_cma_reserved>;
memory-region-names = "lcd_tcon_reserved", "lcd_cma_reserved";
/* power type:(0=cpu_gpio, 2=signal, 3=extern, 0xff=ending) */
/* power index:(gpios_index, or extern_index, 0xff=invalid) */
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -82,6 +82,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -82,6 +82,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -96,6 +96,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -96,6 +96,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -87,6 +87,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -82,6 +82,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
@@ -82,6 +82,14 @@
no-map;
};
lcd_cma_reserved:linux,lcd-cma {
compatible = "shared-dma-pool";
reusable;
/* 512k for lcd dma data */
size = <0x0 0x00080000>;
reg = <0x0 0x3ea80000 0x0 0x00080000>;
};
ion_cma_reserved:linux,ion-dev {
compatible = "shared-dma-pool";
reusable;
+1 -1
View File
@@ -12636,7 +12636,7 @@ static int aml_vecm_probe(struct platform_device *pdev)
spin_lock_init(&vpp_lcd_gamma_lock);
mutex_init(&vpp_lut3d_lock);
#ifdef CONFIG_AMLOGIC_LCD
ret = aml_lcd_notifier_register(&aml_lcd_gamma_nb);
ret = aml_lcd_atomic_notifier_register(&aml_lcd_gamma_nb);
if (ret)
pr_info("register aml_lcd_gamma_notifier failed\n");
+46
View File
@@ -15,6 +15,10 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_reserved_mem.h>
#include <linux/cma.h>
#include <linux/dma-map-ops.h>
#include <linux/dma-mapping.h>
#include <linux/reset.h>
#include <linux/clk.h>
#include <linux/amlogic/media/vout/lcd/aml_lcd.h>
@@ -160,6 +164,48 @@ char *lcd_mode_mode_to_str(int mode)
return lcd_mode_table[mode];
}
int __of_reserved_mem_device_init_by_name(struct device *dev,
struct device_node *np,
const char *name)
{
int idx = of_property_match_string(np, "memory-region-names", name);
return of_reserved_mem_device_init_by_idx(dev, np, idx);
}
void lcd_cma_pool_init(struct aml_lcd_drv_s *pdrv, struct platform_device *pdev)
{
struct device *dev;
int ret;
char rsv_mem_name[64];
if (!pdev || !pdrv)
return;
if (pdrv->index)
sprintf(rsv_mem_name, "lcd%d_cma_reserved", pdrv->index);
dev = &pdrv->pdev->dev;
ret = __of_reserved_mem_device_init_by_name(dev, dev->of_node, rsv_mem_name);
if (ret == 0) {
pdrv->lcd_cma_ready = 1;
//dma_set_coherent_mask(dev, 0xffffffff);//4G
} else {
pdrv->lcd_cma_ready = -1;
LCDPR("warning:lcd cma init failed\n");
}
}
void *lcd_alloc_dma_buffer(struct aml_lcd_drv_s *pdrv, unsigned int size, dma_addr_t *paddr)
{
if (!pdrv || !pdrv->pdev)
return NULL;
if (pdrv->lcd_cma_ready == 0)
lcd_cma_pool_init(pdrv, pdrv->pdev);
return dma_alloc_coherent(&pdrv->pdev->dev, size, paddr, GFP_KERNEL);
}
u8 *lcd_vmap(ulong addr, u32 size)
{
u8 *vaddr = NULL;
+4 -1
View File
@@ -43,7 +43,8 @@
/* 20230815: add full-link-training and EDID-timing for eDP */
/* 20230816: optimize clk accuracy*/
/* 20230821: update clk ss support*/
#define LCD_DRV_VERSION "20230821"
/* 20230823: add dma driver for tcon lut*/
#define LCD_DRV_VERSION "20230823"
extern struct mutex lcd_vout_mutex;
extern spinlock_t lcd_reg_spinlock;
@@ -67,6 +68,8 @@ int lcd_type_str_to_type(const char *str);
char *lcd_type_type_to_str(int type);
unsigned char lcd_mode_str_to_mode(const char *str);
char *lcd_mode_mode_to_str(int mode);
void *lcd_alloc_dma_buffer(struct aml_lcd_drv_s *pdrv,
unsigned int size, dma_addr_t *paddr);
u8 *lcd_vmap(ulong addr, u32 size);
void lcd_unmap_phyaddr(u8 *vaddr);
void lcd_debug_parse_param(char *buf_orig, char **parm);
+88 -22
View File
@@ -1009,6 +1009,7 @@ int lcd_tcon_enable(struct aml_lcd_drv_s *pdrv)
void lcd_tcon_disable(struct aml_lcd_drv_s *pdrv)
{
struct lcd_tcon_fw_s *tcon_fw = aml_lcd_tcon_get_fw();
struct lcd_tcon_data_block_header_s *block_header;
unsigned int i;
int ret;
@@ -1028,8 +1029,21 @@ void lcd_tcon_disable(struct aml_lcd_drv_s *pdrv)
tcon_mm_table.block_bit_flag = 0;
lcd_tcon_data_multi_remvoe(&tcon_mm_table);
for (i = 0; i < tcon_mm_table.block_cnt; i++) {
kfree(tcon_mm_table.data_mem_vaddr[i]);
tcon_mm_table.data_mem_vaddr[i] = NULL;
if (!tcon_mm_table.data_mem_vaddr[i])
continue;
block_header = (struct lcd_tcon_data_block_header_s *)
tcon_mm_table.data_mem_vaddr[i];
if (!is_block_type_basic_init(block_header->block_type) &&
is_block_ctrl_dma(block_header->block_ctrl)) {
dma_free_coherent(&pdrv->pdev->dev,
block_header->block_size,
tcon_mm_table.data_mem_vaddr[i],
tcon_mm_table.data_mem_paddr[i]);
} else {
kfree(tcon_mm_table.data_mem_vaddr[i]);
tcon_mm_table.data_mem_vaddr[i] = NULL;
}
}
} else {
lcd_tcon_data_multi_reset(&tcon_mm_table);
@@ -1066,6 +1080,7 @@ static int lcd_tcon_data_multi_match_policy(struct aml_lcd_drv_s *pdrv, unsigned
switch (data_list->ctrl_method) {
case LCD_TCON_DATA_CTRL_MULTI_VFREQ_DIRECT:
case LCD_TCON_DATA_CTRL_MULTI_VFREQ_NOTIFY:
if (frame_rate < data_list->min || frame_rate > data_list->max)
goto lcd_tcon_data_multi_match_policy_exit;
if (!data_multi)
@@ -1154,7 +1169,7 @@ static int lcd_tcon_data_multi_match_init(struct aml_lcd_drv_s *pdrv,
if (!ctrl_part)
return -1;
if (ctrl_part->ctrl_data_flag != LCD_TCON_DATA_CTRL_FLAG_MULTI)
if (!(ctrl_part->ctrl_data_flag & LCD_TCON_DATA_CTRL_FLAG_MULTI))
return -1;
data_byte = ctrl_part->data_byte_width;
@@ -1266,7 +1281,7 @@ static int lcd_tcon_data_multi_match_check(struct aml_lcd_drv_s *pdrv,
if (!ctrl_part)
return -1;
if (ctrl_part->ctrl_data_flag != LCD_TCON_DATA_CTRL_FLAG_MULTI)
if (!(ctrl_part->ctrl_data_flag & LCD_TCON_DATA_CTRL_FLAG_MULTI))
return -1;
data_byte = ctrl_part->data_byte_width;
@@ -1383,8 +1398,9 @@ static int lcd_tcon_data_multi_list_init(struct aml_lcd_drv_s *pdrv,
struct lcd_tcon_data_block_header_s *block_header;
struct lcd_tcon_data_block_ext_header_s *ext_header;
struct lcd_tcon_data_part_ctrl_s *ctrl_part;
unsigned char *data_buf, *p, part_type;
unsigned char *data_buf, *p, *part_start, part_type;
unsigned int size, data_offset, offset, i;
unsigned int *part_pos, ext_header_size;
unsigned short part_cnt;
int ret;
@@ -1393,11 +1409,14 @@ static int lcd_tcon_data_multi_list_init(struct aml_lcd_drv_s *pdrv,
p = data_buf + LCD_TCON_DATA_BLOCK_HEADER_SIZE;
ext_header = (struct lcd_tcon_data_block_ext_header_s *)p;
part_cnt = ext_header->part_cnt;
ext_header_size = block_header->ext_header_size;
data_offset = LCD_TCON_DATA_BLOCK_HEADER_SIZE + block_header->ext_header_size;
part_pos = (unsigned int *)(p + LCD_TCON_DATA_BLOCK_EXT_HEADER_SIZE_PRE);
part_start = data_buf + LCD_TCON_DATA_BLOCK_HEADER_SIZE + ext_header_size;
size = 0;
for (i = 0; i < part_cnt; i++) {
p = data_buf + data_offset;
p = part_start + part_pos[i];
data_offset = part_pos[i];
part_type = p[LCD_TCON_DATA_PART_NAME_SIZE + 3];
switch (part_type) {
@@ -1405,8 +1424,10 @@ static int lcd_tcon_data_multi_list_init(struct aml_lcd_drv_s *pdrv,
offset = LCD_TCON_DATA_PART_CTRL_SIZE_PRE;
ctrl_part = (struct lcd_tcon_data_part_ctrl_s *)p;
size = offset + (ctrl_part->data_cnt * ctrl_part->data_byte_width);
if (ctrl_part->ctrl_data_flag != LCD_TCON_DATA_CTRL_FLAG_MULTI)
if (!(ctrl_part->ctrl_data_flag & LCD_TCON_DATA_CTRL_FLAG_MULTI))
break;
if ((size + data_offset) > block_header->block_size)
return -1;
ret = lcd_tcon_data_multi_match_init(pdrv, data_list,
ctrl_part, (p + offset));
if (ret == 0)
@@ -1417,7 +1438,6 @@ static int lcd_tcon_data_multi_list_init(struct aml_lcd_drv_s *pdrv,
default:
return -1;
}
data_offset += size;
}
return -1;
@@ -1456,7 +1476,7 @@ int lcd_tcon_data_multi_match_find(struct aml_lcd_drv_s *pdrv, unsigned char *da
ctrl_part = (struct lcd_tcon_data_part_ctrl_s *)p;
size = offset + (ctrl_part->data_cnt *
ctrl_part->data_byte_width);
if (ctrl_part->ctrl_data_flag != LCD_TCON_DATA_CTRL_FLAG_MULTI)
if (!(ctrl_part->ctrl_data_flag & LCD_TCON_DATA_CTRL_FLAG_MULTI))
break;
ret = lcd_tcon_data_multi_match_check(pdrv, frame_rate,
ctrl_part, (p + offset));
@@ -1562,7 +1582,7 @@ static int lcd_tcon_data_multi_update(struct aml_lcd_drv_s *pdrv,
for (i = 0; i < mm_table->data_multi_cnt; i++) {
data_multi = &mm_table->data_multi[i];
/* bypass LCD_TCON_DATA_BLOCK_TYPE_BASIC_INIT for multi lut switch */
if (data_multi->block_type == LCD_TCON_DATA_BLOCK_TYPE_BASIC_INIT)
if (is_block_type_basic_init(data_multi->block_type))
continue;
/* bypass_flag for debug */
if (data_multi->bypass_flag)
@@ -1686,7 +1706,7 @@ static int lcd_tcon_data_multi_set(struct aml_lcd_drv_s *pdrv,
data_multi = &mm_table->data_multi[i];
/* bypass LCD_TCON_DATA_BLOCK_TYPE_BASIC_INIT for multi lut switch */
/* bypass LCD_TCON_DATA_BLOCK_TYPE_ACC_LUT for soc gamma update */
if (data_multi->block_type == LCD_TCON_DATA_BLOCK_TYPE_BASIC_INIT)
if (is_block_type_basic_init(data_multi->block_type))
continue;
/* bypass_flag for debug */
if (data_multi->bypass_flag)
@@ -1696,7 +1716,9 @@ static int lcd_tcon_data_multi_set(struct aml_lcd_drv_s *pdrv,
lut_hit++;
ret = lcd_tcon_data_common_parse_set(pdrv,
data_multi->list_update->block_vaddr, 0);
data_multi->list_update->block_vaddr,
data_multi->list_update->block_paddr, 0);
if (ret) //list update failed
continue;
data_multi->list_cur = data_multi->list_update;
@@ -1726,6 +1748,13 @@ void lcd_tcon_vsync_isr(struct aml_lcd_drv_s *pdrv)
if (lcd_tcon_conf->tcon_is_busy)
return;
lcd_tcon_lut_dma_disable(pdrv);
if (lcd_tcon_get_dma_ref() > 0) {
if (lcd_debug_print_flag & LCD_DBG_PR_ISR)
LCDPR("%s, dma update\n", __func__);
lcd_tcon_dma_update(pdrv);
}
if (tcon_mm_table.version) {
if (tcon_mm_table.multi_lut_update) {
spin_lock_irqsave(&tcon_local_cfg.multi_list_lock, flags);
@@ -2008,7 +2037,9 @@ static int lcd_tcon_data_multi_add(struct aml_lcd_drv_s *pdrv,
data_list = kzalloc(sizeof(*data_list), GFP_KERNEL);
if (!data_list)
return -1;
spin_lock_irqsave(&tcon_local_cfg.multi_list_lock, flags);
data_list->block_vaddr = mm_table->data_mem_vaddr[index];
data_list->block_paddr = mm_table->data_mem_paddr[index];
data_list->next = NULL;
data_list->id = index;
data_list->block_name = block_header->name;
@@ -2020,7 +2051,6 @@ static int lcd_tcon_data_multi_add(struct aml_lcd_drv_s *pdrv,
}
}
spin_lock_irqsave(&tcon_local_cfg.multi_list_lock, flags);
if (!data_multi) { /* create new list */
data_multi = &mm_table->data_multi[mm_table->data_multi_cnt];
mm_table->data_multi_cnt++;
@@ -2180,7 +2210,7 @@ int lcd_tcon_data_load(struct aml_lcd_drv_s *pdrv, unsigned char *data_buf, int
return -1;
}
if (block_header->block_type != LCD_TCON_DATA_BLOCK_TYPE_BASIC_INIT) {
if (!is_block_type_basic_init(block_header->block_type)) {
tcon_mm_table.valid_flag |= block_header->block_flag;
if (block_header->block_flag == LCD_TCON_DATA_VALID_DEMURA)
tcon_mm_table.demura_cnt++;
@@ -2225,7 +2255,8 @@ int lcd_tcon_data_load(struct aml_lcd_drv_s *pdrv, unsigned char *data_buf, int
tcon_mm_table.data_size[index] = block_header->block_size;
/* add data multi list */
if (block_header->block_ctrl & LCD_TCON_DATA_CTRL_FLAG_MULTI)
if (!is_block_type_basic_init(block_header->block_type) &&
is_block_ctrl_multi(block_header->block_ctrl))
lcd_tcon_data_multi_add(pdrv, &tcon_mm_table, block_header, index);
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL) {
@@ -2333,8 +2364,16 @@ int lcd_tcon_bin_load(struct aml_lcd_drv_s *pdrv)
goto lcd_tcon_bin_load_next;
}
tcon_mm_table.data_mem_vaddr[i] =
kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
if (!is_block_type_basic_init(block_header.block_type) &&
is_block_ctrl_dma(block_header.block_ctrl)) {
tcon_mm_table.data_mem_vaddr[i] =
lcd_alloc_dma_buffer(pdrv, size,
tcon_mm_table.data_mem_paddr[i]);
} else {
tcon_mm_table.data_mem_vaddr[i] =
kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
tcon_mm_table.data_mem_paddr[i] = 0;
}
if (!tcon_mm_table.data_mem_vaddr[i]) {
LCDERR("%s: Not enough memory\n", __func__);
goto lcd_tcon_bin_load_next;
@@ -2355,8 +2394,16 @@ int lcd_tcon_bin_load(struct aml_lcd_drv_s *pdrv)
}
ret = lcd_tcon_data_load(pdrv, tcon_mm_table.data_mem_vaddr[i], i);
if (ret) {
kfree(tcon_mm_table.data_mem_vaddr[i]);
tcon_mm_table.data_mem_vaddr[i] = NULL;
if (!is_block_type_basic_init(block_header.block_type) &&
is_block_ctrl_dma(block_header.block_ctrl)) {
dma_free_coherent(&pdrv->pdev->dev,
block_header.block_size,
tcon_mm_table.data_mem_vaddr[i],
tcon_mm_table.data_mem_paddr[i]);
} else {
kfree(tcon_mm_table.data_mem_vaddr[i]);
tcon_mm_table.data_mem_vaddr[i] = NULL;
}
}
lcd_tcon_bin_load_next:
@@ -2520,7 +2567,8 @@ static int lcd_tcon_mm_table_config_v1(void)
cnt = tcon_mm_table.block_cnt;
tcon_mm_table.data_mem_vaddr = kcalloc(cnt, sizeof(unsigned char *), GFP_KERNEL);
if (!tcon_mm_table.data_mem_vaddr)
tcon_mm_table.data_mem_paddr = kcalloc(cnt, sizeof(dma_addr_t), GFP_KERNEL);
if (!tcon_mm_table.data_mem_vaddr || !tcon_mm_table.data_mem_paddr)
return -1;
tcon_mm_table.data_priority =
@@ -3565,6 +3613,7 @@ int lcd_tcon_probe(struct aml_lcd_drv_s *pdrv)
int lcd_tcon_remove(struct aml_lcd_drv_s *pdrv)
{
int i;
struct lcd_tcon_data_block_header_s *block_header;
lcd_tcon_debug_file_remove(&tcon_local_cfg);
@@ -3578,11 +3627,28 @@ int lcd_tcon_remove(struct aml_lcd_drv_s *pdrv)
lcd_tcon_data_multi_remvoe(&tcon_mm_table);
if (tcon_mm_table.data_mem_vaddr) {
for (i = 0; i < tcon_mm_table.block_cnt; i++) {
kfree(tcon_mm_table.data_mem_vaddr[i]);
if (!tcon_mm_table.data_mem_vaddr[i])
continue;
block_header = (struct lcd_tcon_data_block_header_s *)
tcon_mm_table.data_mem_vaddr[i];
if (!is_block_type_basic_init(block_header->block_type) &&
is_block_ctrl_dma(block_header->block_ctrl)) {
dma_free_coherent(&pdrv->pdev->dev,
block_header->block_size,
tcon_mm_table.data_mem_vaddr[i],
tcon_mm_table.data_mem_paddr[i]);
} else {
kfree(tcon_mm_table.data_mem_vaddr[i]);
}
tcon_mm_table.data_mem_vaddr[i] = NULL;
tcon_mm_table.data_mem_paddr[i] = 0;
}
kfree(tcon_mm_table.data_mem_vaddr);
tcon_mm_table.data_mem_vaddr = NULL;
kfree(tcon_mm_table.data_mem_paddr);
tcon_mm_table.data_mem_paddr = NULL;
}
}
+7 -1
View File
@@ -100,6 +100,7 @@ struct tcon_data_list_s {
unsigned int *ctrl_data;
char *block_name;
unsigned char *block_vaddr;
phys_addr_t block_paddr;
struct tcon_data_list_s *next;
};
@@ -147,6 +148,7 @@ struct tcon_mem_map_table_s {
struct tcon_data_priority_s *data_priority;
unsigned int *data_size;
unsigned char **data_mem_vaddr;
dma_addr_t *data_mem_paddr;
unsigned int multi_lut_update;
unsigned int data_multi_cnt;
@@ -249,6 +251,10 @@ void lcd_tcon_fw_base_timing_update(struct aml_lcd_drv_s *pdrv);
* **********************************
*/
/* internal */
int lcd_tcon_get_dma_ref(void);
void lcd_tcon_set_dma_ref(int i);
void lcd_tcon_dma_update(struct aml_lcd_drv_s *pdrv);
void lcd_tcon_lut_dma_mif_set(phys_addr_t paddr, unsigned int size);
void lcd_tcon_lut_dma_enable(struct aml_lcd_drv_s *pdrv);
void lcd_tcon_lut_dma_disable(struct aml_lcd_drv_s *pdrv);
@@ -281,7 +287,7 @@ void lcd_tcon_data_multi_current_update(struct tcon_mem_map_table_s *mm_table,
void lcd_tcon_data_multi_bypass_set(struct tcon_mem_map_table_s *mm_table,
unsigned int block_type, int flag);
int lcd_tcon_data_common_parse_set(struct aml_lcd_drv_s *pdrv,
unsigned char *data_buf, int init_flag);
unsigned char *data_buf, phys_addr_t paddr, int init_flag);
void lcd_tcon_init_data_version_update(char *data_buf);
int lcd_tcon_data_load(struct aml_lcd_drv_s *pdrv, unsigned char *data_buf, int index);
int lcd_tcon_bin_load(struct aml_lcd_drv_s *pdrv);
+49 -28
View File
@@ -1275,9 +1275,11 @@ long lcd_tcon_ioctl_handler(struct aml_lcd_drv_s *pdrv, int mcd_nr, unsigned lon
struct aml_lcd_tcon_bin_s lcd_tcon_buff;
struct tcon_rmem_s *tcon_rmem = get_lcd_tcon_rmem();
struct tcon_mem_map_table_s *mm_table = get_lcd_tcon_mm_table();
struct lcd_tcon_data_block_header_s block_header;
unsigned int size = 0, temp, m = 0;
unsigned char *mem_vaddr = NULL;
struct lcd_tcon_data_block_header_s block_header, block_header_old;
unsigned int size = 0, old_size, temp, m = 0, header_size = 0;
struct device *dev;
phys_addr_t paddr = 0, paddr_old = 0;
unsigned char *mem_vaddr = NULL, *vaddr = NULL, *vaddr_old = NULL;
char *str = NULL;
int index = 0;
int ret = 0;
@@ -1360,44 +1362,63 @@ long lcd_tcon_ioctl_handler(struct aml_lcd_drv_s *pdrv, int mcd_nr, unsigned lon
str = (char *)&mem_vaddr[m + 4];
temp = *(unsigned int *)&mem_vaddr[m];
memset(&block_header, 0, sizeof(struct lcd_tcon_data_block_header_s));
header_size = sizeof(struct lcd_tcon_data_block_header_s);
memset(&block_header, 0, header_size);
memset(&block_header_old, 0, header_size);
vaddr_old = mm_table->data_mem_vaddr[index];
paddr_old = mm_table->data_mem_paddr[index];
if (vaddr_old)
memcpy(&block_header_old, vaddr_old, header_size);
argp = (void __user *)lcd_tcon_buff.ptr;
if (copy_from_user(&block_header, argp,
sizeof(struct lcd_tcon_data_block_header_s))) {
if (copy_from_user(&block_header, argp, header_size)) {
ret = -EFAULT;
break;
}
dev = &pdrv->pdev->dev;
old_size = block_header_old.block_size;
size = block_header.block_size;
if (size > lcd_tcon_buff.size ||
size < sizeof(struct lcd_tcon_data_block_header_s)) {
if (size > lcd_tcon_buff.size || size < header_size) {
LCDERR("%s: block[%d] size 0x%x error\n", __func__, index, size);
ret = -EFAULT;
break;
}
kfree(mm_table->data_mem_vaddr[index]);
mm_table->data_mem_vaddr[index] =
kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
if (!mm_table->data_mem_vaddr[index]) {
ret = -EFAULT;
break;
}
if (copy_from_user(mm_table->data_mem_vaddr[index], argp, size)) {
kfree(mm_table->data_mem_vaddr[index]);
mm_table->data_mem_vaddr[index] = NULL;
ret = -EFAULT;
break;
if (is_block_ctrl_dma(block_header.block_ctrl)) {
vaddr = lcd_alloc_dma_buffer(pdrv, size, &paddr);
if (lcd_debug_print_flag)
LCDPR("alloc for tcon mm_table[%d] form lcd_cma_pool\n"
"pa:0x%llx, va:%p, size:0x%x\n",
index, (unsigned long long)paddr, vaddr, size);
} else {
vaddr = kcalloc(size, sizeof(unsigned char), GFP_KERNEL);
paddr = virt_to_phys(vaddr);
}
LCDPR("tcon: load bin_path[%d]: %s, size: 0x%x -> 0x%x\n",
index, str, temp, size);
if (unlikely(!vaddr))
goto set_tcon_bin_error_break;
ret = lcd_tcon_data_load(pdrv, mm_table->data_mem_vaddr[index], index);
if (ret) {
kfree(mm_table->data_mem_vaddr[index]);
mm_table->data_mem_vaddr[index] = NULL;
ret = -EFAULT;
}
if (unlikely(copy_from_user(vaddr, argp, size)))
goto set_tcon_bin_error_break;
LCDPR("tcon: load bin_path[%d]: %s, size: 0x%x -> 0x%x\n", index, str, temp, size);
mm_table->data_mem_vaddr[index] = vaddr;
mm_table->data_mem_paddr[index] = paddr;
ret = lcd_tcon_data_load(pdrv, vaddr, index);
if (unlikely(ret))
goto set_tcon_bin_error_break;
break;
set_tcon_bin_error_break:
mm_table->data_mem_vaddr[index] = vaddr_old;
mm_table->data_mem_paddr[index] = paddr_old;
if (is_block_ctrl_dma(block_header.block_ctrl))
dma_free_coherent(dev, size, vaddr, paddr);
else
kfree(vaddr);
ret = -EFAULT;
break;
default:
LCDERR("tcon: don't support ioctl cmd_nr: 0x%x\n", mcd_nr);
+123 -18
View File
@@ -21,18 +21,85 @@
#include <linux/amlogic/tee.h>
#endif
struct lcd_tcon_dma_info_s {
phys_addr_t paddr;
unsigned int size;
struct list_head list;
};
static struct list_head *lcd_tcon_dma_list_head;
static atomic_t lcd_tcon_dma_ref = ATOMIC_INIT(-1);
int lcd_tcon_get_dma_ref(void)
{
return atomic_read(&lcd_tcon_dma_ref);
}
void lcd_tcon_set_dma_ref(int i)
{
atomic_set(&lcd_tcon_dma_ref, i);
}
static void lcd_tcon_dma_update_add(phys_addr_t paddr, unsigned int size)
{
struct lcd_tcon_dma_info_s *dma_info;
dma_info = kzalloc(sizeof(*dma_info), GFP_KERNEL);
if (!dma_info)
return;
dma_info->paddr = paddr;
dma_info->size = size;
if (lcd_tcon_dma_list_head) {
list_add_tail(&dma_info->list, lcd_tcon_dma_list_head);
} else {
dma_info->list.prev = &dma_info->list;
dma_info->list.next = &dma_info->list;
lcd_tcon_dma_list_head = &dma_info->list;
}
if (atomic_read(&lcd_tcon_dma_ref) < 0)
atomic_set(&lcd_tcon_dma_ref, 0);
atomic_inc(&lcd_tcon_dma_ref);
}
void lcd_tcon_dma_update(struct aml_lcd_drv_s *pdrv)
{
struct lcd_tcon_dma_info_s *dma_info;
struct list_head *list_temp;
lcd_tcon_lut_dma_disable(pdrv);
if (!lcd_tcon_dma_list_head)
return;
dma_info = list_entry(lcd_tcon_dma_list_head, struct lcd_tcon_dma_info_s, list);
if (lcd_debug_print_flag & LCD_DBG_PR_ISR)
LCDPR("%s, dma_info: paddr:0x%llx, size:0x%x\n", __func__,
(unsigned long long)dma_info->paddr, dma_info->size);
lcd_tcon_lut_dma_mif_set(dma_info->paddr, dma_info->size);
lcd_tcon_lut_dma_enable(pdrv);
if (lcd_tcon_dma_list_head->next != lcd_tcon_dma_list_head) {
list_temp = lcd_tcon_dma_list_head->next;
__list_del(lcd_tcon_dma_list_head->prev, lcd_tcon_dma_list_head->next);
lcd_tcon_dma_list_head = list_temp;
} else {
lcd_tcon_dma_list_head = NULL;
}
kfree(dma_info);
atomic_dec(&lcd_tcon_dma_ref);
}
/*
* must check addr and size before called
* paddr: 16bytes aligned
* size: 16bytes aligned
*/
void lcd_tcon_lut_dma_mif_set(phys_addr_t paddr, unsigned int size)
{
unsigned int cmd_cnt = 0;
/* paddr should be 16 byte align*/
if (!paddr || (paddr & 0xf))
return;
/* size must be 128bit align*/
if (size & 0xf)
return;
/* 128 bits per cmd */
cmd_cnt = size >> 4;
lcd_vcbus_write(VPU_DMA_RDMIF7_BADR0, paddr >> 4);
@@ -58,6 +125,9 @@ void lcd_tcon_lut_dma_enable(struct aml_lcd_drv_s *pdrv)
lcd_tcon_setb(pdrv, 0x367, 1, 0, 14); // intr trig pixel
lcd_tcon_setb(pdrv, 0x367, 1, 16, 1); // enale tcon intr
lcd_tcon_setb(pdrv, 0x367, 1, 16, 1); // enale tcon intr
lcd_tcon_setb(pdrv, 0x367, 1, 16, 1); // enale tcon intr
lcd_tcon_setb(pdrv, 0x367, 1, 16, 1); // enale tcon intr
lcd_tcon_setb(pdrv, 0x207, 1, 31, 1); //enable dma clk
}
@@ -66,6 +136,9 @@ void lcd_tcon_lut_dma_disable(struct aml_lcd_drv_s *pdrv)
if (!pdrv)
return;
lcd_tcon_setb(pdrv, 0x367, 0, 16, 1); // disable tcon intr
lcd_tcon_setb(pdrv, 0x367, 0, 16, 1); // disable tcon intr
lcd_tcon_setb(pdrv, 0x367, 0, 16, 1); // disable tcon intr
lcd_tcon_setb(pdrv, 0x367, 0, 16, 1); // disable tcon intr
lcd_tcon_setb(pdrv, 0x207, 0, 31, 1); //disable dma
}
@@ -539,20 +612,21 @@ static int lcd_tcon_wr_n_data_write(struct aml_lcd_drv_s *pdrv,
}
int lcd_tcon_data_common_parse_set(struct aml_lcd_drv_s *pdrv,
unsigned char *data_buf, int init_flag)
unsigned char *data_buf, phys_addr_t paddr, int init_flag)
{
struct lcd_tcon_config_s *tcon_conf = get_lcd_tcon_config();
struct lcd_tcon_data_block_header_s *block_header;
struct lcd_tcon_data_block_ext_header_s *ext_header;
unsigned char *p;
unsigned char *p, *part_start;
unsigned short part_cnt;
unsigned char part_type;
unsigned int size, reg, data, mask, temp, reg_base = 0;
union lcd_tcon_data_part_u data_part;
unsigned int data_offset, offset, i, j, k, d, m, n, step = 0;
unsigned int data_offset = 0, offset, i, j, k, d, m, n, step = 0;
unsigned int reg_cnt, reg_byte, data_cnt, data_byte;
unsigned short block_ctrl_flag;
unsigned char exe_in_isr = 0, exe_ignore = 0;
unsigned int *part_pos, part_start_offset, ext_header_size;
int ret;
if (tcon_conf)
@@ -566,12 +640,16 @@ int lcd_tcon_data_common_parse_set(struct aml_lcd_drv_s *pdrv,
(lcd_debug_print_flag & LCD_DBG_PR_ADV)) {
LCDPR("%s: %s, part_cnt: %d\n", __func__, block_header->name, part_cnt);
}
part_pos = (unsigned int *)(p + LCD_TCON_DATA_BLOCK_EXT_HEADER_SIZE_PRE);
ext_header_size = block_header->ext_header_size;
block_ctrl_flag = block_header->block_ctrl;
data_offset = LCD_TCON_DATA_BLOCK_HEADER_SIZE + block_header->ext_header_size;
part_start = data_buf + LCD_TCON_DATA_BLOCK_HEADER_SIZE + ext_header_size;
size = 0;
part_start_offset = LCD_TCON_DATA_BLOCK_HEADER_SIZE + ext_header_size;
for (i = 0; i < part_cnt; i++) {
p = data_buf + data_offset;
p = part_start + part_pos[i];
data_offset = part_start_offset + part_pos[i];
part_type = p[LCD_TCON_DATA_PART_NAME_SIZE + 3];
exe_in_isr = p[LCD_TCON_DATA_PART_NAME_SIZE + 2];
exe_ignore = (exe_in_isr & LCD_TCON_DATA_PART_FLAG_CMD_IGNORE_ISR) &&
@@ -901,6 +979,32 @@ int lcd_tcon_data_common_parse_set(struct aml_lcd_drv_s *pdrv,
break;
}
break;
case LCD_TCON_DATA_PART_TYPE_DMA:
if (block_ctrl_flag)
goto lcd_tcon_data_common_parse_set_ctrl_err;
data_part.dma = (struct lcd_tcon_data_part_dma_s *)p;
size = LCD_TCON_DATA_PART_DMA_SIZE_PRE + data_part.dma->dma_data_size;
if ((size + data_offset) > block_header->block_size)
goto lcd_tcon_data_common_parse_set_err_size;
offset = p - data_buf + LCD_TCON_DATA_PART_DMA_SIZE_PRE;
if ((lcd_debug_print_flag & LCD_DBG_PR_ADV))
LCDPR("%s: vaddr:0x%px, paddr:0x%llx,\n"
"offset:0x%x, size:0x%x\n",
__func__, data_buf, (unsigned long long)paddr,
offset, data_part.dma->dma_data_size);
paddr += offset;
if (!paddr || paddr & 0xf || data_part.dma->dma_data_size & 0xf)
break;
lcd_tcon_dma_update_add(paddr, data_part.dma->dma_data_size);
if (exe_ignore) {
if ((lcd_debug_print_flag & LCD_DBG_PR_ADV))
LCDPR("%s step %d ignored\n", __func__, step);
break;
}
break;
default:
if (block_ctrl_flag)
goto lcd_tcon_data_common_parse_set_ctrl_err;
@@ -914,7 +1018,6 @@ int lcd_tcon_data_common_parse_set(struct aml_lcd_drv_s *pdrv,
LCDPR("%s: end step %d, %s, type=0x%02x, size=%d\n",
__func__, step, p, part_type, size);
}
data_offset += size;
step++;
}
@@ -942,6 +1045,7 @@ static int lcd_tcon_data_set(struct aml_lcd_drv_s *pdrv,
unsigned char *data_buf;
unsigned int temp_crc32;
unsigned int i, index, chk_size;
phys_addr_t paddr = 0;
int ret;
if (!mm_table->data_mem_vaddr) {
@@ -967,6 +1071,7 @@ static int lcd_tcon_data_set(struct aml_lcd_drv_s *pdrv,
continue;
}
data_buf = mm_table->data_mem_vaddr[index];
paddr = mm_table->data_mem_paddr[index];
block_header = (struct lcd_tcon_data_block_header_s *)data_buf;
if (block_header->block_size < sizeof(struct lcd_tcon_data_block_header_s)) {
LCDERR("%s: block_size[%d] 0x%x is invalid\n",
@@ -994,22 +1099,22 @@ static int lcd_tcon_data_set(struct aml_lcd_drv_s *pdrv,
}
/* apply data */
if (block_header->block_type == LCD_TCON_DATA_BLOCK_TYPE_BASIC_INIT) {
if (is_block_type_basic_init(block_header->block_type)) {
lcd_tcon_data_init_set(pdrv, data_buf);
continue;
}
if (block_header->block_ctrl == LCD_TCON_DATA_CTRL_FLAG_MULTI) {
if (is_block_ctrl_multi(block_header->block_ctrl)) {
ret = lcd_tcon_data_multi_match_find(pdrv, data_buf);
if (ret == 0) {
ret = lcd_tcon_data_common_parse_set(pdrv, data_buf, 1);
ret = lcd_tcon_data_common_parse_set(pdrv, data_buf, paddr, 1);
if (ret == 0) {
lcd_tcon_data_multi_current_update(mm_table,
block_header, index);
}
}
} else {
lcd_tcon_data_common_parse_set(pdrv, data_buf, 1);
lcd_tcon_data_common_parse_set(pdrv, data_buf, paddr, 1);
}
}
@@ -160,12 +160,15 @@ static void lcd_test_pattern_init(struct aml_lcd_drv_s *pdrv, unsigned int num)
static void lcd_venc_gamma_init(struct aml_lcd_drv_s *pdrv)
{
unsigned int data[2];
int index = pdrv->index;
if (pdrv->lcd_pxp)
return;
aml_lcd_notifier_call_chain(LCD_EVENT_GAMMA_UPDATE, &index);
data[0] = index;
data[1] = 0xff; //default gamma lut
aml_lcd_atomic_notifier_call_chain(LCD_EVENT_GAMMA_UPDATE, (void *)data);
lcd_venc_gamma_check_en(pdrv);
}
@@ -199,12 +199,15 @@ static int lcd_venc_debug_test(struct aml_lcd_drv_s *pdrv, unsigned int num)
static void lcd_venc_gamma_init(struct aml_lcd_drv_s *pdrv)
{
unsigned int data[2];
int index = pdrv->index;
if (pdrv->lcd_pxp)
return;
aml_lcd_notifier_call_chain(LCD_EVENT_GAMMA_UPDATE, &index);
data[0] = index;
data[1] = 0xff; //default gamma lut
aml_lcd_atomic_notifier_call_chain(LCD_EVENT_GAMMA_UPDATE, (void *)data);
lcd_venc_gamma_check_en(pdrv);
}
@@ -182,12 +182,15 @@ static void lcd_test_pattern_init(struct aml_lcd_drv_s *pdrv, unsigned int num)
static void lcd_venc_gamma_init(struct aml_lcd_drv_s *pdrv)
{
unsigned int data[2];
int index = pdrv->index;
if (pdrv->lcd_pxp)
return;
aml_lcd_notifier_call_chain(LCD_EVENT_GAMMA_UPDATE, &index);
data[0] = index;
data[1] = 0xff; //default gamma lut
aml_lcd_atomic_notifier_call_chain(LCD_EVENT_GAMMA_UPDATE, (void *)data);
lcd_venc_gamma_check_en(pdrv);
}
+2
View File
@@ -2193,6 +2193,7 @@ static int lcd_probe(struct platform_device *pdev)
pdrv->data = pdata;
//pdrv->of_node = pdev->dev.of_node;
platform_set_drvdata(pdev, pdrv);
pdrv->pdev = pdev;
#ifdef CONFIG_AMLOGIC_VPU
/*vpu dev register for lcd*/
@@ -2212,6 +2213,7 @@ static int lcd_probe(struct platform_device *pdev)
ret = lcd_cdev_add(pdrv, &pdev->dev);
if (ret)
goto lcd_probe_err_2;
ret = lcd_config_probe(pdrv, pdev);
if (ret)
goto lcd_probe_err_2;
@@ -26,6 +26,7 @@
#define LCD_TCON_DATA_BLOCK_TYPE_VAC 0x11
#define LCD_TCON_DATA_BLOCK_TYPE_EXT 0xe0 /* pmu */
#define LCD_TCON_DATA_BLOCK_TYPE_MAX 0xff
#define is_block_type_basic_init(type) ((type) == LCD_TCON_DATA_BLOCK_TYPE_BASIC_INIT)
/* for tconless data block part type */
#define LCD_TCON_DATA_PART_TYPE_WR_N 0xd0
@@ -34,6 +35,7 @@
#define LCD_TCON_DATA_PART_TYPE_RD_MASK 0xab
#define LCD_TCON_DATA_PART_TYPE_CHK_WR_MASK 0xcb
#define LCD_TCON_DATA_PART_TYPE_CHK_EXIT 0xce
#define LCD_TCON_DATA_PART_TYPE_DMA 0xc0
#define LCD_TCON_DATA_PART_TYPE_PARAM 0xf0 /* only for tool */
#define LCD_TCON_DATA_PART_TYPE_CONTROL 0xfc
#define LCD_TCON_DATA_PART_TYPE_DELAY 0xfd
@@ -47,15 +49,23 @@
#define LCD_TCON_DATA_PART_FLAG_CMD_IGNORE_ISR 0x80
#define LCD_TCON_DATA_BLOCK_HEADER_SIZE 64
#define LCD_TCON_DATA_BLOCK_EXT_HEADER_SIZE_PRE 16
#define LCD_TCON_DATA_BLOCK_NAME_SIZE 36
#define LCD_TCON_DATA_PART_NAME_SIZE 48
#define LCD_TCON_INIT_BIN_NAME_SIZE 28
#define LCD_TCON_INIT_BIN_VERSION_SIZE 8
/* tcon data control define */
/* block_ctrl */
/* block_ctrl for normal tcon data*/
#define LCD_TCON_DATA_CTRL_FLAG_MULTI 0x01
#define LCD_TCON_DATA_CTRL_FLAG_DMA 0x02
/*FLAG_DLG only for basic init data*/
#define LCD_TCON_DATA_CTRL_FLAG_DLG 0xd0
#define is_block_ctrl_dma(block_ctrl) ((block_ctrl) & LCD_TCON_DATA_CTRL_FLAG_DMA)
#define is_block_ctrl_multi(block_ctrl) ((block_ctrl) & LCD_TCON_DATA_CTRL_FLAG_MULTI)
#define is_block_ctrl_dlg(block_ctrl) ((block_ctrl) == LCD_TCON_DATA_CTRL_FLAG_DLG)
/* ctrl_method */
#define LCD_TCON_DATA_CTRL_DEFAULT 0x00
#define LCD_TCON_DATA_CTRL_MULTI_VFREQ_DIRECT 0x01
@@ -197,6 +207,17 @@ struct lcd_tcon_data_part_param_s {
unsigned int param_size;
};
#define LCD_TCON_DATA_PART_DMA_SIZE_PRE (LCD_TCON_DATA_PART_NAME_SIZE + 16)
struct lcd_tcon_data_part_dma_s {
char name[LCD_TCON_DATA_PART_NAME_SIZE];
unsigned short part_id;
unsigned char tuning_flag;
unsigned char part_type;
unsigned int dma_data_size;
unsigned char data_byte;
unsigned char reserved[7];
};
union lcd_tcon_data_part_u {
struct lcd_tcon_data_part_ctrl_s *ctrl;
struct lcd_tcon_data_part_wr_n_s *wr_n;
@@ -207,6 +228,7 @@ union lcd_tcon_data_part_u {
struct lcd_tcon_data_part_chk_exit_s *chk_exit;
struct lcd_tcon_data_part_delay_s *delay;
struct lcd_tcon_data_part_param_s *param;
struct lcd_tcon_data_part_dma_s *dma;
};
#define LCD_UKEY_TCON_SPI_BLOCK_SIZE_PRE 20
@@ -679,6 +679,7 @@ struct aml_lcd_drv_s {
unsigned char gamma_en_flag;
unsigned char projection_en;
unsigned char vsync_none_timer_flag;
signed char lcd_cma_ready;
char vsync_isr_name[3][15];
char vbyone_isr_name[10];
char output_name[30];
@@ -687,6 +688,7 @@ struct aml_lcd_drv_s {
struct lcd_data_s *data;
struct cdev cdev;
struct device *dev;
struct platform_device *pdev;
struct lcd_config_s config;
struct lcd_duration_s *std_duration;
struct lcd_duration_s cur_duration;