mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
lcd: optimize lcd notifier event for power sequence
PD#158197: lcd: optimize lcd notifier event for power sequence Change-Id: I6b91bf1c2c6e31dfa3133f078d37d32fdce2a5bd Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
This commit is contained in:
@@ -24,11 +24,11 @@
|
||||
|
||||
/* 20170505: add a113 support to linux4.9 */
|
||||
/* 20170905: fix coverity errors */
|
||||
#define LCD_DRV_VERSION "20171201"
|
||||
/* 20180122: support txlx, optimize lcd noitfier event */
|
||||
#define LCD_DRV_VERSION "20180122"
|
||||
|
||||
#define VPP_OUT_SATURATE (1 << 0)
|
||||
|
||||
extern struct mutex lcd_power_mutex;
|
||||
extern struct mutex lcd_vout_mutex;
|
||||
extern unsigned char lcd_resume_flag;
|
||||
extern int lcd_vout_serve_bypass;
|
||||
|
||||
@@ -952,7 +952,7 @@ static void lcd_mute_setting(unsigned char flag)
|
||||
}
|
||||
}
|
||||
|
||||
static void lcd_test_check(void)
|
||||
static void lcd_screen_restore(void)
|
||||
{
|
||||
unsigned int h_active, video_on_pixel;
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
@@ -983,6 +983,11 @@ static void lcd_test_check(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void lcd_screen_black(void)
|
||||
{
|
||||
lcd_mute_setting(1);
|
||||
}
|
||||
|
||||
static void lcd_vinfo_update(void)
|
||||
{
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
@@ -1057,6 +1062,26 @@ static void lcd_debug_clk_change(unsigned int pclk)
|
||||
&lcd_drv->lcd_info->mode);
|
||||
}
|
||||
|
||||
static void lcd_power_interface_ctrl(int state)
|
||||
{
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
|
||||
mutex_lock(&lcd_drv->power_mutex);
|
||||
LCDPR("%s: %d\n", __func__, state);
|
||||
if (state) {
|
||||
if (lcd_drv->lcd_status & LCD_STATUS_ENCL_ON) {
|
||||
aml_lcd_notifier_call_chain(
|
||||
LCD_EVENT_IF_POWER_ON, NULL);
|
||||
} else {
|
||||
LCDERR("%s: can't power on when controller is off\n",
|
||||
__func__);
|
||||
}
|
||||
} else {
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_IF_POWER_OFF, NULL);
|
||||
}
|
||||
mutex_unlock(&lcd_drv->power_mutex);
|
||||
}
|
||||
|
||||
static ssize_t lcd_debug_store(struct class *class,
|
||||
struct class_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
@@ -1254,16 +1279,7 @@ static ssize_t lcd_debug_store(struct class *class,
|
||||
case 'p': /* power */
|
||||
ret = sscanf(buf, "power %d", &temp);
|
||||
if (ret == 1) {
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
LCDPR("power: %d\n", temp);
|
||||
if (temp) {
|
||||
aml_lcd_notifier_call_chain(
|
||||
LCD_EVENT_IF_POWER_ON, NULL);
|
||||
} else {
|
||||
aml_lcd_notifier_call_chain(
|
||||
LCD_EVENT_IF_POWER_OFF, NULL);
|
||||
}
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
lcd_power_interface_ctrl(temp);
|
||||
} else {
|
||||
LCDERR("invalid data\n");
|
||||
return -EINVAL;
|
||||
@@ -1450,6 +1466,7 @@ static ssize_t lcd_debug_enable_show(struct class *class,
|
||||
static ssize_t lcd_debug_enable_store(struct class *class,
|
||||
struct class_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
int ret = 0;
|
||||
unsigned int temp = 1;
|
||||
|
||||
@@ -1459,13 +1476,13 @@ static ssize_t lcd_debug_enable_store(struct class *class,
|
||||
return -EINVAL;
|
||||
}
|
||||
if (temp) {
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
mutex_lock(&lcd_drv->power_mutex);
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_drv->power_mutex);
|
||||
} else {
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
mutex_lock(&lcd_drv->power_mutex);
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_OFF, NULL);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_drv->power_mutex);
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -2673,36 +2690,14 @@ static struct class_attribute lcd_phy_debug_class_attrs[] = {
|
||||
lcd_phy_debug_show, lcd_phy_debug_store),
|
||||
};
|
||||
|
||||
static int lcd_black_screen_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
if ((event & LCD_EVENT_BLACK_SCREEN) == 0)
|
||||
return NOTIFY_DONE;
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
|
||||
lcd_mute_setting(1);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block lcd_black_screen_nb = {
|
||||
.notifier_call = lcd_black_screen_notifier,
|
||||
.priority = LCD_PRIORITY_BLACK_SCREEN,
|
||||
};
|
||||
|
||||
int lcd_class_creat(void)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
int type;
|
||||
|
||||
ret = aml_lcd_notifier_register(&lcd_black_screen_nb);
|
||||
if (ret)
|
||||
LCDERR("register lcd_black_screen_notifier failed\n");
|
||||
|
||||
lcd_drv->lcd_test_pattern_restore = lcd_test_check;
|
||||
lcd_drv->lcd_screen_restore = lcd_screen_restore;
|
||||
lcd_drv->lcd_screen_black = lcd_screen_black;
|
||||
|
||||
lcd_drv->lcd_debug_class = class_create(THIS_MODULE, "lcd");
|
||||
if (IS_ERR(lcd_drv->lcd_debug_class)) {
|
||||
|
||||
@@ -873,7 +873,26 @@ void lcd_tablet_driver_init_pre(void)
|
||||
lcd_clk_set(pconf);
|
||||
lcd_venc_set(pconf);
|
||||
lcd_tcon_set(pconf);
|
||||
lcd_drv->lcd_test_pattern_restore();
|
||||
|
||||
lcd_vcbus_write(VENC_INTCTRL, 0x200);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s finished\n", __func__);
|
||||
}
|
||||
|
||||
void lcd_tablet_driver_disable_post(void)
|
||||
{
|
||||
lcd_vcbus_write(ENCL_VIDEO_EN, 0); /* disable encl */
|
||||
|
||||
lcd_clk_disable();
|
||||
lcd_clk_gate_switch(0);
|
||||
#ifdef CONFIG_AMLOGIC_VPU
|
||||
switch_vpu_mem_pd_vmod(VPU_VENCL, VPU_MEM_POWER_DOWN);
|
||||
release_vpu_clk_vmod(VPU_VENCL);
|
||||
#endif
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s finished\n", __func__);
|
||||
}
|
||||
|
||||
int lcd_tablet_driver_init(void)
|
||||
@@ -911,8 +930,6 @@ int lcd_tablet_driver_init(void)
|
||||
break;
|
||||
}
|
||||
|
||||
lcd_vcbus_write(VENC_INTCTRL, 0x200);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s finished\n", __func__);
|
||||
|
||||
@@ -952,88 +969,7 @@ void lcd_tablet_driver_disable(void)
|
||||
break;
|
||||
}
|
||||
|
||||
lcd_vcbus_write(ENCL_VIDEO_EN, 0); /* disable encl */
|
||||
|
||||
lcd_clk_disable();
|
||||
lcd_clk_gate_switch(0);
|
||||
#ifdef CONFIG_AMLOGIC_VPU
|
||||
switch_vpu_mem_pd_vmod(VPU_VENCL, VPU_MEM_POWER_DOWN);
|
||||
release_vpu_clk_vmod(VPU_VENCL);
|
||||
#endif
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s finished\n", __func__);
|
||||
}
|
||||
|
||||
void lcd_tablet_driver_tiny_enable(void)
|
||||
{
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
struct lcd_config_s *pconf;
|
||||
int ret;
|
||||
|
||||
pconf = lcd_drv->lcd_config;
|
||||
ret = lcd_type_supported(pconf);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
/* init driver */
|
||||
switch (pconf->lcd_basic.lcd_type) {
|
||||
case LCD_TTL:
|
||||
lcd_ttl_control_set(pconf);
|
||||
lcd_ttl_pinmux_set(1);
|
||||
break;
|
||||
case LCD_LVDS:
|
||||
lcd_lvds_control_set(pconf);
|
||||
lcd_lvds_phy_set(pconf, 1);
|
||||
break;
|
||||
case LCD_VBYONE:
|
||||
lcd_vbyone_pinmux_set(1);
|
||||
lcd_vbyone_control_set(pconf);
|
||||
lcd_vx1_wait_hpd();
|
||||
lcd_vbyone_phy_set(pconf, 1);
|
||||
lcd_tablet_vbyone_wait_stable();
|
||||
case LCD_MIPI:
|
||||
lcd_mipi_phy_set(pconf, 1);
|
||||
lcd_mipi_control_set(pconf, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LCDPR("enable driver\n");
|
||||
}
|
||||
|
||||
void lcd_tablet_driver_tiny_disable(void)
|
||||
{
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
struct lcd_config_s *pconf;
|
||||
int ret;
|
||||
|
||||
LCDPR("disable driver\n");
|
||||
pconf = lcd_drv->lcd_config;
|
||||
ret = lcd_type_supported(pconf);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
switch (pconf->lcd_basic.lcd_type) {
|
||||
case LCD_TTL:
|
||||
lcd_ttl_pinmux_set(0);
|
||||
break;
|
||||
case LCD_LVDS:
|
||||
lcd_lvds_phy_set(pconf, 0);
|
||||
lcd_lvds_disable();
|
||||
break;
|
||||
case LCD_VBYONE:
|
||||
lcd_vbyone_phy_set(pconf, 0);
|
||||
lcd_vbyone_pinmux_set(0);
|
||||
lcd_vbyone_disable();
|
||||
case LCD_MIPI:
|
||||
mipi_dsi_link_off(pconf);
|
||||
lcd_mipi_phy_set(pconf, 0);
|
||||
lcd_mipi_control_set(pconf, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -293,11 +293,13 @@ static int lcd_get_vframe_rate_policy(void)
|
||||
#ifdef CONFIG_PM
|
||||
static int lcd_suspend(void)
|
||||
{
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
|
||||
mutex_lock(&lcd_drv->power_mutex);
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_OFF, NULL);
|
||||
lcd_resume_flag = 0;
|
||||
LCDPR("%s finished\n", __func__);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_drv->power_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -313,20 +315,20 @@ static int lcd_resume(void)
|
||||
queue_work(lcd_drv->workqueue,
|
||||
&(lcd_drv->lcd_resume_work));
|
||||
} else {
|
||||
mutex_lock(&lcd_drv->power_mutex);
|
||||
LCDPR("Warning: no lcd workqueue\n");
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
lcd_resume_flag = 1;
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
|
||||
LCDPR("%s finished\n", __func__);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_drv->power_mutex);
|
||||
}
|
||||
} else {
|
||||
mutex_lock(&lcd_drv->power_mutex);
|
||||
LCDPR("directly lcd late resume\n");
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
lcd_resume_flag = 1;
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
|
||||
LCDPR("%s finished\n", __func__);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_drv->power_mutex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1292,10 +1294,9 @@ int lcd_tablet_probe(struct device *dev)
|
||||
lcd_drv->version = LCD_DRV_VERSION;
|
||||
lcd_drv->vout_server_init = lcd_tablet_vout_server_init;
|
||||
lcd_drv->driver_init_pre = lcd_tablet_driver_init_pre;
|
||||
lcd_drv->driver_disable_post = lcd_tablet_driver_disable_post;
|
||||
lcd_drv->driver_init = lcd_tablet_driver_init;
|
||||
lcd_drv->driver_disable = lcd_tablet_driver_disable;
|
||||
lcd_drv->driver_tiny_enable = lcd_tablet_driver_tiny_enable;
|
||||
lcd_drv->driver_tiny_disable = lcd_tablet_driver_tiny_disable;
|
||||
|
||||
lcd_get_config(lcd_drv->lcd_config, dev);
|
||||
|
||||
|
||||
@@ -21,9 +21,8 @@
|
||||
extern void lcd_tablet_config_update(struct lcd_config_s *pconf);
|
||||
extern void lcd_tablet_config_post_update(struct lcd_config_s *pconf);
|
||||
extern void lcd_tablet_driver_init_pre(void);
|
||||
extern void lcd_tablet_driver_disable_post(void);
|
||||
extern int lcd_tablet_driver_init(void);
|
||||
extern void lcd_tablet_driver_disable(void);
|
||||
extern void lcd_tablet_driver_tiny_enable(void);
|
||||
extern void lcd_tablet_driver_tiny_disable(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -837,10 +837,7 @@ static void lcd_vx1_timeout_reset(unsigned long data)
|
||||
return;
|
||||
|
||||
LCDPR("%s\n", __func__);
|
||||
if (vx1_timeout_reset_flag == 1)
|
||||
lcd_drv->module_reset();
|
||||
else
|
||||
lcd_drv->module_tiny_reset();
|
||||
lcd_drv->module_reset();
|
||||
if (lcd_drv->lcd_config->lcd_control.vbyone_config->intr_en)
|
||||
lcd_vx1_hold_reset();
|
||||
vx1_timeout_reset_flag = 0;
|
||||
@@ -855,7 +852,7 @@ static irqreturn_t lcd_vbyone_vsync_isr(int irq, void *dev_id)
|
||||
struct vbyone_config_s *vx1_conf;
|
||||
|
||||
vx1_conf = lcd_drv->lcd_config->lcd_control.vbyone_config;
|
||||
if (lcd_drv->lcd_status == 0)
|
||||
if ((lcd_drv->lcd_status & LCD_STATUS_IF_ON) == 0)
|
||||
return IRQ_HANDLED;
|
||||
if (lcd_vcbus_read(VBO_STATUS_L) & 0x40) /* hpd detect */
|
||||
return IRQ_HANDLED;
|
||||
@@ -1240,7 +1237,26 @@ void lcd_tv_driver_init_pre(void)
|
||||
lcd_clk_set(pconf);
|
||||
lcd_venc_set(pconf);
|
||||
lcd_tcon_set(pconf);
|
||||
lcd_drv->lcd_test_pattern_restore();
|
||||
|
||||
lcd_vcbus_write(VENC_INTCTRL, 0x200);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s finished\n", __func__);
|
||||
}
|
||||
|
||||
void lcd_tv_driver_disable_post(void)
|
||||
{
|
||||
lcd_vcbus_write(ENCL_VIDEO_EN, 0); /* disable encl */
|
||||
|
||||
lcd_clk_disable();
|
||||
lcd_clk_gate_switch(0);
|
||||
#ifdef CONFIG_AMLOGIC_VPU
|
||||
switch_vpu_mem_pd_vmod(VPU_VENCL, VPU_MEM_POWER_DOWN);
|
||||
release_vpu_clk_vmod(VPU_VENCL);
|
||||
#endif
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s finished\n", __func__);
|
||||
}
|
||||
|
||||
int lcd_tv_driver_init(void)
|
||||
@@ -1266,15 +1282,13 @@ int lcd_tv_driver_init(void)
|
||||
lcd_vbyone_phy_set(pconf, 1);
|
||||
lcd_vx1_intr_request = 1;
|
||||
queue_delayed_work(lcd_drv->workqueue,
|
||||
&lcd_drv->lcd_vx1_delayed_work,
|
||||
msecs_to_jiffies(LCD_VX1_WAIT_STABLE_DELAY));
|
||||
&lcd_drv->lcd_vx1_delayed_work,
|
||||
msecs_to_jiffies(LCD_VX1_WAIT_STABLE_DELAY));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
lcd_vcbus_write(VENC_INTCTRL, 0x200);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s finished\n", __func__);
|
||||
return 0;
|
||||
@@ -1310,15 +1324,6 @@ void lcd_tv_driver_disable(void)
|
||||
break;
|
||||
}
|
||||
|
||||
lcd_vcbus_write(ENCL_VIDEO_EN, 0); /* disable encl */
|
||||
|
||||
lcd_clk_disable();
|
||||
lcd_clk_gate_switch(0);
|
||||
#ifdef CONFIG_AMLOGIC_VPU
|
||||
switch_vpu_mem_pd_vmod(VPU_VENCL, VPU_MEM_POWER_DOWN);
|
||||
release_vpu_clk_vmod(VPU_VENCL);
|
||||
#endif
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s finished\n", __func__);
|
||||
}
|
||||
@@ -1341,18 +1346,11 @@ int lcd_tv_driver_change(void)
|
||||
request_vpu_clk_vmod(pconf->lcd_timing.lcd_clk, VPU_VENCL);
|
||||
#endif
|
||||
|
||||
if (lcd_drv->lcd_status == 0) {
|
||||
/* only change parameters when panel is off */
|
||||
switch (pconf->lcd_timing.clk_change) {
|
||||
case LCD_CLK_PLL_CHANGE:
|
||||
lcd_clk_generate_parameter(pconf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (lcd_drv->lcd_status & LCD_STATUS_ENCL_ON) {
|
||||
if (pconf->lcd_basic.lcd_type == LCD_VBYONE) {
|
||||
if (lcd_drv->lcd_status & LCD_STATUS_IF_ON)
|
||||
lcd_vbyone_interrupt_enable(0);
|
||||
}
|
||||
} else {
|
||||
if (pconf->lcd_basic.lcd_type == LCD_VBYONE)
|
||||
lcd_vbyone_interrupt_enable(0);
|
||||
|
||||
switch (pconf->lcd_timing.clk_change) {
|
||||
case LCD_CLK_PLL_CHANGE:
|
||||
@@ -1367,8 +1365,19 @@ int lcd_tv_driver_change(void)
|
||||
}
|
||||
lcd_venc_change(pconf);
|
||||
|
||||
if (pconf->lcd_basic.lcd_type == LCD_VBYONE)
|
||||
lcd_vbyone_wait_stable();
|
||||
if (pconf->lcd_basic.lcd_type == LCD_VBYONE) {
|
||||
if (lcd_drv->lcd_status & LCD_STATUS_IF_ON)
|
||||
lcd_vbyone_wait_stable();
|
||||
}
|
||||
} else {
|
||||
/* only change parameters when panel is off */
|
||||
switch (pconf->lcd_timing.clk_change) {
|
||||
case LCD_CLK_PLL_CHANGE:
|
||||
lcd_clk_generate_parameter(pconf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
@@ -1376,69 +1385,10 @@ int lcd_tv_driver_change(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lcd_tv_driver_tiny_enable(void)
|
||||
{
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
struct lcd_config_s *pconf;
|
||||
int ret;
|
||||
|
||||
pconf = lcd_drv->lcd_config;
|
||||
ret = lcd_type_supported(pconf);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
switch (pconf->lcd_basic.lcd_type) {
|
||||
case LCD_LVDS:
|
||||
lcd_lvds_control_set(pconf);
|
||||
lcd_lvds_phy_set(pconf, 1);
|
||||
break;
|
||||
case LCD_VBYONE:
|
||||
lcd_vbyone_pinmux_set(1);
|
||||
lcd_vbyone_control_set(pconf);
|
||||
lcd_vbyone_wait_hpd(pconf);
|
||||
lcd_vbyone_phy_set(pconf, 1);
|
||||
lcd_vbyone_power_on_wait_stable(pconf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LCDPR("enable driver\n");
|
||||
}
|
||||
|
||||
void lcd_tv_driver_tiny_disable(void)
|
||||
{
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
struct lcd_config_s *pconf;
|
||||
int ret;
|
||||
|
||||
LCDPR("disable driver\n");
|
||||
pconf = lcd_drv->lcd_config;
|
||||
ret = lcd_type_supported(pconf);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
switch (pconf->lcd_basic.lcd_type) {
|
||||
case LCD_LVDS:
|
||||
lcd_lvds_phy_set(pconf, 0);
|
||||
lcd_lvds_disable();
|
||||
break;
|
||||
case LCD_VBYONE:
|
||||
lcd_vbyone_interrupt_enable(0);
|
||||
lcd_vbyone_phy_set(pconf, 0);
|
||||
lcd_vbyone_pinmux_set(0);
|
||||
lcd_vbyone_disable();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define VBYONE_IRQF IRQF_SHARED /* IRQF_DISABLED */ /* IRQF_SHARED */
|
||||
|
||||
int lcd_vbyone_interrupt_up(void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int viu_vsync_irq = 0, venc_vx1_irq = 0;
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
|
||||
@@ -1450,42 +1400,39 @@ int lcd_vbyone_interrupt_up(void)
|
||||
lcd_vx1_intr_request = 0;
|
||||
lcd_encl_clk_err_cnt = 0;
|
||||
|
||||
tasklet_init(&lcd_vx1_reset_tasklet, lcd_vx1_timeout_reset,
|
||||
123);
|
||||
tasklet_init(&lcd_vx1_reset_tasklet, lcd_vx1_timeout_reset, 123);
|
||||
|
||||
INIT_DELAYED_WORK(&lcd_drv->lcd_vx1_delayed_work,
|
||||
lcd_vx1_wait_stable_delayed);
|
||||
|
||||
if (!lcd_drv->res_vsync_irq) {
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
} else {
|
||||
viu_vsync_irq = lcd_drv->res_vsync_irq->start;
|
||||
LCDPR("viu_vsync_irq: %d\n", viu_vsync_irq);
|
||||
LCDERR("res_vsync_irq is null\n");
|
||||
return -1;
|
||||
}
|
||||
viu_vsync_irq = lcd_drv->res_vsync_irq->start;
|
||||
LCDPR("viu_vsync_irq: %d\n", viu_vsync_irq);
|
||||
|
||||
if (request_irq(viu_vsync_irq, lcd_vbyone_vsync_isr,
|
||||
IRQF_SHARED, "vbyone_vsync", (void *)"vbyone_vsync"))
|
||||
LCDERR("can't request viu_vsync_irq\n");
|
||||
else {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("request viu_vsync_irq successful\n");
|
||||
}
|
||||
if (request_irq(viu_vsync_irq, lcd_vbyone_vsync_isr,
|
||||
IRQF_SHARED, "vbyone_vsync", (void *)"vbyone_vsync"))
|
||||
LCDERR("can't request viu_vsync_irq\n");
|
||||
else {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("request viu_vsync_irq successful\n");
|
||||
}
|
||||
|
||||
if (!lcd_drv->res_vx1_irq) {
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
} else {
|
||||
venc_vx1_irq = lcd_drv->res_vx1_irq->start;
|
||||
LCDPR("venc_vx1_irq: %d\n", venc_vx1_irq);
|
||||
LCDERR("res_vx1_irq is null\n");
|
||||
return -1;
|
||||
}
|
||||
venc_vx1_irq = lcd_drv->res_vx1_irq->start;
|
||||
LCDPR("venc_vx1_irq: %d\n", venc_vx1_irq);
|
||||
|
||||
if (request_irq(venc_vx1_irq, lcd_vbyone_interrupt_handler, 0,
|
||||
"vbyone", (void *)"vbyone"))
|
||||
LCDERR("can't request venc_vx1_irq\n");
|
||||
else {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("request venc_vx1_irq successful\n");
|
||||
}
|
||||
if (request_irq(venc_vx1_irq, lcd_vbyone_interrupt_handler, 0,
|
||||
"vbyone", (void *)"vbyone"))
|
||||
LCDERR("can't request venc_vx1_irq\n");
|
||||
else {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("request venc_vx1_irq successful\n");
|
||||
}
|
||||
|
||||
lcd_vx1_intr_request = 1;
|
||||
@@ -1500,10 +1447,6 @@ int lcd_vbyone_interrupt_up(void)
|
||||
LCDPR("add vbyone hpll timer handler\n");
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return -ENODEV;
|
||||
|
||||
}
|
||||
|
||||
void lcd_vbyone_interrupt_down(void)
|
||||
|
||||
@@ -521,11 +521,13 @@ static int lcd_get_vframe_rate_policy(void)
|
||||
#ifdef CONFIG_PM
|
||||
static int lcd_suspend(void)
|
||||
{
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
|
||||
mutex_lock(&lcd_drv->power_mutex);
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_OFF, NULL);
|
||||
lcd_resume_flag = 0;
|
||||
LCDPR("%s finished\n", __func__);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_drv->power_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -541,20 +543,20 @@ static int lcd_resume(void)
|
||||
queue_work(lcd_drv->workqueue,
|
||||
&(lcd_drv->lcd_resume_work));
|
||||
} else {
|
||||
mutex_lock(&lcd_drv->power_mutex);
|
||||
LCDPR("Warning: no lcd workqueue\n");
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
lcd_resume_flag = 1;
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
|
||||
LCDPR("%s finished\n", __func__);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_drv->power_mutex);
|
||||
}
|
||||
} else {
|
||||
mutex_lock(&lcd_drv->power_mutex);
|
||||
LCDPR("directly lcd late resume\n");
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
lcd_resume_flag = 1;
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
|
||||
LCDPR("%s finished\n", __func__);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_drv->power_mutex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1413,11 +1415,10 @@ int lcd_tv_probe(struct device *dev)
|
||||
lcd_drv->version = LCD_DRV_VERSION;
|
||||
lcd_drv->vout_server_init = lcd_tv_vout_server_init;
|
||||
lcd_drv->driver_init_pre = lcd_tv_driver_init_pre;
|
||||
lcd_drv->driver_disable_post = lcd_tv_driver_disable_post;
|
||||
lcd_drv->driver_init = lcd_tv_driver_init;
|
||||
lcd_drv->driver_disable = lcd_tv_driver_disable;
|
||||
lcd_drv->driver_change = lcd_tv_driver_change;
|
||||
lcd_drv->driver_tiny_enable = lcd_tv_driver_tiny_enable;
|
||||
lcd_drv->driver_tiny_disable = lcd_tv_driver_tiny_disable;
|
||||
|
||||
lcd_get_config(lcd_drv->lcd_config, dev);
|
||||
|
||||
|
||||
@@ -21,11 +21,10 @@
|
||||
|
||||
extern void lcd_tv_config_update(struct lcd_config_s *pconf);
|
||||
extern void lcd_tv_driver_init_pre(void);
|
||||
extern void lcd_tv_driver_disable_post(void);
|
||||
extern int lcd_tv_driver_init(void);
|
||||
extern void lcd_tv_driver_disable(void);
|
||||
extern int lcd_tv_driver_change(void);
|
||||
extern void lcd_tv_driver_tiny_enable(void);
|
||||
extern void lcd_tv_driver_tiny_disable(void);
|
||||
|
||||
extern void lcd_vbyone_wait_stable(void);
|
||||
extern int lcd_vbyone_interrupt_up(void);
|
||||
|
||||
@@ -55,7 +55,6 @@ unsigned char lcd_debug_print_flag;
|
||||
unsigned char lcd_resume_flag;
|
||||
static struct aml_lcd_drv_s *lcd_driver;
|
||||
|
||||
struct mutex lcd_power_mutex;
|
||||
struct mutex lcd_vout_mutex;
|
||||
int lcd_vout_serve_bypass;
|
||||
|
||||
@@ -206,76 +205,6 @@ struct aml_lcd_drv_s *aml_lcd_get_driver(void)
|
||||
}
|
||||
/* ********************************************************* */
|
||||
|
||||
static void lcd_power_tiny_ctrl(int status)
|
||||
{
|
||||
struct lcd_power_ctrl_s *lcd_power = lcd_driver->lcd_config->lcd_power;
|
||||
struct lcd_power_step_s *power_step;
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN
|
||||
struct aml_lcd_extern_driver_s *ext_drv;
|
||||
#endif
|
||||
int i, index;
|
||||
|
||||
LCDPR("%s: %d\n", __func__, status);
|
||||
i = 0;
|
||||
while (i < LCD_PWR_STEP_MAX) {
|
||||
if (status)
|
||||
power_step = &lcd_power->power_on_step[i];
|
||||
else
|
||||
power_step = &lcd_power->power_off_step[i];
|
||||
|
||||
if (power_step->type >= LCD_POWER_TYPE_MAX)
|
||||
break;
|
||||
if (lcd_debug_print_flag) {
|
||||
LCDPR("power_tiny_ctrl: %d, step %d\n", status, i);
|
||||
LCDPR("type=%d, index=%d, value=%d, delay=%d\n",
|
||||
power_step->type, power_step->index,
|
||||
power_step->value, power_step->delay);
|
||||
}
|
||||
switch (power_step->type) {
|
||||
case LCD_POWER_TYPE_CPU:
|
||||
index = power_step->index;
|
||||
lcd_cpu_gpio_set(index, power_step->value);
|
||||
break;
|
||||
case LCD_POWER_TYPE_PMU:
|
||||
LCDPR("to do\n");
|
||||
break;
|
||||
case LCD_POWER_TYPE_SIGNAL:
|
||||
if (status)
|
||||
lcd_driver->driver_tiny_enable();
|
||||
else
|
||||
lcd_driver->driver_tiny_disable();
|
||||
break;
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN
|
||||
case LCD_POWER_TYPE_EXTERN:
|
||||
index = power_step->index;
|
||||
ext_drv = aml_lcd_extern_get_driver(index);
|
||||
if (ext_drv) {
|
||||
if (status) {
|
||||
if (ext_drv->power_on)
|
||||
ext_drv->power_on();
|
||||
else
|
||||
LCDERR("no ext power on\n");
|
||||
} else {
|
||||
if (ext_drv->power_off)
|
||||
ext_drv->power_off();
|
||||
else
|
||||
LCDERR("no ext power off\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (power_step->delay)
|
||||
mdelay(power_step->delay);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: %d finished\n", __func__, status);
|
||||
}
|
||||
|
||||
static void lcd_power_ctrl(int status)
|
||||
{
|
||||
struct lcd_power_ctrl_s *lcd_power = lcd_driver->lcd_config->lcd_power;
|
||||
@@ -347,54 +276,77 @@ static void lcd_power_ctrl(int status)
|
||||
LCDPR("%s: %d finished\n", __func__, status);
|
||||
}
|
||||
|
||||
static void lcd_module_enable(void)
|
||||
static void lcd_power_encl_on(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->driver_init_pre();
|
||||
lcd_driver->lcd_status |= LCD_STATUS_ENCL_ON;
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
static void lcd_power_encl_off(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->lcd_status &= ~LCD_STATUS_ENCL_ON;
|
||||
lcd_driver->driver_disable_post();
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
static void lcd_power_if_on(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->power_ctrl(1);
|
||||
lcd_driver->lcd_status = 1;
|
||||
lcd_driver->lcd_status |= LCD_STATUS_IF_ON;
|
||||
lcd_driver->lcd_config->change_flag = 0;
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
static void lcd_module_disable(void)
|
||||
static void lcd_power_if_off(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->lcd_status = 0;
|
||||
lcd_driver->lcd_status &= ~LCD_STATUS_IF_ON;
|
||||
lcd_driver->power_ctrl(0);
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
static void lcd_power_screen_black(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->lcd_screen_black();
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
static void lcd_power_screen_restore(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->lcd_screen_restore();
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
static void lcd_module_reset(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->lcd_status = 0;
|
||||
lcd_driver->lcd_status &= ~LCD_STATUS_ON;
|
||||
lcd_driver->power_ctrl(0);
|
||||
|
||||
msleep(500);
|
||||
|
||||
lcd_driver->driver_init_pre();
|
||||
lcd_driver->power_ctrl(1);
|
||||
lcd_driver->lcd_status = 1;
|
||||
lcd_driver->lcd_config->change_flag = 0;
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
static void lcd_module_tiny_reset(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->lcd_status = 0;
|
||||
lcd_power_tiny_ctrl(0);
|
||||
mdelay(500);
|
||||
lcd_power_tiny_ctrl(1);
|
||||
lcd_driver->lcd_status = 1;
|
||||
lcd_driver->lcd_status |= LCD_STATUS_ON;
|
||||
lcd_driver->lcd_config->change_flag = 0;
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
@@ -402,60 +354,129 @@ static void lcd_module_tiny_reset(void)
|
||||
|
||||
static void lcd_resume_work(struct work_struct *p_work)
|
||||
{
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
mutex_lock(&lcd_driver->power_mutex);
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
|
||||
LCDPR("%s finished\n", __func__);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_driver->power_mutex);
|
||||
}
|
||||
|
||||
/* ****************************************
|
||||
* lcd notify
|
||||
* ****************************************
|
||||
*/
|
||||
static int lcd_power_notifier(struct notifier_block *nb,
|
||||
static int lcd_power_encl_on_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
if (event & LCD_EVENT_LCD_ON) {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
lcd_module_enable();
|
||||
} else if (event & LCD_EVENT_LCD_OFF) {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
lcd_module_disable();
|
||||
} else {
|
||||
if ((event & LCD_EVENT_ENCL_ON) == 0)
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
lcd_power_encl_on();
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block lcd_power_nb = {
|
||||
.notifier_call = lcd_power_notifier,
|
||||
.priority = LCD_PRIORITY_POWER_LCD,
|
||||
static struct notifier_block lcd_power_encl_on_nb = {
|
||||
.notifier_call = lcd_power_encl_on_notifier,
|
||||
.priority = LCD_PRIORITY_POWER_ENCL_ON,
|
||||
};
|
||||
|
||||
static int lcd_interface_notifier(struct notifier_block *nb,
|
||||
static int lcd_power_encl_off_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
if (event & LCD_EVENT_IF_ON) {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
lcd_driver->power_tiny_ctrl(1);
|
||||
} else if (event & LCD_EVENT_IF_OFF) {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
lcd_driver->power_tiny_ctrl(0);
|
||||
} else {
|
||||
if ((event & LCD_EVENT_ENCL_OFF) == 0)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
lcd_power_encl_off();
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block lcd_power_encl_off_nb = {
|
||||
.notifier_call = lcd_power_encl_off_notifier,
|
||||
.priority = LCD_PRIORITY_POWER_ENCL_OFF,
|
||||
};
|
||||
|
||||
static int lcd_power_if_on_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
if ((event & LCD_EVENT_IF_ON) == 0)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
|
||||
if (lcd_driver->lcd_status & LCD_STATUS_ENCL_ON) {
|
||||
lcd_power_if_on();
|
||||
} else {
|
||||
LCDERR("%s: can't power on when controller is off\n",
|
||||
__func__);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block lcd_interface_nb = {
|
||||
.notifier_call = lcd_interface_notifier,
|
||||
.priority = LCD_PRIORITY_POWER_LCD,
|
||||
static struct notifier_block lcd_power_if_on_nb = {
|
||||
.notifier_call = lcd_power_if_on_notifier,
|
||||
.priority = LCD_PRIORITY_POWER_IF_ON,
|
||||
};
|
||||
|
||||
static int lcd_power_if_off_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
if ((event & LCD_EVENT_IF_OFF) == 0)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
lcd_power_if_off();
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block lcd_power_if_off_nb = {
|
||||
.notifier_call = lcd_power_if_off_notifier,
|
||||
.priority = LCD_PRIORITY_POWER_IF_OFF,
|
||||
};
|
||||
|
||||
static int lcd_power_screen_black_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
if ((event & LCD_EVENT_SCREEN_BLACK) == 0)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
lcd_power_screen_black();
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block lcd_power_screen_black_nb = {
|
||||
.notifier_call = lcd_power_screen_black_notifier,
|
||||
.priority = LCD_PRIORITY_SCREEN_BLACK,
|
||||
};
|
||||
|
||||
static int lcd_power_screen_restore_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
if ((event & LCD_EVENT_SCREEN_RESTORE) == 0)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
lcd_power_screen_restore();
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block lcd_power_screen_restore_nb = {
|
||||
.notifier_call = lcd_power_screen_restore_notifier,
|
||||
.priority = LCD_PRIORITY_SCREEN_RESTORE,
|
||||
};
|
||||
|
||||
static int lcd_bl_select_notifier(struct notifier_block *nb,
|
||||
@@ -476,6 +497,48 @@ static int lcd_bl_select_notifier(struct notifier_block *nb,
|
||||
static struct notifier_block lcd_bl_select_nb = {
|
||||
.notifier_call = lcd_bl_select_notifier,
|
||||
};
|
||||
|
||||
static int lcd_notifier_register(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = aml_lcd_notifier_register(&lcd_bl_select_nb);
|
||||
if (ret)
|
||||
LCDERR("register aml_bl_select_notifier failed\n");
|
||||
|
||||
ret = aml_lcd_notifier_register(&lcd_power_encl_on_nb);
|
||||
if (ret)
|
||||
LCDERR("register lcd_power_encl_on_nb failed\n");
|
||||
ret = aml_lcd_notifier_register(&lcd_power_encl_off_nb);
|
||||
if (ret)
|
||||
LCDERR("register lcd_power_encl_off_nb failed\n");
|
||||
ret = aml_lcd_notifier_register(&lcd_power_if_on_nb);
|
||||
if (ret)
|
||||
LCDERR("register lcd_power_if_on_nb failed\n");
|
||||
ret = aml_lcd_notifier_register(&lcd_power_if_off_nb);
|
||||
if (ret)
|
||||
LCDERR("register lcd_power_if_off_nb failed\n");
|
||||
ret = aml_lcd_notifier_register(&lcd_power_screen_black_nb);
|
||||
if (ret)
|
||||
LCDERR("register lcd_power_screen_black_nb failed\n");
|
||||
ret = aml_lcd_notifier_register(&lcd_power_screen_restore_nb);
|
||||
if (ret)
|
||||
LCDERR("register lcd_power_screen_restore_nb failed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lcd_notifier_unregister(void)
|
||||
{
|
||||
aml_lcd_notifier_unregister(&lcd_power_screen_restore_nb);
|
||||
aml_lcd_notifier_unregister(&lcd_power_screen_black_nb);
|
||||
aml_lcd_notifier_unregister(&lcd_power_if_off_nb);
|
||||
aml_lcd_notifier_unregister(&lcd_power_if_on_nb);
|
||||
aml_lcd_notifier_unregister(&lcd_power_encl_off_nb);
|
||||
aml_lcd_notifier_unregister(&lcd_power_encl_on_nb);
|
||||
|
||||
aml_lcd_notifier_unregister(&lcd_bl_select_nb);
|
||||
}
|
||||
/* **************************************** */
|
||||
|
||||
/* ************************************************************* */
|
||||
@@ -656,8 +719,6 @@ static void lcd_init_vout(void)
|
||||
|
||||
static int lcd_mode_probe(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (lcd_driver->lcd_mode) {
|
||||
#ifdef CONFIG_AMLOGIC_LCD_TV
|
||||
case LCD_MODE_TV:
|
||||
@@ -677,15 +738,7 @@ static int lcd_mode_probe(struct device *dev)
|
||||
lcd_class_creat();
|
||||
lcd_fops_create();
|
||||
|
||||
ret = aml_lcd_notifier_register(&lcd_interface_nb);
|
||||
if (ret)
|
||||
LCDERR("register aml_bl_select_notifier failed\n");
|
||||
ret = aml_lcd_notifier_register(&lcd_bl_select_nb);
|
||||
if (ret)
|
||||
LCDERR("register aml_bl_select_notifier failed\n");
|
||||
ret = aml_lcd_notifier_register(&lcd_power_nb);
|
||||
if (ret)
|
||||
LCDPR("register lcd_power_notifier failed\n");
|
||||
lcd_notifier_register();
|
||||
|
||||
/* add notifier for video sync_duration info refresh */
|
||||
vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
|
||||
@@ -696,6 +749,8 @@ static int lcd_mode_probe(struct device *dev)
|
||||
|
||||
static int lcd_mode_remove(struct device *dev)
|
||||
{
|
||||
lcd_notifier_unregister();
|
||||
|
||||
switch (lcd_driver->lcd_mode) {
|
||||
#ifdef CONFIG_AMLOGIC_LCD_TV
|
||||
case LCD_MODE_TV:
|
||||
@@ -748,7 +803,7 @@ static void lcd_config_default(void)
|
||||
pconf->lcd_basic.v_active = lcd_vcbus_read(ENCL_VIDEO_VAVON_ELINE)
|
||||
- lcd_vcbus_read(ENCL_VIDEO_VAVON_BLINE) + 1;
|
||||
if (lcd_vcbus_read(ENCL_VIDEO_EN)) {
|
||||
lcd_driver->lcd_status = 1;
|
||||
lcd_driver->lcd_status = LCD_STATUS_ON;
|
||||
lcd_resume_flag = 1;
|
||||
} else {
|
||||
lcd_driver->lcd_status = 0;
|
||||
@@ -803,8 +858,6 @@ static int lcd_config_probe(struct platform_device *pdev)
|
||||
lcd_driver->lcd_resume_type = 1; /* default workqueue */
|
||||
lcd_driver->power_ctrl = lcd_power_ctrl;
|
||||
lcd_driver->module_reset = lcd_module_reset;
|
||||
lcd_driver->power_tiny_ctrl = lcd_power_tiny_ctrl;
|
||||
lcd_driver->module_tiny_reset = lcd_module_tiny_reset;
|
||||
lcd_driver->res_vsync_irq = platform_get_resource(pdev,
|
||||
IORESOURCE_IRQ, 0);
|
||||
lcd_driver->res_vx1_irq = platform_get_resource(pdev,
|
||||
@@ -924,7 +977,7 @@ static int lcd_probe(struct platform_device *pdev)
|
||||
lcd_driver->data->chip_name);
|
||||
|
||||
mutex_init(&lcd_vout_mutex);
|
||||
mutex_init(&lcd_power_mutex);
|
||||
mutex_init(&lcd_driver->power_mutex);
|
||||
lcd_vout_serve_bypass = 0;
|
||||
|
||||
/* init workqueue */
|
||||
@@ -953,10 +1006,6 @@ static int lcd_remove(struct platform_device *pdev)
|
||||
destroy_workqueue(lcd_driver->workqueue);
|
||||
|
||||
if (lcd_driver) {
|
||||
aml_lcd_notifier_unregister(&lcd_power_nb);
|
||||
aml_lcd_notifier_unregister(&lcd_bl_select_nb);
|
||||
aml_lcd_notifier_unregister(&lcd_interface_nb);
|
||||
|
||||
lcd_fops_remove();
|
||||
lcd_class_remove();
|
||||
lcd_clk_config_remove();
|
||||
@@ -978,19 +1027,19 @@ static int lcd_resume(struct platform_device *pdev)
|
||||
queue_work(lcd_driver->workqueue,
|
||||
&(lcd_driver->lcd_resume_work));
|
||||
} else {
|
||||
mutex_lock(&lcd_driver->power_mutex);
|
||||
LCDPR("Warning: no lcd workqueue\n");
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
|
||||
LCDPR("%s finished\n", __func__);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_driver->power_mutex);
|
||||
}
|
||||
} else {
|
||||
mutex_lock(&lcd_driver->power_mutex);
|
||||
LCDPR("directly lcd resume\n");
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
lcd_resume_flag = 1;
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
|
||||
LCDPR("%s finished\n", __func__);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_driver->power_mutex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -998,13 +1047,13 @@ static int lcd_resume(struct platform_device *pdev)
|
||||
|
||||
static int lcd_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
mutex_lock(&lcd_driver->power_mutex);
|
||||
if (lcd_driver->lcd_status) {
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_OFF, NULL);
|
||||
lcd_resume_flag = 0;
|
||||
LCDPR("%s finished\n", __func__);
|
||||
}
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
mutex_unlock(&lcd_driver->power_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,27 +20,45 @@
|
||||
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#define LCD_PRIORITY_INIT_CONFIG 4
|
||||
#define LCD_PRIORITY_INIT_VOUT 3
|
||||
#define LCD_PRIORITY_INIT_CONFIG 12
|
||||
#define LCD_PRIORITY_INIT_VOUT 11
|
||||
|
||||
#define LCD_PRIORITY_BLACK_SCREEN 3
|
||||
#define LCD_PRIORITY_POWER_BL_OFF 2
|
||||
#define LCD_PRIORITY_POWER_LCD 1
|
||||
#define LCD_PRIORITY_POWER_BL_ON 0
|
||||
#define LCD_PRIORITY_SCREEN_BLACK 7
|
||||
#define LCD_PRIORITY_POWER_BL_OFF 6
|
||||
#define LCD_PRIORITY_POWER_IF_OFF 5
|
||||
#define LCD_PRIORITY_POWER_ENCL_OFF 4
|
||||
#define LCD_PRIORITY_POWER_ENCL_ON 3
|
||||
#define LCD_PRIORITY_POWER_IF_ON 2
|
||||
#define LCD_PRIORITY_POWER_BL_ON 1
|
||||
#define LCD_PRIORITY_SCREEN_RESTORE 0
|
||||
|
||||
#define LCD_EVENT_BL_ON (1 << 0)
|
||||
#define LCD_EVENT_LCD_ON (1 << 1)
|
||||
#define LCD_EVENT_IF_ON (1 << 2)
|
||||
#define LCD_EVENT_POWER_ON (LCD_EVENT_BL_ON | LCD_EVENT_LCD_ON)
|
||||
#define LCD_EVENT_IF_POWER_ON (LCD_EVENT_BL_ON | LCD_EVENT_IF_ON)
|
||||
#define LCD_EVENT_BLACK_SCREEN (1 << 3)
|
||||
#define LCD_EVENT_BL_OFF (1 << 4)
|
||||
#define LCD_EVENT_LCD_OFF (1 << 5)
|
||||
#define LCD_EVENT_IF_OFF (1 << 6)
|
||||
#define LCD_EVENT_POWER_OFF (LCD_EVENT_BL_OFF | LCD_EVENT_LCD_OFF |\
|
||||
LCD_EVENT_BLACK_SCREEN)
|
||||
#define LCD_EVENT_IF_POWER_OFF (LCD_EVENT_BL_OFF | LCD_EVENT_IF_OFF |\
|
||||
LCD_EVENT_BLACK_SCREEN)
|
||||
/* orignal event */
|
||||
#define LCD_EVENT_SCREEN_BLACK (1 << 0)
|
||||
#define LCD_EVENT_BL_OFF (1 << 1)
|
||||
#define LCD_EVENT_IF_OFF (1 << 2)
|
||||
#define LCD_EVENT_ENCL_OFF (1 << 3)
|
||||
#define LCD_EVENT_ENCL_ON (1 << 4)
|
||||
#define LCD_EVENT_IF_ON (1 << 5)
|
||||
#define LCD_EVENT_BL_ON (1 << 6)
|
||||
#define LCD_EVENT_SCREEN_RESTORE (1 << 7)
|
||||
|
||||
/* combined event */
|
||||
#define LCD_EVENT_POWER_ON (LCD_EVENT_BL_ON | LCD_EVENT_IF_ON | \
|
||||
LCD_EVENT_ENCL_ON | LCD_EVENT_SCREEN_RESTORE)
|
||||
#define LCD_EVENT_IF_POWER_ON (LCD_EVENT_IF_ON | LCD_EVENT_BL_ON | \
|
||||
LCD_EVENT_SCREEN_RESTORE)
|
||||
#define LCD_EVENT_POWER_OFF (LCD_EVENT_SCREEN_BLACK | \
|
||||
LCD_EVENT_BL_OFF | LCD_EVENT_IF_OFF | \
|
||||
LCD_EVENT_ENCL_OFF)
|
||||
#define LCD_EVENT_IF_POWER_OFF (LCD_EVENT_SCREEN_BLACK | \
|
||||
LCD_EVENT_BL_OFF | LCD_EVENT_IF_OFF)
|
||||
|
||||
#define LCD_EVENT_PREPARE (LCD_EVENT_ENCL_ON)
|
||||
#define LCD_EVENT_ENABLE (LCD_EVENT_IF_ON | LCD_EVENT_BL_ON | \
|
||||
LCD_EVENT_SCREEN_RESTORE)
|
||||
#define LCD_EVENT_DISABLE (LCD_EVENT_SCREEN_BLACK | \
|
||||
LCD_EVENT_BL_OFF | LCD_EVENT_IF_OFF)
|
||||
#define LCD_EVENT_UNPREPARE (LCD_EVENT_ENCL_OFF)
|
||||
|
||||
/* lcd backlight index select */
|
||||
#define LCD_EVENT_BACKLIGHT_SEL (1 << 8)
|
||||
|
||||
@@ -396,6 +396,10 @@ struct lcd_duration_s {
|
||||
unsigned int duration_den;
|
||||
};
|
||||
|
||||
#define LCD_STATUS_IF_ON (1 << 0)
|
||||
#define LCD_STATUS_ENCL_ON (1 << 1)
|
||||
#define LCD_STATUS_ON (LCD_STATUS_IF_ON | LCD_STATUS_ENCL_ON)
|
||||
|
||||
struct aml_lcd_drv_s {
|
||||
char *version;
|
||||
struct lcd_data_s *data;
|
||||
@@ -426,15 +430,14 @@ struct aml_lcd_drv_s {
|
||||
|
||||
void (*vout_server_init)(void);
|
||||
void (*driver_init_pre)(void);
|
||||
void (*driver_disable_post)(void);
|
||||
int (*driver_init)(void);
|
||||
void (*driver_disable)(void);
|
||||
int (*driver_change)(void);
|
||||
void (*module_reset)(void);
|
||||
void (*power_tiny_ctrl)(int status);
|
||||
void (*driver_tiny_enable)(void);
|
||||
void (*driver_tiny_disable)(void);
|
||||
void (*module_tiny_reset)(void);
|
||||
void (*lcd_test_pattern_restore)(void);
|
||||
void (*lcd_screen_black)(void);
|
||||
void (*lcd_screen_restore)(void);
|
||||
void (*power_ctrl)(int status);
|
||||
|
||||
struct workqueue_struct *workqueue;
|
||||
@@ -443,6 +446,8 @@ struct aml_lcd_drv_s {
|
||||
struct work_struct lcd_resume_work;
|
||||
struct resource *res_vsync_irq;
|
||||
struct resource *res_vx1_irq;
|
||||
|
||||
struct mutex power_mutex;
|
||||
};
|
||||
|
||||
extern struct aml_lcd_drv_s *aml_lcd_get_driver(void);
|
||||
|
||||
Reference in New Issue
Block a user