lcd: update display mode management [2/2]

PD#SWPL-152929

Problem:
need update lcd display mode management

Solution:
update lcd display mode management

Verify:
ay301, bc302

Change-Id: I62470ca5f65c4a70c6de6cec6712a43609ff170e
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
This commit is contained in:
Evoke Zhang
2024-01-18 13:15:16 +08:00
committed by gerrit autosubmit
parent 146775df1c
commit f01bbd554d
11 changed files with 506 additions and 938 deletions
+23 -8
View File
@@ -2368,14 +2368,14 @@ static int lcd_config_load_from_dts(struct aml_lcd_drv_s *pdrv)
return ret;
}
static int lcd_config_load_from_unifykey_v2(struct lcd_config_s *pconf,
static int lcd_config_load_from_unifykey_v2(struct aml_lcd_drv_s *pdrv,
unsigned char *p,
unsigned int key_len,
unsigned int offset)
{
struct aml_lcd_unifykey_header_s *lcd_header;
struct phy_config_s *phy_cfg = &pconf->phy_cfg;
struct cus_ctrl_config_s *cus_ctrl = &pconf->cus_ctrl;
struct phy_config_s *phy_cfg = &pdrv->config.phy_cfg;
struct cus_ctrl_config_s *cus_ctrl = &pdrv->config.cus_ctrl;
unsigned int temp, len;
int i, ret;
@@ -2448,7 +2448,7 @@ static int lcd_config_load_from_unifykey_v2(struct lcd_config_s *pconf,
((*(p + LCD_UKEY_CUS_CTRL_ATTR_FLAG + 1)) << 8) |
((*(p + LCD_UKEY_CUS_CTRL_ATTR_FLAG + 2)) << 16) |
((*(p + LCD_UKEY_CUS_CTRL_ATTR_FLAG + 3)) << 24));
if (lcd_debug_print_flag)
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL)
LCDPR("%s: cus_ctrl_flag=0x%x\n", __func__, cus_ctrl->flag);
if (cus_ctrl->flag & 0x1) {
@@ -2473,6 +2473,21 @@ static int lcd_config_load_from_unifykey_v2(struct lcd_config_s *pconf,
LCDPR("%s: cus_ctrl attr_0_para1=%d\n",
__func__, cus_ctrl->attr_0_para1);
}
memcpy(&cus_ctrl->dft_timing, &pdrv->config.timing.dft_timing,
sizeof(struct lcd_detail_timing_s));
cus_ctrl->dft_timing.v_active /= 2;
cus_ctrl->dft_timing.v_period /= 2;
cus_ctrl->dft_timing.frame_rate *= 2;
temp = cus_ctrl->dft_timing.v_period - cus_ctrl->dft_timing.v_active -
cus_ctrl->dft_timing.vsync_width - cus_ctrl->dft_timing.vsync_bp;
cus_ctrl->dft_timing.vsync_fp = temp;
cus_ctrl->dft_timing.v_period_min = cus_ctrl->attr_0_para0;
cus_ctrl->dft_timing.v_period_max = cus_ctrl->attr_0_para1;
cus_ctrl->dft_timing.frame_rate_min = 0;
cus_ctrl->dft_timing.frame_rate_max = 0;
lcd_fr_range_update(&cus_ctrl->dft_timing);
}
return 0;
@@ -2773,7 +2788,7 @@ static int lcd_config_load_from_unifykey(struct aml_lcd_drv_s *pdrv, char *key_s
if (lcd_header.version == 2) {
p = para + lcd_header.block_cur_size;
lcd_config_load_from_unifykey_v2(pconf, p, key_len, lcd_header.block_cur_size);
lcd_config_load_from_unifykey_v2(pdrv, p, key_len, lcd_header.block_cur_size);
}
kfree(para);
@@ -2999,7 +3014,7 @@ void lcd_p2p_bit_rate_config(struct aml_lcd_drv_s *pdrv)
clk_mode = pconf->timing.clk_mode;
switch (p2p_type) {
case P2P_CEDS:
case P2P_EPI:
case P2P_EPI: /*24to28*/
if (clk_mode == LCD_CLK_MODE_DEPENDENCE)
band_width = band_width * 3 * lcd_bits;
else //independence & dependence_adapt
@@ -3010,7 +3025,7 @@ void lcd_p2p_bit_rate_config(struct aml_lcd_drv_s *pdrv)
break;
case P2P_CSPI:
case P2P_ISP:
case P2P_CMPI:
case P2P_CMPI: /*24to27*/
if (clk_mode == LCD_CLK_MODE_DEPENDENCE) {
band_width = band_width * 3 * lcd_bits;
} else { //independence & dependence_adapt
@@ -3018,7 +3033,7 @@ void lcd_p2p_bit_rate_config(struct aml_lcd_drv_s *pdrv)
band_width = lcd_do_div((band_width * 3 * lcd_bits * 9), 8);
}
break;
case P2P_USIT:
case P2P_USIT: /*9to10*/
if (clk_mode == LCD_CLK_MODE_DEPENDENCE)
band_width = band_width * 3 * lcd_bits;
else //independence & dependence_adapt
+2 -1
View File
@@ -56,7 +56,8 @@
/* 20231205: add lcd config check*/
/* 20231218: update timing management*/
/* 20240118: MIPI DSI arch adjust*/
#define LCD_DRV_VERSION "20240118"
/* 20240129: update display mode management*/
#define LCD_DRV_VERSION "20240129"
extern struct mutex lcd_vout_mutex;
extern spinlock_t lcd_reg_spinlock;
+76 -350
View File
@@ -24,10 +24,8 @@
#include <linux/component.h>
#include <drm/amlogic/meson_drm_bind.h>
static int meson_lcd_bind(struct device *dev,
struct device *master, void *data);
static void meson_lcd_unbind(struct device *dev,
struct device *master, void *data);
static int meson_lcd_bind(struct device *dev, struct device *master, void *data);
static void meson_lcd_unbind(struct device *dev, struct device *master, void *data);
struct drm_lcd_wrapper {
struct meson_panel_dev drm_lcd_instance;
@@ -40,171 +38,18 @@ struct drm_lcd_wrapper {
static struct drm_lcd_wrapper drm_lcd_wrappers[LCD_MAX_DRV];
static struct drm_display_mode tv_lcd_mode_ref[] = {
{ /* 600p */
.name = "600p",
.status = 0,
.clock = 40234,
.hdisplay = 1024,
.hsync_start = 1026,
.hsync_end = 1034,
.htotal = 1056,
.hskew = 0,
.vdisplay = 600,
.vsync_start = 624,
.vsync_end = 630,
.vtotal = 635,
.vscan = 0,
//.vrefresh = 60,
},
{ /* 768p */
.name = "768p",
.status = 0,
.clock = 75442,
.hdisplay = 1366,
.hsync_start = 1390,
.hsync_end = 1430,
.htotal = 1560,
.hskew = 0,
.vdisplay = 768,
.vsync_start = 773,
.vsync_end = 788,
.vtotal = 806,
.vscan = 0,
//.vrefresh = 60,
},
{ /* 1080p */
.name = "1080p",
.status = 0,
.clock = 148500,
.hdisplay = 1920,
.hsync_start = 1930,
.hsync_end = 1970,
.htotal = 2200,
.hskew = 0,
.vdisplay = 1080,
.vsync_start = 1090,
.vsync_end = 1100,
.vtotal = 1125,
.vscan = 0,
//.vrefresh = 60,
},
{ /* 2160p */
.name = "2160p",
.status = 0,
.clock = 594000,
.hdisplay = 3840,
.hsync_start = 4000,
.hsync_end = 4060,
.htotal = 4400,
.hskew = 0,
.vdisplay = 2160,
.vsync_start = 2200,
.vsync_end = 2210,
.vtotal = 2250,
.vscan = 0,
//.vrefresh = 60,
},
{ /* 3840x1080p120hz */
.name = "3840x1080p",
.status = 0,
.clock = 594000,
.hdisplay = 3840,
.hsync_start = 4000,
.hsync_end = 4060,
.htotal = 4400,
.hskew = 0,
.vdisplay = 1080,
.vsync_start = 1100,
.vsync_end = 1105,
.vtotal = 1125,
.vscan = 0,
//.vrefresh = 120,
},
{ /* 3840x2160p120/144hz */
.name = "3840x2160p",
.status = 0,
.clock = 1188000,
.hdisplay = 3840,
.hsync_start = 4000,
.hsync_end = 4060,
.htotal = 4400,
.hskew = 0,
.vdisplay = 2160,
.vsync_start = 2200,
.vsync_end = 2210,
.vtotal = 2250,
.vscan = 0,
//.vrefresh = 120,
},
{ /* invalid */
.name = "invalid",
.status = 0,
.clock = 148500,
.hdisplay = 1920,
.hsync_start = 1930,
.hsync_end = 1970,
.htotal = 2200,
.hskew = 0,
.vdisplay = 1080,
.vsync_start = 1090,
.vsync_end = 1100,
.vtotal = 1125,
.vscan = 0,
//.vrefresh = 60,
},
};
static unsigned int lcd_std_frame_rate[] = {
60,
59,
50,
48,
47,
0
};
static unsigned int lcd_std_frame_rate_high[] = {
288,
240,
144,
120,
119,
100,
96,
95,
0
};
static unsigned int lcd_drm_vmode_get_valid_num(struct aml_lcd_drv_s *pdrv,
unsigned int *fr_table, unsigned int cnt)
static void lcd_drm_vmode_update(struct aml_lcd_drv_s *pdrv, struct lcd_detail_timing_s *ptiming,
struct drm_display_mode *pmode, unsigned int frame_rate)
{
unsigned int i, num = 0;
for (i = 0; i < cnt; i++) {
if (fr_table[i] == 0)
break;
if (fr_table[i] > pdrv->config.timing.base_timing.frame_rate)
continue;
num++;
}
return num;
}
static void lcd_drm_vmode_update(struct aml_lcd_drv_s *pdrv, struct drm_display_mode *mode,
unsigned int frame_rate)
{
struct lcd_config_s *pconf = &pdrv->config;
unsigned int pclk = pconf->timing.base_timing.pixel_clk;
unsigned int htotal = pconf->timing.base_timing.h_period;
unsigned int vtotal = pconf->timing.base_timing.v_period;
unsigned int pclk = ptiming->pixel_clk;
unsigned int htotal = ptiming->h_period;
unsigned int vtotal = ptiming->v_period;
unsigned long long temp;
if (!mode)
if (!pmode)
return;
switch (pconf->timing.base_timing.fr_adjust_type) {
switch (ptiming->fr_adjust_type) {
case 0: /* pixel clk adjust */
pclk = frame_rate * htotal * vtotal;
break;
@@ -230,20 +75,20 @@ static void lcd_drm_vmode_update(struct aml_lcd_drv_s *pdrv, struct drm_display_
vtotal = htotal * frame_rate;
vtotal = lcd_do_div(temp, vtotal);
vtotal = (vtotal + 99) / 100; /* round off */
if (vtotal > pconf->timing.base_timing.v_period_max) {
vtotal = pconf->timing.base_timing.v_period_max;
if (vtotal > ptiming->v_period_max) {
vtotal = ptiming->v_period_max;
htotal = vtotal * frame_rate;
htotal = lcd_do_div(temp, htotal);
htotal = (htotal + 99) / 100; /* round off */
if (htotal > pconf->timing.base_timing.h_period_max)
htotal = pconf->timing.base_timing.h_period_max;
} else if (vtotal < pconf->timing.base_timing.v_period_min) {
vtotal = pconf->timing.base_timing.v_period_min;
if (htotal > ptiming->h_period_max)
htotal = ptiming->h_period_max;
} else if (vtotal < ptiming->v_period_min) {
vtotal = ptiming->v_period_min;
htotal = vtotal * frame_rate;
htotal = lcd_do_div(temp, htotal);
htotal = (htotal + 99) / 100; /* round off */
if (htotal < pconf->timing.base_timing.h_period_min)
htotal = pconf->timing.base_timing.h_period_min;
if (htotal < ptiming->h_period_min)
htotal = ptiming->h_period_min;
}
pclk = frame_rate * htotal * vtotal;
break;
@@ -279,106 +124,43 @@ static void lcd_drm_vmode_update(struct aml_lcd_drv_s *pdrv, struct drm_display_
break;
default:
LCDERR("[%d]: %s: invalid fr_adjust_type: %d\n",
pdrv->index, __func__, pconf->timing.base_timing.fr_adjust_type);
pdrv->index, __func__, ptiming->fr_adjust_type);
return;
}
mode->clock = pclk / 1000;
mode->htotal = htotal;
mode->vtotal = vtotal;
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL) {
LCDPR("[%d]: %s: %s, clock=%d, htotal=%d, vtotal=%d\n",
pdrv->index, __func__, mode->name, mode->clock,
mode->htotal, mode->vtotal);
}
pmode->clock = pclk / 1000;
pmode->htotal = htotal;
pmode->vtotal = vtotal;
}
static int lcd_drm_update_hsr_mode(struct aml_lcd_drv_s *pdrv,
struct drm_display_mode **modes,
struct drm_display_mode *nmodes,
struct drm_display_mode *native_mode,
int hsr_flag)
static void lcd_drm_display_mode_add(struct aml_lcd_drv_s *pdrv,
struct lcd_detail_timing_s *ptiming,
struct drm_display_mode *pmode, unsigned short frame_rate)
{
int mode_idx, i, num_0 = 0, num_1 = 0;
unsigned int *fr_table = NULL;
unsigned short tmp;
num_0 = ARRAY_SIZE(lcd_std_frame_rate);
num_1 = ARRAY_SIZE(lcd_std_frame_rate_high);
if (hsr_flag) {
mode_idx = 0;
fr_table = lcd_std_frame_rate_high;
//support 3840x1080p240 or 288 hz
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL)
LCDPR("[%d]: %s add HSR mode\n", pdrv->index, __func__);
native_mode = &tv_lcd_mode_ref[4];
for (i = 0; i < num_1; i++) {
if (fr_table[i] == 0)
break;
if (fr_table[i] < 240)
continue;
if (mode_idx >= 10)
break;
memcpy(&nmodes[mode_idx], native_mode, sizeof(struct drm_display_mode));
memset(nmodes[mode_idx].name, 0, DRM_DISPLAY_MODE_LEN);
sprintf(nmodes[mode_idx].name, "%s%dhz", native_mode->name, fr_table[i]);
//nmodes[mode_idx].vrefresh = fr_table[j];
lcd_drm_vmode_update(pdrv, &nmodes[mode_idx], fr_table[i]);
mode_idx++;
}
native_mode = &tv_lcd_mode_ref[5];
for (i = 0; i < num_1; i++) {
if (fr_table[i] == 0)
break;
if (fr_table[i] > 144)
continue;
if (mode_idx >= 10)
break;
memcpy(&nmodes[mode_idx], native_mode, sizeof(struct drm_display_mode));
memset(nmodes[mode_idx].name, 0, DRM_DISPLAY_MODE_LEN);
sprintf(nmodes[mode_idx].name, "%s%dhz", native_mode->name, fr_table[i]);
//nmodes[mode_idx].vrefresh = fr_table[j];
lcd_drm_vmode_update(pdrv, &nmodes[mode_idx], fr_table[i]);
mode_idx++;
}
*modes = nmodes;
return 0;
}
pmode->clock = ptiming->pixel_clk / 1000;
pmode->hdisplay = ptiming->h_active;
tmp = ptiming->h_period - ptiming->hsync_width - ptiming->hsync_bp;
pmode->hsync_start = tmp;
pmode->hsync_end = ptiming->hsync_width + tmp;
pmode->htotal = ptiming->h_period;
pmode->vdisplay = ptiming->v_active;
tmp = ptiming->v_period - ptiming->vsync_width - ptiming->vsync_bp;
pmode->vsync_start = tmp;
pmode->vsync_end = ptiming->vsync_width + tmp;
pmode->vtotal = ptiming->v_period;
pmode->width_mm = pdrv->config.basic.screen_width;
pmode->height_mm = pdrv->config.basic.screen_height;
mode_idx = 0;
fr_table = lcd_std_frame_rate;
native_mode = &tv_lcd_mode_ref[3];
for (i = 0; i < num_0; i++) {
if (fr_table[i] == 0)
break;
memcpy(&nmodes[mode_idx], native_mode, sizeof(struct drm_display_mode));
memset(nmodes[mode_idx].name, 0, DRM_DISPLAY_MODE_LEN);
sprintf(nmodes[mode_idx].name, "%s%dhz",
native_mode->name, fr_table[i]);
//nmodes[mode_idx].vrefresh = fr_table[i];
lcd_drm_vmode_update(pdrv, &nmodes[mode_idx], fr_table[i]);
mode_idx++;
}
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL)
LCDPR("[%d]: %s add dlg mode\n", pdrv->index, __func__);
fr_table = lcd_std_frame_rate_high;
native_mode = &tv_lcd_mode_ref[4];
for (i = 0; i < num_1; i++) {
if (fr_table[i] == 0)
break;
if (fr_table[i] > 120)
continue;
if (mode_idx >= 10)
break;
memcpy(&nmodes[mode_idx], native_mode, sizeof(struct drm_display_mode));
memset(nmodes[mode_idx].name, 0, DRM_DISPLAY_MODE_LEN);
sprintf(nmodes[mode_idx].name, "%s%dhz", native_mode->name, fr_table[i]);
//nmodes[mode_idx].vrefresh = fr_table[j];
lcd_drm_vmode_update(pdrv, &nmodes[mode_idx], fr_table[i]);
mode_idx++;
}
*modes = nmodes;
if (frame_rate != ptiming->frame_rate)
lcd_drm_vmode_update(pdrv, ptiming, pmode, frame_rate);
return 0;
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL) {
LCDPR("[%d]: %s: %s, clock=%d, htotal=%d, vtotal=%d\n",
pdrv->index, __func__, pmode->name, pmode->clock,
pmode->htotal, pmode->vtotal);
}
}
static int get_lcd_tv_modes(struct meson_panel_dev *panel,
@@ -386,109 +168,46 @@ static int get_lcd_tv_modes(struct meson_panel_dev *panel,
{
struct drm_lcd_wrapper *wrapper = to_drm_lcd_wrapper(panel);
struct aml_lcd_drv_s *pdrv = wrapper->lcd_drv;
struct drm_display_mode *native_mode;
struct drm_display_mode *nmodes;
unsigned int *fr_table;
int i, num_0, num_1, cnt, mode_idx;
int find_high = 0, hsr_flag = 0;
if (!pdrv)
return -ENODEV;
struct lcd_vmode_list_s *temp_list;
struct lcd_detail_timing_s *ptiming;
unsigned int i, frame_rate, mode_cnt = 0, mode_idx;
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL)
LCDPR("[%d]: %s\n", pdrv->index, __func__);
switch (pdrv->config.timing.base_timing.v_active) {
case 600:
native_mode = &tv_lcd_mode_ref[0];
break;
case 768:
native_mode = &tv_lcd_mode_ref[1];
break;
case 1080:
if (pdrv->config.timing.base_timing.h_active == 3840) {
if (pdrv->config.timing.base_timing.frame_rate == 240 ||
pdrv->config.timing.base_timing.frame_rate == 288) {
find_high = 1;
hsr_flag = 1;
} else if (pdrv->config.timing.base_timing.frame_rate == 120) {
find_high = 1;
}
native_mode = &tv_lcd_mode_ref[4];
} else {
native_mode = &tv_lcd_mode_ref[2];
}
break;
case 2160:
if (pdrv->config.timing.base_timing.frame_rate == 120 ||
pdrv->config.timing.base_timing.frame_rate == 144) {
find_high = 1;
hsr_flag = 1;
native_mode = &tv_lcd_mode_ref[5];
} else {
native_mode = &tv_lcd_mode_ref[3];
}
break;
default:
native_mode = &tv_lcd_mode_ref[5];
LCDERR("[%d]: %s: invalid lcd mode\n", pdrv->index, __func__);
break;
}
if (strstr(native_mode->name, "invalid")) {
*num = 0;
return -ENODEV;
}
num_0 = ARRAY_SIZE(lcd_std_frame_rate);
num_1 = ARRAY_SIZE(lcd_std_frame_rate_high);
if (pdrv->config.cus_ctrl.ufr_flag) {
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL)
LCDPR("%s, ufr_flag = %d, hsr_flag: %d\n",
__func__, pdrv->config.cus_ctrl.ufr_flag, hsr_flag);
*num = 10;
nmodes = kmalloc_array(*num, sizeof(struct drm_display_mode), GFP_KERNEL);
if (!nmodes) {
*num = 0;
return -ENOMEM;
}
lcd_drm_update_hsr_mode(pdrv, modes, nmodes, native_mode,
hsr_flag);
if (!pdrv || !pdrv->vmode_mgr.vmode_list_header)
return 0;
}
if (find_high) {
fr_table = lcd_std_frame_rate_high;
cnt = num_1;
} else {
fr_table = lcd_std_frame_rate;
cnt = num_0;
}
*num = lcd_drm_vmode_get_valid_num(pdrv, fr_table, cnt);
nmodes = kmalloc_array(*num, sizeof(struct drm_display_mode), GFP_KERNEL);
mode_cnt = pdrv->vmode_mgr.vmode_cnt;
nmodes = kcalloc(mode_cnt, sizeof(struct drm_display_mode), GFP_KERNEL);
if (!nmodes) {
*num = 0;
return -ENOMEM;
}
mode_idx = 0;
for (i = 0; i < cnt; i++) {
if (fr_table[i] == 0)
break;
if (fr_table[i] > pdrv->config.timing.base_timing.frame_rate)
temp_list = pdrv->vmode_mgr.vmode_list_header;
while (temp_list) {
if (!temp_list->info || !temp_list->info->dft_timing)
continue;
if (mode_idx >= *num)
break;
memcpy(&nmodes[mode_idx], native_mode, sizeof(struct drm_display_mode));
memset(nmodes[mode_idx].name, 0, DRM_DISPLAY_MODE_LEN);
sprintf(nmodes[mode_idx].name, "%s%dhz", native_mode->name, fr_table[i]);
//nmodes[mode_idx].vrefresh = fr_table[i];
lcd_drm_vmode_update(pdrv, &nmodes[mode_idx], fr_table[i]);
mode_idx++;
ptiming = temp_list->info->dft_timing;
for (i = 0; i < temp_list->info->duration_cnt; i++) {
frame_rate = temp_list->info->duration[i].frame_rate;
if (frame_rate == 0)
break;
memset(nmodes[mode_idx].name, 0, DRM_DISPLAY_MODE_LEN);
sprintf(nmodes[mode_idx].name, "%s%dhz",
temp_list->info->name, frame_rate);
lcd_drm_display_mode_add(pdrv, ptiming, &nmodes[mode_idx], frame_rate);
mode_idx++;
}
temp_list = temp_list->next;
}
*num = mode_idx;
*modes = nmodes;
return 0;
@@ -536,6 +255,13 @@ static int get_lcd_tablet_modes(struct meson_panel_dev *panel,
//mode->vrefresh = ptiming->sync_duration_num/
//ptiming->sync_duration_den;
if (lcd_debug_print_flag & LCD_DBG_PR_NORMAL) {
LCDPR("[%d]: %s: %s, clock=%d, htotal=%d, vtotal=%d, %dx%d@%dhz\n",
pdrv->index, __func__, mode->name, mode->clock,
mode->htotal, mode->vtotal,
mode->hdisplay, mode->vdisplay, ptiming->frame_rate);
}
return 0;
}
+9 -10
View File
@@ -110,6 +110,7 @@ static int lcd_set_current_vmode(enum vmode_e mode, void *data)
lcd_if_enable_retry(pdrv);
}
pdrv->vmode_switch = 0;
pdrv->status |= LCD_STATUS_VMODE_ACTIVE;
mutex_unlock(&lcd_power_mutex);
@@ -275,10 +276,14 @@ static int lcd_set_vframe_rate_hint(int duration, void *data)
}
/* update frame rate */
pdrv->config.timing.act_timing.frame_rate = pdrv->cur_duration.frame_rate;
pdrv->config.timing.act_timing.sync_duration_num = pdrv->cur_duration.duration_num;
pdrv->config.timing.act_timing.sync_duration_den = pdrv->cur_duration.duration_den;
pdrv->config.timing.act_timing.frac = pdrv->cur_duration.frac;
pdrv->config.timing.act_timing.frame_rate =
pdrv->config.timing.base_timing.frame_rate;
pdrv->config.timing.act_timing.sync_duration_num =
pdrv->config.timing.base_timing.sync_duration_num;
pdrv->config.timing.act_timing.sync_duration_den =
pdrv->config.timing.base_timing.sync_duration_den;
pdrv->config.timing.act_timing.frac =
pdrv->config.timing.base_timing.frac;
pdrv->fr_mode = 0;
} else {
for (i = 0; i < n; i++) {
@@ -418,12 +423,6 @@ static void lcd_tablet_vinfo_update(struct aml_lcd_drv_s *pdrv)
ptiming = &pdrv->config.timing.act_timing;
/* store current duration */
pdrv->cur_duration.frame_rate = ptiming->frame_rate;
pdrv->cur_duration.duration_num = ptiming->sync_duration_num;
pdrv->cur_duration.duration_den = ptiming->sync_duration_den;
pdrv->cur_duration.frac = ptiming->frac;
pdrv->vinfo.width = ptiming->h_active;
pdrv->vinfo.height = ptiming->v_active;
pdrv->vinfo.field_height = ptiming->v_active;
-1
View File
@@ -209,7 +209,6 @@ int lcd_tv_driver_change(struct aml_lcd_drv_s *pdrv)
if (ret)
return -1;
lcd_frame_rate_change(pdrv);
#ifdef CONFIG_AMLOGIC_VPU
vpu_dev_clk_request(pdrv->lcd_vpu_dev, pdrv->config.timing.enc_clk);
#endif
File diff suppressed because it is too large Load Diff
+5 -14
View File
@@ -327,7 +327,7 @@ static void lcd_venc_change_timing(struct aml_lcd_drv_s *pdrv)
{
unsigned int htotal, vtotal;
if (pdrv->vmode_update) {
if (pdrv->vmode_switch) {
lcd_venc_set_timing(pdrv);
} else {
htotal = lcd_vcbus_read(ENCL_VIDEO_MAX_PXCNT) + 1;
@@ -381,21 +381,12 @@ static int lcd_venc_get_init_config(struct aml_lcd_drv_s *pdrv)
struct lcd_config_s *pconf = &pdrv->config;
unsigned int init_state;
pconf->timing.dft_timing.h_active = lcd_vcbus_read(ENCL_VIDEO_HAVON_END)
pconf->timing.act_timing.h_active = lcd_vcbus_read(ENCL_VIDEO_HAVON_END)
- lcd_vcbus_read(ENCL_VIDEO_HAVON_BEGIN) + 1;
pconf->timing.dft_timing.v_active = lcd_vcbus_read(ENCL_VIDEO_VAVON_ELINE)
pconf->timing.act_timing.v_active = lcd_vcbus_read(ENCL_VIDEO_VAVON_ELINE)
- lcd_vcbus_read(ENCL_VIDEO_VAVON_BLINE) + 1;
pconf->timing.dft_timing.h_period = lcd_vcbus_read(ENCL_VIDEO_MAX_PXCNT) + 1;
pconf->timing.dft_timing.v_period = lcd_vcbus_read(ENCL_VIDEO_MAX_LNCNT) + 1;
pconf->timing.base_timing.h_active = pconf->timing.dft_timing.h_active;
pconf->timing.act_timing.h_active = pconf->timing.dft_timing.h_active;
pconf->timing.base_timing.v_active = pconf->timing.dft_timing.v_active;
pconf->timing.act_timing.v_active = pconf->timing.dft_timing.v_active;
pconf->timing.base_timing.h_period = pconf->timing.dft_timing.h_period;
pconf->timing.act_timing.h_period = pconf->timing.dft_timing.h_period;
pconf->timing.base_timing.v_period = pconf->timing.dft_timing.v_period;
pconf->timing.act_timing.v_period = pconf->timing.dft_timing.v_period;
pconf->timing.act_timing.h_period = lcd_vcbus_read(ENCL_VIDEO_MAX_PXCNT) + 1;
pconf->timing.act_timing.v_period = lcd_vcbus_read(ENCL_VIDEO_MAX_LNCNT) + 1;
lcd_venc_gamma_check_en(pdrv);
+5 -14
View File
@@ -458,7 +458,7 @@ static void lcd_venc_change_timing(struct aml_lcd_drv_s *pdrv)
ppc = pdrv->config.timing.ppc;
htotal = (lcd_vcbus_getb(ENCL_VIDEO_MAX_CNT + offset, 16, 16) + 1) * ppc;
if (pdrv->vmode_update) {
if (pdrv->vmode_switch) {
lcd_venc_set_timing(pdrv);
} else if (pdrv->config.basic.lcd_type == LCD_VBYONE &&
pdrv->config.timing.act_timing.h_period != htotal) {
@@ -514,23 +514,14 @@ static int lcd_venc_get_init_config(struct aml_lcd_drv_s *pdrv)
size = lcd_vcbus_getb(ENCL_VIDEO_HAVON_PX_RNG + offset, 0, 16)
- lcd_vcbus_getb(ENCL_VIDEO_HAVON_PX_RNG + offset, 16, 16) + 1;
pconf->timing.dft_timing.h_active = size * ppc;
pconf->timing.act_timing.h_active = size * ppc;
size = lcd_vcbus_getb(ENCL_VIDEO_VAVON_LN_RNG + offset, 0, 16)
- lcd_vcbus_getb(ENCL_VIDEO_VAVON_LN_RNG + offset, 16, 16) + 1;
pconf->timing.dft_timing.v_active = size;
pconf->timing.act_timing.v_active = size;
size = lcd_vcbus_getb(ENCL_VIDEO_MAX_CNT + offset, 16, 16) + 1;
pconf->timing.dft_timing.h_period = size * ppc;
pconf->timing.act_timing.h_period = size * ppc;
size = lcd_vcbus_getb(ENCL_VIDEO_MAX_CNT + offset, 0, 16) + 1;
pconf->timing.dft_timing.v_period = size;
pconf->timing.base_timing.h_active = pconf->timing.dft_timing.h_active;
pconf->timing.act_timing.h_active = pconf->timing.dft_timing.h_active;
pconf->timing.base_timing.v_active = pconf->timing.dft_timing.v_active;
pconf->timing.act_timing.v_active = pconf->timing.dft_timing.v_active;
pconf->timing.base_timing.h_period = pconf->timing.dft_timing.h_period;
pconf->timing.act_timing.h_period = pconf->timing.dft_timing.h_period;
pconf->timing.base_timing.v_period = pconf->timing.dft_timing.v_period;
pconf->timing.act_timing.v_period = pconf->timing.dft_timing.v_period;
pconf->timing.act_timing.v_period = size;
lcd_venc_gamma_check_en(pdrv);
+5 -14
View File
@@ -434,7 +434,7 @@ static void lcd_venc_change_timing(struct aml_lcd_drv_s *pdrv)
offset = pdrv->data->offset_venc[pdrv->index];
if (pdrv->vmode_update) {
if (pdrv->vmode_switch) {
lcd_venc_set_timing(pdrv);
} else {
htotal = lcd_vcbus_read(ENCL_VIDEO_MAX_PXCNT + offset) + 1;
@@ -498,21 +498,12 @@ static int lcd_venc_get_init_config(struct aml_lcd_drv_s *pdrv)
offset = pdrv->data->offset_venc[pdrv->index];
pconf->timing.dft_timing.h_active = lcd_vcbus_read(ENCL_VIDEO_HAVON_END + offset)
pconf->timing.act_timing.h_active = lcd_vcbus_read(ENCL_VIDEO_HAVON_END + offset)
- lcd_vcbus_read(ENCL_VIDEO_HAVON_BEGIN + offset) + 1;
pconf->timing.dft_timing.v_active = lcd_vcbus_read(ENCL_VIDEO_VAVON_ELINE + offset)
pconf->timing.act_timing.v_active = lcd_vcbus_read(ENCL_VIDEO_VAVON_ELINE + offset)
- lcd_vcbus_read(ENCL_VIDEO_VAVON_BLINE + offset) + 1;
pconf->timing.dft_timing.h_period = lcd_vcbus_read(ENCL_VIDEO_MAX_PXCNT + offset) + 1;
pconf->timing.dft_timing.v_period = lcd_vcbus_read(ENCL_VIDEO_MAX_LNCNT + offset) + 1;
pconf->timing.base_timing.h_active = pconf->timing.dft_timing.h_active;
pconf->timing.act_timing.h_active = pconf->timing.dft_timing.h_active;
pconf->timing.base_timing.v_active = pconf->timing.dft_timing.v_active;
pconf->timing.act_timing.v_active = pconf->timing.dft_timing.v_active;
pconf->timing.base_timing.h_period = pconf->timing.dft_timing.h_period;
pconf->timing.act_timing.h_period = pconf->timing.dft_timing.h_period;
pconf->timing.base_timing.v_period = pconf->timing.dft_timing.v_period;
pconf->timing.act_timing.v_period = pconf->timing.dft_timing.v_period;
pconf->timing.act_timing.h_period = lcd_vcbus_read(ENCL_VIDEO_MAX_PXCNT + offset) + 1;
pconf->timing.act_timing.v_period = lcd_vcbus_read(ENCL_VIDEO_MAX_LNCNT + offset) + 1;
lcd_venc_gamma_check_en(pdrv);
+11
View File
@@ -1809,6 +1809,15 @@ static void lcd_config_default(struct aml_lcd_drv_s *pdrv)
pdrv->init_flag = 0;
init_state = lcd_get_venc_init_config(pdrv);
pdrv->config.timing.base_timing.h_active = pdrv->config.timing.act_timing.h_active;
pdrv->config.timing.dft_timing.h_active = pdrv->config.timing.act_timing.h_active;
pdrv->config.timing.base_timing.v_active = pdrv->config.timing.act_timing.v_active;
pdrv->config.timing.dft_timing.v_active = pdrv->config.timing.act_timing.v_active;
pdrv->config.timing.base_timing.h_period = pdrv->config.timing.act_timing.h_period;
pdrv->config.timing.dft_timing.h_period = pdrv->config.timing.act_timing.h_period;
pdrv->config.timing.base_timing.v_period = pdrv->config.timing.act_timing.v_period;
pdrv->config.timing.dft_timing.v_period = pdrv->config.timing.act_timing.v_period;
if (init_state) {
switch (pdrv->boot_ctrl->init_level) {
case LCD_INIT_LEVEL_NORMAL:
@@ -1863,6 +1872,8 @@ static void lcd_bootup_config_init(struct aml_lcd_drv_s *pdrv)
pdrv->config.basic.lcd_type = pdrv->boot_ctrl->lcd_type;
pdrv->config.timing.clk_mode = pdrv->boot_ctrl->clk_mode;
pdrv->config.timing.dft_timing.frame_rate = pdrv->boot_ctrl->base_frame_rate;
pdrv->config.timing.dft_timing.frame_rate_min = pdrv->boot_ctrl->base_frame_rate;
pdrv->config.timing.dft_timing.frame_rate_max = pdrv->boot_ctrl->base_frame_rate;
pdrv->config.timing.base_timing.frame_rate = pdrv->boot_ctrl->base_frame_rate;
pdrv->config.timing.act_timing.frame_rate = pdrv->boot_ctrl->base_frame_rate;
switch (pdrv->boot_ctrl->ppc) {
@@ -524,6 +524,8 @@ enum lcd_phy_set_status {
struct cus_ctrl_config_s {
unsigned int flag;
unsigned char ufr_flag;
struct lcd_detail_timing_s dft_timing;
unsigned long long mute_time;
unsigned long long unmute_time;
unsigned long long switch_time;
@@ -625,6 +627,7 @@ struct lcd_debug_ctrl_s {
unsigned char debug_lcd_mode;
};
#define LCD_DURATION_MAX 8
struct lcd_duration_s {
unsigned int frame_rate;
unsigned int duration_num;
@@ -632,6 +635,29 @@ struct lcd_duration_s {
unsigned int frac;
};
struct lcd_vmode_info_s {
char name[32];
unsigned int width;
unsigned int height;
unsigned int base_fr;
unsigned int duration_index;
unsigned int duration_cnt;
struct lcd_duration_s duration[LCD_DURATION_MAX];
struct lcd_detail_timing_s *dft_timing;
};
struct lcd_vmode_list_s {
struct lcd_vmode_info_s *info;
struct lcd_vmode_list_s *next;
};
struct lcd_vmode_mgr_s {
unsigned int vmode_cnt;
struct lcd_vmode_list_s *vmode_list_header;
struct lcd_vmode_info_s *cur_vmode_info;
struct lcd_vmode_info_s *next_vmode_info;
};
struct lcd_data_s {
enum lcd_chip_e chip_type;
const char *chip_name;
@@ -691,7 +717,7 @@ struct aml_lcd_drv_s {
char vsync_isr_name[3][15];
char vbyone_isr_name[10];
char output_name[30];
unsigned int vmode_update;
unsigned int vmode_switch;
unsigned char config_check_glb;
unsigned char config_check_en;
@@ -701,7 +727,7 @@ struct aml_lcd_drv_s {
struct platform_device *pdev;
struct lcd_config_s config;
struct lcd_duration_s *std_duration;
struct lcd_duration_s cur_duration;
struct lcd_vmode_mgr_s vmode_mgr;
struct vinfo_s vinfo;
void *clk_conf;
struct lcd_reg_map_s *reg_map;