mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
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:
committed by
gerrit autosubmit
parent
cf648bb6aa
commit
77713835a4
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user