mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
lcd: support dccd parsing flow [2/3]
PD#SWPL-139062 Problem: DCCD support Solution: Support load dccd Verify: T5M Change-Id: I3f30b90b6e27fff1566902b9da848280fe6aa532 Signed-off-by: huijie.huang <huijie.huang@amlogic.com>
This commit is contained in:
committed by
gerrit autosubmit
parent
091b66b611
commit
91ed26090c
@@ -2969,6 +2969,26 @@ lcd_tcon_load_init_data_new_err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int lcd_tcon_dccd_flow_check(struct aml_lcd_drv_s *pdrv)
|
||||
{
|
||||
struct lcd_tcon_fw_s *fw = aml_lcd_tcon_get_fw();
|
||||
|
||||
if (pdrv->boot_ctrl->dccd_flag && fw && fw->valid) {
|
||||
//step 1. wait fw alg handle dccd flow
|
||||
LCDPR("Wait fw alg to handle...\n");
|
||||
wait_for_completion(&fw->alg_comp);
|
||||
|
||||
//step 2. update core reg from fw alg
|
||||
LCDPR("fw alg handle done, update core reg\n");
|
||||
memcpy(tcon_mm_table.core_reg_header, fw->config->core_reg_header,
|
||||
tcon_mm_table.core_reg_header->header_size);
|
||||
memcpy(tcon_mm_table.core_reg_table, fw->config->core_reg_table,
|
||||
tcon_mm_table.core_reg_table_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcd_tcon_get_config(struct aml_lcd_drv_s *pdrv)
|
||||
{
|
||||
tcon_mm_table.data_init = NULL;
|
||||
@@ -2994,6 +3014,8 @@ static int lcd_tcon_get_config(struct aml_lcd_drv_s *pdrv)
|
||||
|
||||
lcd_tcon_debug_file_add(pdrv, &tcon_local_cfg);
|
||||
|
||||
lcd_tcon_dccd_flow_check(pdrv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1228,18 +1228,22 @@ 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_fw_s *tcon_fw = aml_lcd_tcon_get_fw();
|
||||
struct lcd_tcon_data_block_header_s block_header, block_header_old;
|
||||
struct aml_lcd_dccd_config_s dccd_config;
|
||||
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;
|
||||
unsigned char *buf = NULL;
|
||||
int index = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!pdrv)
|
||||
return -EFAULT;
|
||||
|
||||
memset(&dccd_config, 0, sizeof(dccd_config));
|
||||
argp = (void __user *)arg;
|
||||
switch (mcd_nr) {
|
||||
case LCD_IOC_GET_TCON_BIN_MAX_CNT_INFO:
|
||||
@@ -1373,6 +1377,77 @@ set_tcon_bin_error_break:
|
||||
kfree(vaddr);
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
case TCON_IOC_SET_DCCD:
|
||||
ret = -EINVAL;
|
||||
if (copy_from_user(&dccd_config, argp, sizeof(dccd_config)))
|
||||
goto __dccd_set_exit;
|
||||
if (dccd_config.size < 4 || dccd_config.size > 0x10000)
|
||||
goto __dccd_set_exit;
|
||||
|
||||
argp = (void __user *)dccd_config.data.ptr;
|
||||
buf = kzalloc(dccd_config.size, GFP_KERNEL);
|
||||
if (unlikely(!buf)) {
|
||||
LCDERR("Alloc dccd size=%d fail\n", dccd_config.size);
|
||||
goto __dccd_set_exit;
|
||||
}
|
||||
|
||||
if (copy_from_user(buf, argp, dccd_config.size)) {
|
||||
LCDERR("Copy ptr size=%d fail\n", dccd_config.size);
|
||||
goto __dccd_set_exit;
|
||||
}
|
||||
dccd_config.data.ptr = buf;
|
||||
tcon_fw->buf_table_in = (void *)&dccd_config;
|
||||
if (tcon_fw->tcon_alg)
|
||||
ret = tcon_fw->tcon_alg(tcon_fw, 0);
|
||||
__dccd_set_exit:
|
||||
kfree(buf);
|
||||
if (!ret)
|
||||
complete_all(&tcon_fw->alg_comp);
|
||||
break;
|
||||
case TCON_IOC_SET_QUICK_REG:
|
||||
ret = -EINVAL;
|
||||
if (!copy_from_user(&temp, argp, sizeof(temp))) {
|
||||
if (tcon_fw->cmd_handler) {
|
||||
ret = tcon_fw->cmd_handler(tcon_fw,
|
||||
FWCMD_AUTOCALC_SET_QK_REG, &temp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TCON_IOC_GET_DCCD_FLG:
|
||||
temp = !!(tcon_fw->flag & (1 << 8));
|
||||
if (!copy_to_user(argp, &temp, sizeof(temp)))
|
||||
ret = 0;
|
||||
LCDPR("Get dccd flag(%d) %s!\n", temp, !ret ? "ok" : "error");
|
||||
break;
|
||||
case TCON_IOC_GET_CALC_STATUS:
|
||||
temp = 0;
|
||||
ret = -EINVAL;
|
||||
if (tcon_fw->cmd_handler) {
|
||||
ret = tcon_fw->cmd_handler(tcon_fw,
|
||||
FWCMD_AUTOCALC_GET_RDY_FLG, &temp);
|
||||
}
|
||||
if (!ret && !copy_to_user(argp, &temp, sizeof(temp)))
|
||||
ret = 0;
|
||||
LCDPR("Get dccd status(%d) %s!\n", temp, !ret ? "ok" : "error");
|
||||
break;
|
||||
case TCON_IOC_GET_CALC_BUF:
|
||||
if (!tcon_fw->config || !tcon_fw->config->core_reg)
|
||||
goto __tcon_get_calc_exit;
|
||||
if (copy_from_user(&dccd_config, argp, sizeof(dccd_config)))
|
||||
goto __tcon_get_calc_exit;
|
||||
|
||||
dccd_config.size = tcon_fw->config->core_reg_size;
|
||||
if (copy_to_user(argp, &dccd_config, sizeof(dccd_config)))
|
||||
goto __tcon_get_calc_exit;
|
||||
|
||||
argp = (void __user *)dccd_config.data.ptr;
|
||||
if (copy_to_user(argp, tcon_fw->config->core_reg, dccd_config.size))
|
||||
goto __tcon_get_calc_exit;
|
||||
ret = 0;
|
||||
|
||||
__tcon_get_calc_exit:
|
||||
LCDPR("Get tcon calc buf %s\n", ret ? "fail" : "ok");
|
||||
break;
|
||||
default:
|
||||
LCDERR("tcon: don't support ioctl cmd_nr: 0x%x\n", mcd_nr);
|
||||
ret = -EINVAL;
|
||||
@@ -1424,7 +1499,12 @@ static long lcd_tcon_ioctl(struct file *file, unsigned int cmd, unsigned long ar
|
||||
case LCD_IOC_SET_TCON_DATA_INDEX_INFO:
|
||||
case LCD_IOC_GET_TCON_BIN_PATH_INFO:
|
||||
case LCD_IOC_SET_TCON_BIN_DATA_INFO:
|
||||
lcd_tcon_ioctl_handler(pdrv, mcd_nr, arg);
|
||||
case TCON_IOC_SET_DCCD:
|
||||
case TCON_IOC_SET_QUICK_REG:
|
||||
case TCON_IOC_GET_DCCD_FLG:
|
||||
case TCON_IOC_GET_CALC_BUF:
|
||||
case TCON_IOC_GET_CALC_STATUS:
|
||||
ret = lcd_tcon_ioctl_handler(pdrv, mcd_nr, arg);
|
||||
break;
|
||||
default:
|
||||
LCDERR("tcon: don't support ioctl cmd_nr: 0x%x\n", mcd_nr);
|
||||
|
||||
@@ -143,6 +143,10 @@ static struct tcon_fw_config_s lcd_tcon_fw_config = {
|
||||
.if_type = TCON_IF_TYPE_MAX,
|
||||
.axi_cnt = 0,
|
||||
.axi_rmem = NULL,
|
||||
.core_reg = NULL,
|
||||
.core_reg_size = 0,
|
||||
.core_reg_header = NULL,
|
||||
.core_reg_table = NULL,
|
||||
};
|
||||
|
||||
static struct tcon_fw_base_timing_s lcd_tcon_fw_base_timing;
|
||||
@@ -305,6 +309,32 @@ void lcd_tcon_fw_prepare(struct aml_lcd_drv_s *pdrv, struct lcd_tcon_config_s *t
|
||||
lcd_tcon_fw.config->axi_rmem[i].mem_size = tcon_rmem->axi_rmem[i].mem_size;
|
||||
}
|
||||
|
||||
if (!mm_table->core_reg_table || !mm_table->core_reg_header) {
|
||||
LCDERR("Invalid core reg table\n");
|
||||
kfree(lcd_tcon_fw.config->axi_rmem);
|
||||
lcd_tcon_fw.config->axi_rmem = NULL;
|
||||
lcd_tcon_fw.config->axi_cnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (pdrv->boot_ctrl->dccd_flag) {
|
||||
lcd_tcon_fw.config->core_reg_size = mm_table->core_reg_header->header_size +
|
||||
mm_table->core_reg_table_size;
|
||||
lcd_tcon_fw.config->core_reg =
|
||||
kzalloc(lcd_tcon_fw.config->core_reg_size, GFP_KERNEL);
|
||||
if (lcd_tcon_fw.config->core_reg) {
|
||||
memmove(lcd_tcon_fw.config->core_reg, mm_table->core_reg_header,
|
||||
mm_table->core_reg_header->header_size);
|
||||
memmove(lcd_tcon_fw.config->core_reg +
|
||||
mm_table->core_reg_header->header_size,
|
||||
mm_table->core_reg_table, mm_table->core_reg_table_size);
|
||||
lcd_tcon_fw.config->core_reg_header =
|
||||
(struct lcd_tcon_init_block_header_s *)lcd_tcon_fw.config->core_reg;
|
||||
lcd_tcon_fw.config->core_reg_table = lcd_tcon_fw.config->core_reg +
|
||||
lcd_tcon_fw.config->core_reg_header->header_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (pdrv->status & LCD_STATUS_IF_ON)
|
||||
lcd_tcon_fw.tcon_state |= TCON_FW_STATE_TCON_EN;
|
||||
if (mm_table->lut_valid_flag & LCD_TCON_DATA_VALID_VAC)
|
||||
@@ -321,9 +351,11 @@ void lcd_tcon_fw_prepare(struct aml_lcd_drv_s *pdrv, struct lcd_tcon_config_s *t
|
||||
lcd_tcon_fw.tcon_state |= TCON_FW_STATE_LOD_VALID;
|
||||
|
||||
lcd_tcon_fw_base_timing_update(pdrv);
|
||||
init_completion(&lcd_tcon_fw.alg_comp);
|
||||
|
||||
lcd_tcon_fw.drvdat = (void *)pdrv;
|
||||
lcd_tcon_fw.dev = pdrv->dev;
|
||||
lcd_tcon_fw.flag |= (((unsigned int)pdrv->boot_ctrl->dccd_flag) << 8);
|
||||
|
||||
lcd_tcon_fw.valid = 1;
|
||||
|
||||
|
||||
@@ -1530,7 +1530,12 @@ static long lcd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
case LCD_IOC_SET_TCON_DATA_INDEX_INFO:
|
||||
case LCD_IOC_GET_TCON_BIN_PATH_INFO:
|
||||
case LCD_IOC_SET_TCON_BIN_DATA_INFO:
|
||||
lcd_tcon_ioctl_handler(pdrv, mcd_nr, arg);
|
||||
case TCON_IOC_SET_DCCD:
|
||||
case TCON_IOC_SET_QUICK_REG:
|
||||
case TCON_IOC_GET_DCCD_FLG:
|
||||
case TCON_IOC_GET_CALC_BUF:
|
||||
case TCON_IOC_GET_CALC_STATUS:
|
||||
ret = lcd_tcon_ioctl_handler(pdrv, mcd_nr, arg);
|
||||
break;
|
||||
case LCD_IOC_POWER_CTRL:
|
||||
if (copy_from_user((void *)&temp, argp, sizeof(unsigned int))) {
|
||||
@@ -2081,6 +2086,11 @@ static void lcd_config_default(struct aml_lcd_drv_s *pdrv)
|
||||
pdrv->config.timing.dft_timing.v_period = pdrv->config.timing.act_timing.v_period;
|
||||
|
||||
if (init_state) {
|
||||
if (pdrv->boot_ctrl->dccd_flag) {
|
||||
pdrv->boot_ctrl->init_level = LCD_INIT_LEVEL_KERNEL_ON;
|
||||
LCDPR("DCCD flow detected!\n");
|
||||
}
|
||||
|
||||
switch (pdrv->boot_ctrl->init_level) {
|
||||
case LCD_INIT_LEVEL_NORMAL:
|
||||
pdrv->status = (LCD_STATUS_ON | LCD_STATUS_PREPARE | LCD_STATUS_POWER);
|
||||
@@ -2735,6 +2745,7 @@ static int lcd_boot_ctrl_setup(char *str)
|
||||
boot_ctrl->lcd_bits = (data32 >> 4) & 0xf;
|
||||
boot_ctrl->advanced_flag = (data32 >> 8) & 0xff;
|
||||
boot_ctrl->custom_pinmux = (data32 >> 16) & 0x1;
|
||||
boot_ctrl->dccd_flag = (data32 >> 17) & 0x1;
|
||||
boot_ctrl->init_level = (data32 >> 18) & 0x3;
|
||||
boot_ctrl->ppc = (data32 >> 20) & 0x3;
|
||||
boot_ctrl->clk_mode = (data32 >> 22) & 0x3;
|
||||
@@ -2762,6 +2773,7 @@ static int lcd1_boot_ctrl_setup(char *str)
|
||||
boot_ctrl->lcd_bits = (data32 >> 4) & 0xf;
|
||||
boot_ctrl->advanced_flag = (data32 >> 8) & 0xff;
|
||||
boot_ctrl->custom_pinmux = (data32 >> 16) & 0x1;
|
||||
boot_ctrl->dccd_flag = (data32 >> 17) & 0x1;
|
||||
boot_ctrl->init_level = (data32 >> 18) & 0x3;
|
||||
boot_ctrl->ppc = (data32 >> 20) & 0x3;
|
||||
boot_ctrl->clk_mode = (data32 >> 22) & 0x3;
|
||||
@@ -2789,6 +2801,7 @@ static int lcd2_boot_ctrl_setup(char *str)
|
||||
boot_ctrl->lcd_bits = (data32 >> 4) & 0xf;
|
||||
boot_ctrl->advanced_flag = (data32 >> 8) & 0xff;
|
||||
boot_ctrl->custom_pinmux = (data32 >> 16) & 0x1;
|
||||
boot_ctrl->dccd_flag = (data32 >> 17) & 0x1;
|
||||
boot_ctrl->init_level = (data32 >> 18) & 0x3;
|
||||
boot_ctrl->ppc = (data32 >> 20) & 0x3;
|
||||
boot_ctrl->clk_mode = (data32 >> 22) & 0x3;
|
||||
|
||||
@@ -87,7 +87,9 @@ struct lcd_tcon_init_block_header_s {
|
||||
unsigned short ext_header_size;
|
||||
unsigned short block_type;
|
||||
unsigned short block_ctrl;
|
||||
unsigned char reserved2[5];
|
||||
unsigned char dccd_flag;
|
||||
unsigned char dccd_crc;
|
||||
unsigned char reserved2[3];
|
||||
unsigned char data_byte_width;
|
||||
unsigned short chipid;
|
||||
unsigned char name[LCD_TCON_INIT_BIN_NAME_SIZE];
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
#define _INC_AML_LCD_TCON_FW_H
|
||||
#include <linux/types.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
#define TCON_FW_PARA_VER 2
|
||||
#define TCON_FW_PARA_VER 3
|
||||
|
||||
enum tcon_fw_chip_e {
|
||||
TCON_CHIP_TL1 = 0,
|
||||
@@ -40,6 +41,11 @@ struct tcon_fw_config_s {
|
||||
unsigned int if_type;
|
||||
unsigned char axi_cnt;
|
||||
struct tcon_fw_axi_rmem_s *axi_rmem;
|
||||
|
||||
unsigned char *core_reg; //full tcon bin
|
||||
unsigned int core_reg_size; //size of tcon bin
|
||||
struct lcd_tcon_init_block_header_s *core_reg_header; //tcon bin header
|
||||
unsigned char *core_reg_table; //tcon bin register map
|
||||
};
|
||||
|
||||
struct tcon_fw_base_timing_s {
|
||||
@@ -96,13 +102,19 @@ struct tcon_fw_data_header_s {
|
||||
#define TCON_FW_STATE_OD_VALID 0x00010000
|
||||
#define TCON_FW_STATE_LOD_VALID 0x00100000
|
||||
|
||||
#define FWCMD_AUTOCALC_SET_QK_REG 0x1
|
||||
#define FWCMD_AUTOCALC_GET_RDY_FLG 0x2
|
||||
|
||||
struct lcd_tcon_fw_s {
|
||||
/* init by driver */
|
||||
unsigned int para_ver;
|
||||
unsigned int para_size;
|
||||
unsigned char valid;
|
||||
|
||||
// bit[8]: dccd flag, indicate running dccd flow
|
||||
unsigned int flag; //for some state update
|
||||
unsigned int tcon_state;
|
||||
struct completion alg_comp; //indicate alg handle done
|
||||
|
||||
/* init by fw */
|
||||
char fw_ver[20];
|
||||
@@ -142,6 +154,7 @@ struct lcd_tcon_fw_s {
|
||||
int (*tcon_alg)(struct lcd_tcon_fw_s *fw, unsigned int flag);
|
||||
ssize_t (*debug_show)(struct lcd_tcon_fw_s *fw, char *buf);
|
||||
ssize_t (*debug_store)(struct lcd_tcon_fw_s *fw, const char *buf, size_t count);
|
||||
int (*cmd_handler)(struct lcd_tcon_fw_s *fw, unsigned int cmd, void *data);
|
||||
};
|
||||
|
||||
struct lcd_tcon_fw_s *aml_lcd_tcon_get_fw(void);
|
||||
|
||||
@@ -608,20 +608,21 @@ struct lcd_config_s {
|
||||
#define LCD_VENC_4PPC 2
|
||||
|
||||
/*
|
||||
*bit[31:24]: base frame rate
|
||||
*bit[23:22]: clk mode
|
||||
*bit[21:20]: ppc
|
||||
*bit[19:18]: lcd_init_level
|
||||
*bit[17]: reserved
|
||||
*bit[16]: custom pinmux flag
|
||||
*bit[15:8]: advanced flag(p2p_type when lcd_type=p2p)
|
||||
*bit[7:4]: lcd bits
|
||||
*bit[3:0]: lcd_type
|
||||
* bit[31:24] : base frame rate
|
||||
* bit[23:22] : clk mode
|
||||
* bit[21:20] : ppc
|
||||
* bit[19:18] : lcd_init_level
|
||||
* bit[17] : dccd flag
|
||||
* bit[16] : custom pinmux flag
|
||||
* bit[15:8] : advanced flag(p2p_type when lcd_type=p2p)
|
||||
* bit[7:4] : lcd bits
|
||||
* bit[3:0] : lcd_type
|
||||
*/
|
||||
struct lcd_boot_ctrl_s {
|
||||
unsigned char lcd_type;
|
||||
unsigned char lcd_bits;
|
||||
unsigned char advanced_flag;
|
||||
unsigned char dccd_flag;
|
||||
unsigned char custom_pinmux;
|
||||
unsigned char init_level;
|
||||
unsigned char ppc;
|
||||
|
||||
@@ -80,6 +80,14 @@ struct aml_lcd_ss_ctl_s {
|
||||
unsigned int mode;
|
||||
};
|
||||
|
||||
struct aml_lcd_dccd_config_s {
|
||||
unsigned int size;
|
||||
union {
|
||||
void *ptr;
|
||||
unsigned long long unuse;
|
||||
} data;
|
||||
};
|
||||
|
||||
#define LCD_IOC_TYPE 'C'
|
||||
#define LCD_IOC_NR_GET_HDR_INFO 0x0
|
||||
#define LCD_IOC_NR_SET_HDR_INFO 0x1
|
||||
@@ -96,6 +104,15 @@ struct aml_lcd_ss_ctl_s {
|
||||
#define LCD_IOC_SET_SS 0xc
|
||||
#define LCD_IOC_GET_SS 0xd
|
||||
|
||||
/*
|
||||
* tcon use 0x20~0x2f
|
||||
*/
|
||||
#define TCON_IOC_SET_DCCD 0x20
|
||||
#define TCON_IOC_SET_QUICK_REG 0x21
|
||||
#define TCON_IOC_GET_DCCD_FLG 0x22
|
||||
#define TCON_IOC_GET_CALC_BUF 0x23
|
||||
#define TCON_IOC_GET_CALC_STATUS 0x24
|
||||
|
||||
#define LCD_IOC_CMD_GET_HDR_INFO \
|
||||
_IOR(LCD_IOC_TYPE, LCD_IOC_NR_GET_HDR_INFO, struct lcd_optical_info_s)
|
||||
#define LCD_IOC_CMD_SET_HDR_INFO \
|
||||
@@ -122,5 +139,16 @@ struct aml_lcd_ss_ctl_s {
|
||||
#define LCD_IOC_CMD_GET_SS \
|
||||
_IOR(LCD_IOC_TYPE, LCD_IOC_GET_SS, struct aml_lcd_ss_ctl_s)
|
||||
|
||||
#define TCON_IOC_CMD_SET_DCCD \
|
||||
_IOW(LCD_IOC_TYPE, TCON_IOC_SET_DCCD, struct aml_lcd_dccd_config_s)
|
||||
#define TCON_IOC_CMD_SET_QUICK_REG \
|
||||
_IOW(LCD_IOC_TYPE, TCON_IOC_SET_QUICK_REG, unsigned int)
|
||||
#define TCON_IOC_CMD_GET_DCCD_FLG \
|
||||
_IOR(LCD_IOC_TYPE, TCON_IOC_GET_DCCD_FLG, unsigned int)
|
||||
#define TCON_IOC_CMD_GET_CALC_BUF \
|
||||
_IOR(LCD_IOC_TYPE, TCON_IOC_GET_CALC_BUF, struct aml_lcd_dccd_config_s)
|
||||
#define TCON_IOC_CMD_GET_CALC_STATUS \
|
||||
_IOR(LCD_IOC_TYPE, TCON_IOC_GET_CALC_STATUS, unsigned int)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user