lcd: tcon: add tcon_fw support [1/3]

PD#SWPL-116221

Problem:
need support tcon fw

Solution:
add tcon fw support

Verify:
ay301

Change-Id: If517305e649c69bcfcb2662a2f6a33684a923f03
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
This commit is contained in:
Evoke Zhang
2023-05-06 20:27:45 +08:00
committed by gerrit autosubmit
parent e602bebf51
commit 4e0a56d565
14 changed files with 359 additions and 218 deletions
+2
View File
@@ -14,12 +14,14 @@ config AMLOGIC_MEDIA_ALGORITHM
sl_hdr
ldim
frc
tcon
if AMLOGIC_MEDIA_ALGORITHM
#source "$(COMMON_DRIVERS_DIR)/drivers/algorithm/ldim/Kconfig"
#source "$(COMMON_DRIVERS_DIR)/drivers/algorithm/dnlp/Kconfig"
#source "$(COMMON_DRIVERS_DIR)/drivers/algorithm/common/Kconfig"
#source "$(COMMON_DRIVERS_DIR)/drivers/algorithm/frc/Kconfig"
#source "$(COMMON_DRIVERS_DIR)/drivers/algorithm/tcon/Kconfig"
endif
endmenu
+1
View File
@@ -2,3 +2,4 @@
#obj-$(CONFIG_AMLOGIC_MEDIA_ALGORITHM) += dnlp/
#obj-$(CONFIG_AMLOGIC_MEDIA_ALGORITHM) += common/
#obj-$(CONFIG_AMLOGIC_MEDIA_ALGORITHM) += frc/
#obj-$(CONFIG_AMLOGIC_MEDIA_ALGORITHM) += tcon/
+4 -5
View File
@@ -32,7 +32,8 @@
/* 20230303: fix hdmi mode 47hz & 95hz timing*/
/* 20230313: update tcon debug info print*/
/* 20230319: optimize phy code*/
#define LCD_DRV_VERSION "20230319"
/* 20230510: support tcon fw*/
#define LCD_DRV_VERSION "20230510"
extern struct mutex lcd_vout_mutex;
extern spinlock_t lcd_reg_spinlock;
@@ -129,9 +130,6 @@ void lcd_tcon_reg_write(struct aml_lcd_drv_s *pdrv,
unsigned int addr, unsigned int val);
int lcd_tcon_probe(struct aml_lcd_drv_s *pdrv);
void lcd_tcon_global_reset(struct aml_lcd_drv_s *pdrv);
int lcd_tcon_gamma_set_pattern(struct aml_lcd_drv_s *pdrv,
unsigned int bit_width, unsigned int gamma_r,
unsigned int gamma_g, unsigned int gamma_b);
unsigned int lcd_tcon_table_read(unsigned int addr);
unsigned int lcd_tcon_table_write(unsigned int addr, unsigned int val);
int lcd_tcon_core_update(struct aml_lcd_drv_s *pdrv);
@@ -177,7 +175,8 @@ void lcd_clk_config_init(void);
void aml_lcd_prbs_test(struct aml_lcd_drv_s *pdrv, unsigned int ms, unsigned int mode_flag);
/* lcd venc */
unsigned int lcd_get_encl_lint_cnt(struct aml_lcd_drv_s *pdrv);
unsigned int lcd_get_encl_line_cnt(struct aml_lcd_drv_s *pdrv);
unsigned int lcd_get_encl_frm_cnt(struct aml_lcd_drv_s *pdrv);
void lcd_wait_vsync(struct aml_lcd_drv_s *pdrv);
void lcd_gamma_debug_test_en(struct aml_lcd_drv_s *pdrv, int flag);
+53 -29
View File
@@ -21,6 +21,7 @@
#include <linux/amlogic/media/vout/lcd/lcd_tcon_data.h>
#include <linux/amlogic/media/vout/lcd/lcd_notify.h>
#include <linux/amlogic/media/vout/lcd/lcd_unifykey.h>
#include <linux/amlogic/media/vout/lcd/lcd_tcon_fw.h>
#include "lcd_reg.h"
#include "lcd_common.h"
#ifdef CONFIG_AMLOGIC_LCD_TABLET
@@ -31,8 +32,8 @@
#include "lcd_tcon.h"
#include "./lcd_clk/lcd_clk_config.h"
/* 1: unlocked, 0: locked, negative: locked, possible waiters */
struct mutex lcd_tcon_adb_mutex;
//1: unlocked, 0: locked, negative: locked, possible waiters
struct mutex lcd_tcon_dbg_mutex;
/*device attribute buf max size 4k*/
#define PR_BUF_MAX (4 * 1024)
@@ -5041,7 +5042,6 @@ static ssize_t lcd_tcon_debug_store(struct device *dev, struct device_attribute
char *buf_orig;
char **parm = NULL;
unsigned int temp = 0, val, back_val, i, n, size = 0;
unsigned int gamma_r, gamma_g, gamma_b;
struct tcon_mem_map_table_s *mm_table = get_lcd_tcon_mm_table();
unsigned char data;
unsigned char *table = NULL;
@@ -5193,22 +5193,6 @@ static ssize_t lcd_tcon_debug_store(struct device *dev, struct device_attribute
lcd_tcon_read(pdrv, temp + i));
}
}
} else if (strcmp(parm[0], "gamma") == 0) { /* save buf to bin */
if (!parm[4])
goto lcd_tcon_debug_store_err;
ret = kstrtouint(parm[1], 10, &temp);
if (ret)
goto lcd_tcon_debug_store_err;
ret = kstrtouint(parm[2], 16, &gamma_r);
if (ret)
goto lcd_tcon_debug_store_err;
ret = kstrtouint(parm[3], 16, &gamma_g);
if (ret)
goto lcd_tcon_debug_store_err;
ret = kstrtouint(parm[4], 16, &gamma_b);
if (ret)
goto lcd_tcon_debug_store_err;
lcd_tcon_gamma_set_pattern(pdrv, temp, gamma_r, gamma_g, gamma_b);
} else if (strcmp(parm[0], "table") == 0) {
if (lcd_tcon_reg_table_check(table, size))
goto lcd_tcon_debug_store_end;
@@ -5444,12 +5428,12 @@ static ssize_t lcd_tcon_adb_status_show(struct device *dev,
int len = 0;
unsigned int i, addr;
mutex_lock(&lcd_tcon_adb_mutex);
mutex_lock(&lcd_tcon_dbg_mutex);
len += sprintf(buf + len, "for_tool:");
if ((pdrv->status & LCD_STATUS_IF_ON) == 0) {
len += sprintf(buf + len, "ERROR\n");
mutex_unlock(&lcd_tcon_adb_mutex);
mutex_unlock(&lcd_tcon_dbg_mutex);
return len;
}
switch (adb_reg.rw_mode) {
@@ -5523,7 +5507,7 @@ static ssize_t lcd_tcon_adb_status_show(struct device *dev,
break;
}
len += sprintf(buf + len, "\n");
mutex_unlock(&lcd_tcon_adb_mutex);
mutex_unlock(&lcd_tcon_dbg_mutex);
return len;
}
@@ -5544,18 +5528,18 @@ static ssize_t lcd_tcon_adb_debug_store(struct device *dev, struct device_attrib
if (!buf)
return count;
mutex_lock(&lcd_tcon_adb_mutex);
mutex_lock(&lcd_tcon_dbg_mutex);
buf_orig = kstrdup(buf, GFP_KERNEL);
if (!buf_orig) {
mutex_unlock(&lcd_tcon_adb_mutex);
mutex_unlock(&lcd_tcon_dbg_mutex);
return count;
}
parm = kcalloc(1500, sizeof(char *), GFP_KERNEL);
if (!parm) {
kfree(buf_orig);
mutex_unlock(&lcd_tcon_adb_mutex);
mutex_unlock(&lcd_tcon_dbg_mutex);
return count;
}
@@ -5713,7 +5697,7 @@ static ssize_t lcd_tcon_adb_debug_store(struct device *dev, struct device_attrib
kfree(parm);
kfree(buf_orig);
mutex_unlock(&lcd_tcon_adb_mutex);
mutex_unlock(&lcd_tcon_dbg_mutex);
return count;
lcd_tcon_adb_debug_store_err:
@@ -5721,7 +5705,45 @@ lcd_tcon_adb_debug_store_err:
kfree(parm);
kfree(buf_orig);
mutex_unlock(&lcd_tcon_adb_mutex);
mutex_unlock(&lcd_tcon_dbg_mutex);
return count;
}
static ssize_t lcd_tcon_fw_dbg_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct lcd_tcon_fw_s *tcon_fw = aml_lcd_tcon_get_fw();
ssize_t ret = 0;
if (!tcon_fw)
return ret;
if (tcon_fw->debug_show)
ret = tcon_fw->debug_show(tcon_fw, buf);
return ret;
}
static ssize_t lcd_tcon_fw_dbg_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct aml_lcd_drv_s *pdrv = dev_get_drvdata(dev);
struct lcd_tcon_fw_s *tcon_fw = aml_lcd_tcon_get_fw();
if ((pdrv->status & LCD_STATUS_IF_ON) == 0)
return count;
if (!buf)
return count;
if (!tcon_fw)
return count;
mutex_lock(&lcd_tcon_dbg_mutex);
if (tcon_fw->debug_store)
tcon_fw->debug_store(tcon_fw, buf);
mutex_unlock(&lcd_tcon_dbg_mutex);
return count;
}
@@ -6278,6 +6300,7 @@ static struct device_attribute lcd_debug_attrs_mlvds[] = {
__ATTR(tcon, 0644, lcd_tcon_debug_show, lcd_tcon_debug_store),
__ATTR(tcon_status, 0444, lcd_tcon_status_show, NULL),
__ATTR(tcon_reg, 0644, lcd_tcon_adb_status_show, lcd_tcon_adb_debug_store),
__ATTR(tcon_fw, 0644, lcd_tcon_fw_dbg_show, lcd_tcon_fw_dbg_store),
__ATTR(null, 0644, NULL, NULL)
};
@@ -6287,6 +6310,7 @@ static struct device_attribute lcd_debug_attrs_p2p[] = {
__ATTR(tcon, 0644, lcd_tcon_debug_show, lcd_tcon_debug_store),
__ATTR(tcon_status, 0444, lcd_tcon_status_show, NULL),
__ATTR(tcon_reg, 0644, lcd_tcon_adb_status_show, lcd_tcon_adb_debug_store),
__ATTR(tcon_fw, 0644, lcd_tcon_fw_dbg_show, lcd_tcon_fw_dbg_store),
__ATTR(null, 0644, NULL, NULL)
};
@@ -6814,11 +6838,11 @@ int lcd_debug_probe(struct aml_lcd_drv_s *pdrv)
lcd_debug_info->debug_if = lcd_debug_info->debug_if_edp;
break;
case LCD_MLVDS:
mutex_init(&lcd_tcon_adb_mutex);
mutex_init(&lcd_tcon_dbg_mutex);
lcd_debug_info->debug_if = lcd_debug_info->debug_if_mlvds;
break;
case LCD_P2P:
mutex_init(&lcd_tcon_adb_mutex);
mutex_init(&lcd_tcon_dbg_mutex);
lcd_debug_info->debug_if = lcd_debug_info->debug_if_p2p;
break;
default:
+12
View File
@@ -826,6 +826,7 @@ unsigned int lcd_tcon_read(struct aml_lcd_drv_s *pdrv, unsigned int reg)
return temp;
};
EXPORT_SYMBOL(lcd_tcon_read);
void lcd_tcon_write(struct aml_lcd_drv_s *pdrv,
unsigned int reg, unsigned int val)
@@ -839,6 +840,7 @@ void lcd_tcon_write(struct aml_lcd_drv_s *pdrv,
writel(val, p);
spin_unlock_irqrestore(&lcd_reg_spinlock, flags);
};
EXPORT_SYMBOL(lcd_tcon_write);
void lcd_tcon_setb(struct aml_lcd_drv_s *pdrv,
unsigned int reg, unsigned int value,
@@ -858,6 +860,7 @@ void lcd_tcon_setb(struct aml_lcd_drv_s *pdrv,
}
spin_unlock_irqrestore(&lcd_reg_spinlock, flags);
}
EXPORT_SYMBOL(lcd_tcon_setb);
unsigned int lcd_tcon_getb(struct aml_lcd_drv_s *pdrv, unsigned int reg,
unsigned int start, unsigned int len)
@@ -877,6 +880,7 @@ unsigned int lcd_tcon_getb(struct aml_lcd_drv_s *pdrv, unsigned int reg,
return temp;
}
EXPORT_SYMBOL(lcd_tcon_getb);
void lcd_tcon_update_bits(struct aml_lcd_drv_s *pdrv, unsigned int reg,
unsigned int mask, unsigned int value)
@@ -898,6 +902,7 @@ void lcd_tcon_update_bits(struct aml_lcd_drv_s *pdrv, unsigned int reg,
}
spin_unlock_irqrestore(&lcd_reg_spinlock, flags);
}
EXPORT_SYMBOL(lcd_tcon_update_bits);
int lcd_tcon_check_bits(struct aml_lcd_drv_s *pdrv, unsigned int reg,
unsigned int mask, unsigned int value)
@@ -921,6 +926,7 @@ int lcd_tcon_check_bits(struct aml_lcd_drv_s *pdrv, unsigned int reg,
return temp;
}
EXPORT_SYMBOL(lcd_tcon_check_bits);
unsigned char lcd_tcon_read_byte(struct aml_lcd_drv_s *pdrv, unsigned int reg)
{
@@ -936,6 +942,7 @@ unsigned char lcd_tcon_read_byte(struct aml_lcd_drv_s *pdrv, unsigned int reg)
return temp;
};
EXPORT_SYMBOL(lcd_tcon_read_byte);
void lcd_tcon_write_byte(struct aml_lcd_drv_s *pdrv,
unsigned int reg, unsigned char val)
@@ -949,6 +956,7 @@ void lcd_tcon_write_byte(struct aml_lcd_drv_s *pdrv,
writeb(val, p);
spin_unlock_irqrestore(&lcd_reg_spinlock, flags);
};
EXPORT_SYMBOL(lcd_tcon_write_byte);
void lcd_tcon_setb_byte(struct aml_lcd_drv_s *pdrv,
unsigned int reg, unsigned char value,
@@ -968,6 +976,7 @@ void lcd_tcon_setb_byte(struct aml_lcd_drv_s *pdrv,
}
spin_unlock_irqrestore(&lcd_reg_spinlock, flags);
}
EXPORT_SYMBOL(lcd_tcon_setb_byte);
unsigned char lcd_tcon_getb_byte(struct aml_lcd_drv_s *pdrv, unsigned int reg,
unsigned int start, unsigned int len)
@@ -986,6 +995,7 @@ unsigned char lcd_tcon_getb_byte(struct aml_lcd_drv_s *pdrv, unsigned int reg,
return temp;
}
EXPORT_SYMBOL(lcd_tcon_getb_byte);
void lcd_tcon_update_bits_byte(struct aml_lcd_drv_s *pdrv, unsigned int reg,
unsigned char mask, unsigned char value)
@@ -1007,6 +1017,7 @@ void lcd_tcon_update_bits_byte(struct aml_lcd_drv_s *pdrv, unsigned int reg,
}
spin_unlock_irqrestore(&lcd_reg_spinlock, flags);
}
EXPORT_SYMBOL(lcd_tcon_update_bits_byte);
int lcd_tcon_check_bits_byte(struct aml_lcd_drv_s *pdrv, unsigned int reg,
unsigned char mask, unsigned char value)
@@ -1030,6 +1041,7 @@ int lcd_tcon_check_bits_byte(struct aml_lcd_drv_s *pdrv, unsigned int reg,
return temp;
}
EXPORT_SYMBOL(lcd_tcon_check_bits_byte);
unsigned int dptx_reg_read(struct aml_lcd_drv_s *pdrv, unsigned int reg)
{
+135 -30
View File
@@ -26,6 +26,7 @@
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
#include <linux/amlogic/media/vout/lcd/lcd_unifykey.h>
#include <linux/amlogic/media/vout/lcd/lcd_notify.h>
#include <linux/amlogic/media/vout/lcd/lcd_tcon_fw.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#ifdef CONFIG_AMLOGIC_BACKLIGHT
#include <linux/amlogic/media/vout/lcd/aml_bl.h>
@@ -51,6 +52,7 @@ static struct lcd_tcon_local_cfg_s tcon_local_cfg;
static int lcd_tcon_data_multi_remvoe(struct tcon_mem_map_table_s *mm_table);
static int lcd_tcon_data_multi_reset(struct tcon_mem_map_table_s *mm_table);
static void lcd_tcon_fw_prepare(struct aml_lcd_drv_s *pdrv);
static unsigned long long *dbg_vsync_time, *dbg_list_trave_time;
static unsigned int dbg_vsync_cnt, dbg_list_trave_cnt;
@@ -185,6 +187,48 @@ void lcd_tcon_dbg_trace_print(unsigned int flag)
* tcon common function
* **********************************
*/
static struct tcon_fw_config_s lcd_tcon_fw_config = {
.config_size = sizeof(struct tcon_fw_config_s),
.chip_type = TCON_CHIP_MAX,
.if_type = TCON_IF_TYPE_MAX,
.axi_cnt = 0,
.axi_rmem = NULL,
};
static struct lcd_tcon_fw_s lcd_tcon_fw = {
/* init by driver */
.para_ver = TCON_FW_PARA_VER,
.para_size = sizeof(struct lcd_tcon_fw_s),
.valid = 0,
.tcon_state = 0,
/* init by fw */
.flag = 0,
.fw_ver = "not installed",
.dbg_level = 0,
/* driver resource */
.drvdat = NULL,
.dev = NULL,
.config = &lcd_tcon_fw_config,
/* fw resource */
.buf_table_in = NULL,
.buf_table_out = NULL,
/* API */
.vsync_isr = NULL,
.tcon_alg = NULL,
.debug_show = NULL,
.debug_store = NULL,
};
struct lcd_tcon_fw_s *aml_lcd_tcon_get_fw(void)
{
return &lcd_tcon_fw;
}
EXPORT_SYMBOL(aml_lcd_tcon_get_fw);
int lcd_tcon_valid_check(void)
{
if (!lcd_tcon_conf) {
@@ -939,27 +983,6 @@ void lcd_tcon_global_reset(struct aml_lcd_drv_s *pdrv)
}
}
int lcd_tcon_gamma_set_pattern(struct aml_lcd_drv_s *pdrv,
unsigned int bit_width, unsigned int gamma_r,
unsigned int gamma_g, unsigned int gamma_b)
{
int ret;
ret = lcd_tcon_valid_check();
if (ret)
return -1;
if (lcd_tcon_conf->tcon_gamma_pattern) {
ret = lcd_tcon_conf->tcon_gamma_pattern(pdrv,
bit_width, gamma_r,
gamma_g, gamma_b);
LCDPR("%s: %dbits gamma r:0x%x g:0x%x b:0x%x\n",
__func__, bit_width, gamma_r, gamma_g, gamma_b);
}
return ret;
}
int lcd_tcon_core_update(struct aml_lcd_drv_s *pdrv)
{
int ret;
@@ -1004,6 +1027,7 @@ int lcd_tcon_reload(struct aml_lcd_drv_s *pdrv)
int lcd_tcon_enable(struct aml_lcd_drv_s *pdrv)
{
struct lcd_tcon_fw_s *tcon_fw = aml_lcd_tcon_get_fw();
int ret;
ret = lcd_tcon_valid_check();
@@ -1013,11 +1037,14 @@ int lcd_tcon_enable(struct aml_lcd_drv_s *pdrv)
if (lcd_tcon_conf->tcon_enable)
lcd_tcon_conf->tcon_enable(pdrv);
tcon_fw->tcon_state |= TCON_FW_STATE_TCON_EN;
return 0;
}
void lcd_tcon_disable(struct aml_lcd_drv_s *pdrv)
{
struct lcd_tcon_fw_s *tcon_fw = aml_lcd_tcon_get_fw();
unsigned int i;
int ret;
@@ -1027,6 +1054,8 @@ void lcd_tcon_disable(struct aml_lcd_drv_s *pdrv)
LCDPR("%s\n", __func__);
tcon_fw->tcon_state &= ~TCON_FW_STATE_TCON_EN;
/* release data*/
if (tcon_mm_table.version) {
if (tcon_mm_table.init_load == 0) {
@@ -1665,7 +1694,7 @@ static int lcd_tcon_data_multi_set(struct aml_lcd_drv_s *pdrv,
if (lcd_debug_print_flag & LCD_DBG_PR_TEST) {
local_time[0] = sched_clock();
line_cnt = lcd_get_encl_lint_cnt(pdrv);
line_cnt = lcd_get_encl_line_cnt(pdrv);
lcd_tcon_dbg_vsync_time_save(local_time[0], line_cnt, 0);
}
@@ -1678,14 +1707,14 @@ static int lcd_tcon_data_multi_set(struct aml_lcd_drv_s *pdrv,
if (lcd_debug_print_flag & LCD_DBG_PR_TEST) {
local_time[1] = sched_clock();
line_cnt = lcd_get_encl_lint_cnt(pdrv);
line_cnt = lcd_get_encl_line_cnt(pdrv);
lcd_tcon_dbg_vsync_time_save(local_time[1] - local_time[0], line_cnt, 1);
}
lcd_tcon_data_multi_update(pdrv, &tcon_mm_table);
if (lcd_debug_print_flag & LCD_DBG_PR_TEST) {
local_time[2] = sched_clock();
line_cnt = lcd_get_encl_lint_cnt(pdrv);
line_cnt = lcd_get_encl_line_cnt(pdrv);
lcd_tcon_dbg_vsync_time_save(local_time[2] - local_time[0], line_cnt, 2);
}
@@ -1711,7 +1740,7 @@ static int lcd_tcon_data_multi_set(struct aml_lcd_drv_s *pdrv,
}
if (lcd_debug_print_flag & LCD_DBG_PR_TEST) {
local_time[3] = sched_clock();
line_cnt = lcd_get_encl_lint_cnt(pdrv);
line_cnt = lcd_get_encl_line_cnt(pdrv);
temp = (0xf << 12) | (lut_hit << 4) | 3;
lcd_tcon_dbg_vsync_time_save(local_time[3] - local_time[0], line_cnt, temp);
lcd_tcon_time_sort_save(mm_table->vsync_time, (local_time[3] - local_time[0]));
@@ -1722,6 +1751,7 @@ static int lcd_tcon_data_multi_set(struct aml_lcd_drv_s *pdrv,
void lcd_tcon_vsync_isr(struct aml_lcd_drv_s *pdrv)
{
struct lcd_tcon_fw_s *tcon_fw = aml_lcd_tcon_get_fw();
unsigned long flags = 0;
if ((pdrv->status & LCD_STATUS_IF_ON) == 0)
@@ -1736,6 +1766,9 @@ void lcd_tcon_vsync_isr(struct aml_lcd_drv_s *pdrv)
spin_unlock_irqrestore(&tcon_local_cfg.multi_list_lock, flags);
}
}
if (tcon_fw->vsync_isr)
tcon_fw->vsync_isr(tcon_fw);
}
/* **********************************
@@ -3061,6 +3094,8 @@ static int lcd_tcon_get_config(struct aml_lcd_drv_s *pdrv)
lcd_tcon_intr_init(pdrv);
lcd_tcon_fw_prepare(pdrv);
return 0;
}
@@ -3088,6 +3123,81 @@ static void lcd_tcon_get_config_work(struct work_struct *p_work)
lcd_tcon_get_config(pdrv);
}
static void lcd_tcon_fw_prepare(struct aml_lcd_drv_s *pdrv)
{
struct lcd_tcon_fw_s *tcon_fw = aml_lcd_tcon_get_fw();
int i;
if (!tcon_fw || !tcon_fw->config)
return;
if (!lcd_tcon_conf)
return;
switch (pdrv->data->chip_type) {
case LCD_CHIP_TL1:
tcon_fw->config->chip_type = TCON_CHIP_TL1;
break;
case LCD_CHIP_TM2:
case LCD_CHIP_TM2B:
tcon_fw->config->chip_type = TCON_CHIP_TM2;
break;
case LCD_CHIP_T5:
tcon_fw->config->chip_type = TCON_CHIP_T5;
break;
case LCD_CHIP_T5D:
tcon_fw->config->chip_type = TCON_CHIP_T5D;
break;
case LCD_CHIP_T3:
tcon_fw->config->chip_type = TCON_CHIP_T3;
break;
case LCD_CHIP_T5W:
tcon_fw->config->chip_type = TCON_CHIP_T5W;
break;
default:
break;
}
switch (pdrv->config.basic.lcd_type) {
case LCD_MLVDS:
tcon_fw->config->if_type = TCON_IF_MLVDS;
break;
case LCD_P2P:
tcon_fw->config->if_type = TCON_IF_P2P;
break;
default:
break;
}
tcon_fw->config->axi_cnt = lcd_tcon_conf->axi_bank;
if (!tcon_rmem.axi_rmem)
return;
tcon_fw->config->axi_rmem = kcalloc(tcon_fw->config->axi_cnt,
sizeof(struct tcon_fw_axi_rmem_s), GFP_KERNEL);
for (i = 0; i < tcon_fw->config->axi_cnt; i++) {
tcon_fw->config->axi_rmem[i].mem_paddr = tcon_rmem.axi_rmem[i].mem_paddr;
tcon_fw->config->axi_rmem[i].mem_size = tcon_rmem.axi_rmem[i].mem_size;
}
if (pdrv->status & LCD_STATUS_IF_ON)
tcon_fw->tcon_state |= TCON_FW_STATE_TCON_EN;
if (tcon_mm_table.valid_flag & LCD_TCON_DATA_VALID_VAC)
tcon_fw->tcon_state |= TCON_FW_STATE_VAC_VALID;
if (tcon_mm_table.valid_flag & LCD_TCON_DATA_VALID_DEMURA)
tcon_fw->tcon_state |= TCON_FW_STATE_DEMURA_VALID;
if (tcon_mm_table.valid_flag & LCD_TCON_DATA_VALID_ACC)
tcon_fw->tcon_state |= TCON_FW_STATE_ACC_VALID;
if (tcon_mm_table.valid_flag & LCD_TCON_DATA_VALID_DITHER)
tcon_fw->tcon_state |= TCON_FW_STATE_DITHER_VALID;
if (tcon_mm_table.valid_flag & LCD_TCON_DATA_VALID_OD)
tcon_fw->tcon_state |= TCON_FW_STATE_OD_VALID;
if (tcon_mm_table.valid_flag & LCD_TCON_DATA_VALID_LOD)
tcon_fw->tcon_state |= TCON_FW_STATE_LOD_VALID;
tcon_fw->drvdat = (void *)pdrv;
tcon_fw->dev = pdrv->dev;
tcon_fw->valid = 1;
}
/* **********************************
* tcon match data
* **********************************
@@ -3131,7 +3241,6 @@ static struct lcd_tcon_config_s tcon_data_tl1 = {
.tcon_axi_mem_secure = lcd_tcon_axi_mem_secure_tl1,
.tcon_axi_mem_update = NULL,
.tcon_global_reset = NULL,
.tcon_gamma_pattern = lcd_tcon_gamma_pattern_tl1,
.tcon_enable = lcd_tcon_enable_tl1,
.tcon_disable = lcd_tcon_disable_tl1,
.tcon_reload = NULL,
@@ -3177,7 +3286,6 @@ static struct lcd_tcon_config_s tcon_data_t5 = {
.tcon_axi_mem_secure = lcd_tcon_axi_mem_secure_t3,
.tcon_axi_mem_update = lcd_tcon_axi_rmem_update_t5,
.tcon_global_reset = lcd_tcon_global_reset_t5,
.tcon_gamma_pattern = lcd_tcon_gamma_pattern_t5,
.tcon_enable = lcd_tcon_enable_t5,
.tcon_disable = lcd_tcon_disable_t5,
.tcon_reload = NULL,
@@ -3219,7 +3327,6 @@ static struct lcd_tcon_config_s tcon_data_t5d = {
.tcon_axi_mem_secure = lcd_tcon_axi_mem_secure_t3,
.tcon_axi_mem_update = lcd_tcon_axi_rmem_update_t5d,
.tcon_global_reset = lcd_tcon_global_reset_t5,
.tcon_gamma_pattern = lcd_tcon_gamma_pattern_t5,
.tcon_enable = lcd_tcon_enable_t5,
.tcon_disable = lcd_tcon_disable_t5,
.tcon_reload = NULL,
@@ -3265,7 +3372,6 @@ static struct lcd_tcon_config_s tcon_data_t3 = {
.tcon_axi_mem_secure = lcd_tcon_axi_mem_secure_t3,
.tcon_axi_mem_update = lcd_tcon_axi_rmem_update_t5,
.tcon_global_reset = lcd_tcon_global_reset_t3,
.tcon_gamma_pattern = lcd_tcon_gamma_pattern_t5,
.tcon_enable = lcd_tcon_enable_t3,
.tcon_disable = lcd_tcon_disable_t3,
.tcon_reload = lcd_tcon_reload_t3,
@@ -3311,7 +3417,6 @@ static struct lcd_tcon_config_s tcon_data_t5w = {
.tcon_axi_mem_secure = lcd_tcon_axi_mem_secure_t3,
.tcon_axi_mem_update = lcd_tcon_axi_rmem_update_t5,
.tcon_global_reset = lcd_tcon_global_reset_t5,
.tcon_gamma_pattern = lcd_tcon_gamma_pattern_t5,
.tcon_enable = lcd_tcon_enable_t5,
.tcon_disable = lcd_tcon_disable_t5,
.tcon_reload = lcd_tcon_reload_t3,
-3
View File
@@ -52,9 +52,6 @@ struct lcd_tcon_config_s {
void (*tcon_axi_mem_secure)(void);
void (*tcon_axi_mem_update)(unsigned int *table);
void (*tcon_global_reset)(struct aml_lcd_drv_s *pdrv);
int (*tcon_gamma_pattern)(struct aml_lcd_drv_s *pdrv,
unsigned int bit_width, unsigned int gamma_r,
unsigned int gamma_g, unsigned int gamma_b);
int (*tcon_reload_pre)(struct aml_lcd_drv_s *pdrv);
int (*tcon_reload)(struct aml_lcd_drv_s *pdrv);
int (*tcon_enable)(struct aml_lcd_drv_s *pdrv);
-132
View File
@@ -1121,138 +1121,6 @@ void lcd_tcon_global_reset_t3(struct aml_lcd_drv_s *pdrv)
udelay(2);
}
int lcd_tcon_gamma_pattern_tl1(struct aml_lcd_drv_s *pdrv,
unsigned int bit_width, unsigned int gamma_r,
unsigned int gamma_g, unsigned int gamma_b)
{
unsigned int val_r = 0, val_g = 0, val_b = 0, reg;
unsigned char temp[3];
int i;
switch (bit_width) {
case 12:
val_r = gamma_r;
val_g = gamma_g;
val_b = gamma_b;
break;
case 10:
val_r = (gamma_r << 2);
val_g = (gamma_g << 2);
val_b = (gamma_b << 2);
break;
case 8:
val_r = (gamma_r << 4);
val_g = (gamma_g << 4);
val_b = (gamma_b << 4);
break;
default:
LCDERR("gamma_set: invalid bit_width %d\n", bit_width);
return -1;
}
/* enable lut access, disable gamma en*/
lcd_tcon_setb_byte(pdrv, 0x262, 0x2, 0, 2);
/* gamma_r */
/*2 data splice 3 bytes*/
temp[0] = val_r & 0xff;
temp[1] = ((val_r >> 8) & 0xf) | ((val_r & 0xf) << 4);
temp[2] = (val_r >> 4) & 0xff;
reg = 0xb50;
for (i = 0; i < 384; i += 3) { /* 256 * 1.5 */
lcd_tcon_write_byte(pdrv, (reg + i), temp[0]);
lcd_tcon_write_byte(pdrv, (reg + i + 1), temp[1]);
lcd_tcon_write_byte(pdrv, (reg + i + 2), temp[2]);
}
temp[0] = val_r & 0xff;
temp[1] = ((val_r >> 8) & 0xf);
temp[2] = 0;
reg += 384;
lcd_tcon_write_byte(pdrv, (reg), temp[0]);
lcd_tcon_write_byte(pdrv, (reg + 1), temp[1]);
lcd_tcon_write_byte(pdrv, (reg + 2), temp[2]);
/* gamma_g */
/*2 data splice 3 bytes*/
temp[0] = val_g & 0xff;
temp[1] = ((val_g >> 8) & 0xf) | ((val_g & 0xf) << 4);
temp[2] = (val_g >> 4) & 0xff;
reg += 3;
for (i = 0; i < 384; i += 3) { /* 256 * 1.5 */
lcd_tcon_write_byte(pdrv, (reg + i), temp[0]);
lcd_tcon_write_byte(pdrv, (reg + i + 1), temp[1]);
lcd_tcon_write_byte(pdrv, (reg + i + 2), temp[2]);
}
temp[0] = val_g & 0xff;
temp[1] = ((val_g >> 8) & 0xf);
temp[2] = 0;
reg += 384;
lcd_tcon_write_byte(pdrv, (reg), temp[0]);
lcd_tcon_write_byte(pdrv, (reg + 1), temp[1]);
lcd_tcon_write_byte(pdrv, (reg + 2), temp[2]);
/* gamma_b */
/*2 data splice 3 bytes*/
temp[0] = val_b & 0xff;
temp[1] = ((val_b >> 8) & 0xf) | ((val_b & 0xf) << 4);
temp[2] = (val_b >> 4) & 0xff;
reg += 3;
for (i = 0; i < 384; i += 3) { /* 256 * 1.5 */
lcd_tcon_write_byte(pdrv, (reg + i), temp[0]);
lcd_tcon_write_byte(pdrv, (reg + i + 1), temp[1]);
lcd_tcon_write_byte(pdrv, (reg + i + 2), temp[2]);
}
temp[0] = val_b & 0xff;
temp[1] = ((val_b >> 8) & 0xf);
temp[2] = 0;
reg += 384;
lcd_tcon_write_byte(pdrv, (reg), temp[0]);
lcd_tcon_write_byte(pdrv, (reg + 1), temp[1]);
lcd_tcon_write_byte(pdrv, (reg + 2), temp[2]);
/* enable gamma */
lcd_tcon_setb_byte(pdrv, 0x262, 0x3, 0, 2);
return 0;
}
int lcd_tcon_gamma_pattern_t5(struct aml_lcd_drv_s *pdrv,
unsigned int bit_width, unsigned int gamma_r,
unsigned int gamma_g, unsigned int gamma_b)
{
unsigned int val_r = 0, val_g = 0, val_b = 0;
unsigned int temp;
switch (bit_width) {
case 10:
val_r = gamma_r & 0x3ff;
val_g = gamma_g & 0x3ff;
val_b = gamma_b & 0x3ff;
break;
case 8:
val_r = (gamma_r << 2) & 0x3ff;
val_g = (gamma_g << 2) & 0x3ff;
val_b = (gamma_b << 2) & 0x3ff;
break;
default:
LCDERR("gamma_set: invalid bit_width %d\n", bit_width);
return -1;
}
/* gamma calibrate mode */
lcd_tcon_setb(pdrv, 0x222, 1, 13, 1);
lcd_tcon_setb(pdrv, 0x222, 0, 12, 1);
lcd_tcon_setb(pdrv, 0x222, 0, 8, 2);
lcd_tcon_setb(pdrv, 0x201, 1, 31, 1); //test pattern enable
/* gamma pattern */
lcd_tcon_setb(pdrv, 0x201, 0, 26, 4);
temp = (val_r << 0) | (val_g << 10) | (val_b << 20);
lcd_tcon_setb(pdrv, 0x204, temp, 0, 30);
return 0;
}
int lcd_tcon_enable_tl1(struct aml_lcd_drv_s *pdrv)
{
struct lcd_config_s *pconf = &pdrv->config;
+2 -1
View File
@@ -21,7 +21,8 @@ struct lcd_venc_op_s {
void (*mute_set)(struct aml_lcd_drv_s *pdrv, unsigned char flag);
int (*get_venc_init_config)(struct aml_lcd_drv_s *pdrv);
void (*venc_vrr_recovery)(struct aml_lcd_drv_s *pdrv);
unsigned int (*get_encl_lint_cnt)(struct aml_lcd_drv_s *pdrv);
unsigned int (*get_encl_line_cnt)(struct aml_lcd_drv_s *pdrv);
unsigned int (*get_encl_frm_cnt)(struct aml_lcd_drv_s *pdrv);
};
int lcd_venc_op_init_dft(struct aml_lcd_drv_s *pdrv, struct lcd_venc_op_s *venc_op);
@@ -168,7 +168,8 @@ int lcd_venc_op_init_c3(struct aml_lcd_drv_s *pdrv, struct lcd_venc_op_s *venc_o
venc_op->mute_set = lcd_venc_mute_set;
venc_op->get_venc_init_config = lcd_venc_get_init_config;
venc_op->venc_vrr_recovery = NULL;
venc_op->get_encl_lint_cnt = NULL;
venc_op->get_encl_line_cnt = NULL;
venc_op->get_encl_frm_cnt = NULL;
return 0;
};
+12 -4
View File
@@ -389,11 +389,18 @@ static void lcd_venc_set_vrr_recovery(struct aml_lcd_drv_s *pdrv)
lcd_vcbus_write(ENCL_VIDEO_MAX_LNCNT, vtotal);
}
static unsigned int lcd_venc_get_encl_lint_cnt(struct aml_lcd_drv_s *pdrv)
static unsigned int lcd_venc_get_encl_line_cnt(struct aml_lcd_drv_s *pdrv)
{
unsigned int line_cnt = lcd_vcbus_getb(ENCL_INFO_READ, 16, 13);
unsigned int cnt = lcd_vcbus_getb(ENCL_INFO_READ, 16, 13);
return line_cnt;
return cnt;
}
static unsigned int lcd_venc_get_encl_frm_cnt(struct aml_lcd_drv_s *pdrv)
{
unsigned int cnt = lcd_vcbus_getb(ENCL_INFO_READ, 29, 3);
return cnt;
}
int lcd_venc_op_init_dft(struct aml_lcd_drv_s *pdrv, struct lcd_venc_op_s *venc_op)
@@ -411,7 +418,8 @@ int lcd_venc_op_init_dft(struct aml_lcd_drv_s *pdrv, struct lcd_venc_op_s *venc_
venc_op->mute_set = lcd_venc_mute_set;
venc_op->get_venc_init_config = lcd_venc_get_init_config;
venc_op->venc_vrr_recovery = lcd_venc_set_vrr_recovery;
venc_op->get_encl_lint_cnt = lcd_venc_get_encl_lint_cnt;
venc_op->get_encl_line_cnt = lcd_venc_get_encl_line_cnt;
venc_op->get_encl_frm_cnt = lcd_venc_get_encl_frm_cnt;
INIT_WORK(&pdrv->test_check_work, lcd_test_pattern_check);
+25 -8
View File
@@ -30,7 +30,8 @@ static struct lcd_venc_op_s lcd_venc_op = {
.mute_set = NULL,
.get_venc_init_config = NULL,
.venc_vrr_recovery = NULL,
.get_encl_lint_cnt = NULL
.get_encl_line_cnt = NULL,
.get_encl_frm_cnt = NULL,
};
void lcd_wait_vsync(struct aml_lcd_drv_s *pdrv)
@@ -161,19 +162,35 @@ int lcd_get_venc_init_config(struct aml_lcd_drv_s *pdrv)
return ret;
}
unsigned int lcd_get_encl_lint_cnt(struct aml_lcd_drv_s *pdrv)
unsigned int lcd_get_encl_line_cnt(struct aml_lcd_drv_s *pdrv)
{
if (!lcd_venc_op.get_encl_lint_cnt)
unsigned int cnt = 0;
if (!lcd_venc_op.get_encl_line_cnt)
return 0;
int ret = 0;
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL)
if (lcd_debug_print_flag & LCD_DBG_PR_ISR)
LCDPR("[%d]: %s\n", pdrv->index, __func__);
ret = lcd_venc_op.get_encl_lint_cnt(pdrv);
return ret;
cnt = lcd_venc_op.get_encl_line_cnt(pdrv);
return cnt;
}
EXPORT_SYMBOL(lcd_get_encl_line_cnt);
unsigned int lcd_get_encl_frm_cnt(struct aml_lcd_drv_s *pdrv)
{
unsigned int cnt = 0;
if (!lcd_venc_op.get_encl_frm_cnt)
return 0;
if (lcd_debug_print_flag & LCD_DBG_PR_ISR)
LCDPR("[%d]: %s\n", pdrv->index, __func__);
cnt = lcd_venc_op.get_encl_frm_cnt(pdrv);
return cnt;
}
EXPORT_SYMBOL(lcd_get_encl_frm_cnt);
void lcd_venc_vrr_recovery(struct aml_lcd_drv_s *pdrv)
{
+20 -5
View File
@@ -511,9 +511,9 @@ static void lcd_venc_set_vrr_recovery(struct aml_lcd_drv_s *pdrv)
lcd_vcbus_write(ENCL_VIDEO_MAX_LNCNT + offset, vtotal);
}
static unsigned int lcd_venc_get_encl_lint_cnt(struct aml_lcd_drv_s *pdrv)
static unsigned int lcd_venc_get_encl_line_cnt(struct aml_lcd_drv_s *pdrv)
{
unsigned int reg, offset, line_cnt;
unsigned int reg, offset, cnt;
if (!pdrv)
return 0;
@@ -521,8 +521,22 @@ static unsigned int lcd_venc_get_encl_lint_cnt(struct aml_lcd_drv_s *pdrv)
offset = pdrv->data->offset_venc[pdrv->index];
reg = VPU_VENCP_STAT + offset;
line_cnt = lcd_vcbus_getb(reg, 16, 13);
return line_cnt;
cnt = lcd_vcbus_getb(reg, 16, 13);
return cnt;
}
static unsigned int lcd_venc_get_encl_frm_cnt(struct aml_lcd_drv_s *pdrv)
{
unsigned int reg, offset, cnt;
if (!pdrv)
return 0;
offset = pdrv->data->offset_venc[pdrv->index];
reg = VPU_VENCP_STAT + offset;
cnt = lcd_vcbus_getb(reg, 29, 3);
return cnt;
}
int lcd_venc_op_init_t7(struct aml_lcd_drv_s *pdrv, struct lcd_venc_op_s *venc_op)
@@ -540,7 +554,8 @@ int lcd_venc_op_init_t7(struct aml_lcd_drv_s *pdrv, struct lcd_venc_op_s *venc_o
venc_op->mute_set = lcd_venc_mute_set;
venc_op->get_venc_init_config = lcd_venc_get_init_config;
venc_op->venc_vrr_recovery = lcd_venc_set_vrr_recovery;
venc_op->get_encl_lint_cnt = lcd_venc_get_encl_lint_cnt;
venc_op->get_encl_line_cnt = lcd_venc_get_encl_line_cnt;
venc_op->get_encl_frm_cnt = lcd_venc_get_encl_frm_cnt;
return 0;
};
@@ -0,0 +1,91 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#ifndef _INC_AML_LCD_TCON_FW_H
#define _INC_AML_LCD_TCON_FW_H
#include <linux/dma-mapping.h>
#define TCON_FW_PARA_VER 1
enum tcon_fw_chip_e {
TCON_CHIP_TL1 = 0,
TCON_CHIP_TM2, /* 1 */
TCON_CHIP_T5, /* 2 */
TCON_CHIP_T5D, /* 3 */
TCON_CHIP_T3, /* 4 */
TCON_CHIP_T5W, /* 5 */
TCON_CHIP_T5M, /* 6 */
TCON_CHIP_T3X, /* 7 */
TCON_CHIP_TXHD2, /* 8 */
TCON_CHIP_MAX,
};
enum tcon_fw_if_type_e {
TCON_IF_MLVDS = 0,
TCON_IF_P2P,
TCON_IF_TYPE_MAX,
};
struct tcon_fw_axi_rmem_s {
phys_addr_t mem_paddr;
unsigned int mem_size;
};
struct tcon_fw_config_s {
unsigned int config_size;
unsigned int chip_type;
unsigned int if_type;
unsigned char axi_cnt;
struct tcon_fw_axi_rmem_s *axi_rmem;
};
#define TCON_FW_DATA_HEADER_SIZE 32
struct tcon_fw_data_header_s {
unsigned int crc32;
unsigned int data_size;
unsigned char block_cnt;
unsigned char reserved[55];
};
#define TCON_FW_STATE_TCON_EN 0x00000001
#define TCON_FW_STATE_VAC_VALID 0x00000100
#define TCON_FW_STATE_DEMURA_VALID 0x00000200
#define TCON_FW_STATE_DITHER_VALID 0x00000400
#define TCON_FW_STATE_ACC_VALID 0x00001000
#define TCON_FW_STATE_PRE_ACC_VALID 0x00002000
#define TCON_FW_STATE_OD_VALID 0x00010000
#define TCON_FW_STATE_LOD_VALID 0x00100000
struct lcd_tcon_fw_s {
/* init by driver */
unsigned int para_ver;
unsigned int para_size;
unsigned char valid;
unsigned int tcon_state;
/* init by fw */
char fw_ver[20];
unsigned char flag;
unsigned int dbg_level;
/* driver resource */
void *drvdat;
struct device *dev;
struct tcon_fw_config_s *config;
/* fw resource */
unsigned char *buf_table_in;
unsigned char *buf_table_out;
/* API */
int (*vsync_isr)(struct lcd_tcon_fw_s *fw);
int (*tcon_alg)(struct lcd_tcon_fw_s *fw, unsigned int flag);
ssize_t (*debug_show)(struct lcd_tcon_fw_s *fw, char *buf);
int (*debug_store)(struct lcd_tcon_fw_s *fw, const char *buf);
};
struct lcd_tcon_fw_s *aml_lcd_tcon_get_fw(void);
#endif /* _INC_AML_LCD_TCON_FW_H */