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