From 19155a2d36716c8dc0481d57958fd7e7714dac9e Mon Sep 17 00:00:00 2001 From: Joachim Damm Date: Wed, 22 Jun 2016 20:15:47 +0200 Subject: [PATCH] H3 cec driver fix for crash after resume --- .../video/sunxi/disp2/hdmi/aw/hdmi_bsp_sun8iw7.c | 6 ++- drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c | 49 ++++------------------ drivers/video/sunxi/disp2/hdmi/aw/hdmi_core.c | 1 - 3 files changed, 13 insertions(+), 43 deletions(-) diff --git a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_bsp_sun8iw7.c b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_bsp_sun8iw7.c index cd57651..777ca29 100755 --- a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_bsp_sun8iw7.c +++ b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_bsp_sun8iw7.c @@ -1,6 +1,7 @@ #include "hdmi_bsp_i.h" #include "hdmi_bsp.h" #include "hdmi_core.h" +#include "dw_hdmi.h" static unsigned int hdmi_base_addr; static struct video_para glb_video; @@ -266,7 +267,6 @@ void bsp_hdmi_inner_init(void) hdmi_write(0x10013,0x54); hdmi_write(0x8080, 0x00); hdmi_udelay(1); - hdmi_write(0xF01F, 0x00); hdmi_write(0x8403, 0xff); hdmi_write(0x904C, 0xff); hdmi_write(0x904E, 0xff); @@ -275,9 +275,13 @@ void bsp_hdmi_inner_init(void) hdmi_write(0x8A50, 0xff); hdmi_write(0x8272, 0xff); hdmi_write(0x40C0, 0xff); + hdmi_write(HDMI_PHY_MASK0, 0xff); + hdmi_write(HDMI_IH_MUTE_PHY_STAT0, 0xff); + hdmi_write(HDMI_IH_MUTE_I2CM_STAT0, 0xff); hdmi_write(0x86F0, 0xff); hdmi_write(0x0EE3, 0xff); hdmi_write(0x8EE2, 0xff); + hdmi_write(HDMI_IH_MUTE, 0x00); hdmi_write(0xA049, 0xf0); hdmi_write(0xB045, 0x1e); hdmi_write(0x00C1, 0x00); diff --git a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c index 09db0aa..1ba8e6a 100644 --- a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c +++ b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c @@ -154,7 +154,7 @@ static int sunxi_hdmi_notify(struct notifier_block *nb, if (open_count) { switch (code) { case 0x00: // Unplug - pr_err("HDMI link disconnected\n"); + pr_info("[CEC]HDMI link disconnected\n"); event = vmalloc(sizeof(struct hdmi_cec_event)); if (NULL == event) { pr_err("%s: Not enough memory!\n", __func__); @@ -168,7 +168,7 @@ static int sunxi_hdmi_notify(struct notifier_block *nb, wake_up(&hdmi_cec_queue); break; case 0x04: // Plug - pr_err("HDMI link connected\n"); + pr_info("[CEC]HDMI link connected\n"); event = vmalloc(sizeof(struct hdmi_cec_event)); if (NULL == event) { pr_err("%s: Not enough memory\n", __func__); @@ -182,7 +182,7 @@ static int sunxi_hdmi_notify(struct notifier_block *nb, wake_up(&hdmi_cec_queue); break; case 0x05: // reinit done - pr_err("HDMI reinitialized\n"); + pr_info("[CEC]HDMI reinitialized\n"); val = hdmi_readb(HDMI_MC_CLKDIS); val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE; hdmi_writeb(val, HDMI_MC_CLKDIS); @@ -208,38 +208,6 @@ static struct notifier_block sunxi_hdmi_nb = { .notifier_call = sunxi_hdmi_notify, }; -static void initialize_hdmi_ih_mutes(void) -{ - u8 ih_mute; - - /* - * Boot up defaults are: - * HDMI_IH_MUTE = 0x03 (disabled) - * HDMI_IH_MUTE_* = 0x00 (enabled) - * - * Disable top level interrupt bits in HDMI block - */ - - ih_mute = hdmi_readb(HDMI_IH_MUTE) | - HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | - HDMI_IH_MUTE_MUTE_ALL_INTERRUPT; - - hdmi_writeb(ih_mute, HDMI_IH_MUTE); - - /* FIXME : should be done in HDMI init */ - /* by default mask all interrupts */ - hdmi_writeb(0xff, HDMI_PHY_MASK0); - - /* Disable interrupts in the IH_MUTE_* registers */ - hdmi_writeb(0xff, HDMI_IH_MUTE_PHY_STAT0); - hdmi_writeb(0xff, HDMI_IH_MUTE_I2CM_STAT0); - - /* Enable top level interrupt bits in HDMI block */ - ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | - HDMI_IH_MUTE_MUTE_ALL_INTERRUPT); - hdmi_writeb(ih_mute, HDMI_IH_MUTE); -} - static int hdmi_cec_read_reg_bit(void) /* 1bit */ { return (hdmi_readl(0x1003c) >> 1) & 0x1; @@ -366,7 +334,7 @@ int rxack_thread(void *data) static irqreturn_t hdmi_cec_isr(int irq, void *data) { struct hdmi_cec_priv *hdmi_cec = data; - u16 cec_stat = 0; + u8 cec_stat; unsigned long flags; spin_lock_irqsave(&hdmi_cec->irq_lock, flags); @@ -377,7 +345,7 @@ static irqreturn_t hdmi_cec_isr(int irq, void *data) hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0); if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \ - HDMI_IH_CEC_STAT0_DONE | 0x180)) == 0) { + HDMI_IH_CEC_STAT0_DONE)) == 0) { spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags); return IRQ_HANDLED; } @@ -586,10 +554,10 @@ static ssize_t hdmi_cec_write(struct file *file, const char __user *buf, if (!open_count) return -ENODEV; - /* wait for free line */ + /* wait for free CEC line */ ret = hdmi_wait_free_cecline(); if (ret < 0) { - pr_err("[CEC] no free cec line detected.\n"); + pr_err("[CEC]No free cec line detected.\n"); ret = -ERESTARTSYS; goto tx_out; } @@ -687,7 +655,7 @@ static long hdmi_cec_ioctl(struct file *filp, u_int cmd, mutex_lock(&hdmi_cec_data.lock); if (false == hdmi_cec_data.cec_state) { mutex_unlock(&hdmi_cec_data.lock); - pr_err("Trying to set logical address while not started\n"); + pr_err("[CEC]Trying to set logical address while not started.\n"); return -EACCES; } hdmi_cec_data.Logical_address = (u8)arg; @@ -801,7 +769,6 @@ static int __init hdmi_cec_init(void) goto out; } - initialize_hdmi_ih_mutes(); spin_lock_init(&hdmi_cec_data.irq_lock); hdmi_cec_data.cec_irq = irqhdmi; diff --git a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_core.c b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_core.c index b7f5f83..afa446d 100755 --- a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_core.c +++ b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_core.c @@ -522,6 +522,5 @@ __s32 video_enter_lp(void) __s32 video_exit_lp(void) { bsp_hdmi_init(); - sunxi_hdmi_notifier_call_chain(0x05); return 0; }