summaryrefslogtreecommitdiff
authorZongdong Jiao <zongdong.jiao@amlogic.com>2019-04-24 11:12:21 (GMT)
committer Zongdong Jiao <zongdong.jiao@amlogic.com>2019-04-24 11:12:21 (GMT)
commitbb872121311ca34e911907ad45d21cea92079493 (patch)
tree5917f7a11230087969529bf48a236d9f3d7ea96c
parentce505f753edbb320ea66ab1755b4fadee8b56a6e (diff)
downloadcommon-bb872121311ca34e911907ad45d21cea92079493.zip
common-bb872121311ca34e911907ad45d21cea92079493.tar.gz
common-bb872121311ca34e911907ad45d21cea92079493.tar.bz2
hdmitx: move work_internal_intr to delayed_work [1/1]
PD#SWPL-6894 Problem: Queue work 'work_internal_intr' cause the hdcp22 flicker Solution: Move work_internal_intr to delayed_work Verify: G12/U212 Signed-off-by: Zongdong Jiao <zongdong.jiao@amlogic.com> Change-Id: Icf6849db2c10c5a10a7804869da602ae2d32640d
Diffstat
-rw-r--r--drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c4
-rw-r--r--drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c60
-rw-r--r--include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h2
3 files changed, 34 insertions, 32 deletions
diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c
index 3467cd6..3c76bae 100644
--- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c
+++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c
@@ -3153,7 +3153,7 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work)
static void hdmitx_internal_intr_handler(struct work_struct *work)
{
- struct hdmitx_dev *hdev = container_of((struct work_struct *)work,
+ struct hdmitx_dev *hdev = container_of((struct delayed_work *)work,
struct hdmitx_dev, work_internal_intr);
hdev->HWOp.DebugFun(hdev, "dumpintr");
@@ -3208,7 +3208,7 @@ static int hdmi_task_handle(void *data)
hdmitx_hpd_plugout_handler);
INIT_DELAYED_WORK(&hdmitx_device->work_aud_hpd_plug,
hdmitx_aud_hpd_plug_handler);
- INIT_WORK(&hdmitx_device->work_internal_intr,
+ INIT_DELAYED_WORK(&hdmitx_device->work_internal_intr,
hdmitx_internal_intr_handler);
/* for rx sense feature */
diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c
index 089e278..be02a8c 100644
--- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c
+++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c
@@ -595,33 +595,37 @@ void HDMITX_Meson_Init(struct hdmitx_dev *hdev)
static irqreturn_t intr_handler(int irq, void *dev)
{
- unsigned int data32 = 0;
+ /* get interrupt status */
+ unsigned int dat_top = hdmitx_rd_reg(HDMITX_TOP_INTR_STAT);
+ unsigned int dat_dwc = hdmitx_rd_reg(HDMITX_DWC_HDCP22REG_STAT);
struct hdmitx_dev *hdev = (struct hdmitx_dev *)dev;
- /* get interrupt status */
- data32 = hdmitx_rd_reg(HDMITX_TOP_INTR_STAT);
- pr_info(HW "irq %x\n", data32);
+ /* ack INTERNAL_INTR or else we stuck with no interrupts at all */
+ hdmitx_wr_reg(HDMITX_TOP_INTR_STAT_CLR, ~0);
+ hdmitx_wr_reg(HDMITX_DWC_HDCP22REG_STAT, 0xff);
+
+ pr_info(SYS "irq %x %x\n", dat_top, dat_dwc);
+
if (hdev->hpd_lock == 1) {
- hdmitx_wr_reg(HDMITX_TOP_INTR_STAT_CLR, 0xf);
pr_info(HW "HDMI hpd locked\n");
goto next;
}
/* check HPD status */
- if ((data32 & (1 << 1)) && (data32 & (1 << 2))) {
+ if ((dat_top & (1 << 1)) && (dat_top & (1 << 2))) {
if (hdmitx_hpd_hw_op(HPD_READ_HPD_GPIO))
- data32 &= ~(1 << 2);
+ dat_top &= ~(1 << 2);
else
- data32 &= ~(1 << 1);
+ dat_top &= ~(1 << 1);
}
/* HPD rising */
- if (data32 & (1 << 1)) {
+ if (dat_top & (1 << 1)) {
hdev->hdmitx_event |= HDMI_TX_HPD_PLUGIN;
hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT;
queue_delayed_work(hdev->hdmi_wq,
&hdev->work_hpd_plugin, HZ / 2);
}
/* HPD falling */
- if (data32 & (1 << 2)) {
+ if (dat_top & (1 << 2)) {
queue_delayed_work(hdev->hdmi_wq,
&hdev->work_aud_hpd_plug, 2 * HZ);
hdev->hdmitx_event |= HDMI_TX_HPD_PLUGOUT;
@@ -629,21 +633,19 @@ static irqreturn_t intr_handler(int irq, void *dev)
queue_delayed_work(hdev->hdmi_wq,
&hdev->work_hpd_plugout, HZ / 20);
}
-next:
/* internal interrupt */
- if (data32 & (1 << 0)) {
+ if (dat_top & (1 << 0)) {
hdev->hdmitx_event |= HDMI_TX_INTERNAL_INTR;
- queue_work(hdev->hdmi_wq, &hdev->work_internal_intr);
+ queue_delayed_work(hdev->hdmi_wq,
+ &hdev->work_internal_intr, HZ / 10);
}
- if (data32 & (1 << 3)) {
+ if (dat_top & (1 << 3)) {
unsigned int rd_nonce_mode =
hdmitx_rd_reg(HDMITX_TOP_SKP_CNTL_STAT) & 0x1;
pr_info(HW "hdcp22: Nonce %s Vld: %d\n",
rd_nonce_mode ? "HW" : "SW",
((hdmitx_rd_reg(HDMITX_TOP_SKP_CNTL_STAT) >> 31) & 1));
- if (rd_nonce_mode)
- hdmitx_wr_reg(HDMITX_TOP_INTR_STAT_CLR, (1 << 3));
- else {
+ if (!rd_nonce_mode) {
hdmitx_wr_reg(HDMITX_TOP_NONCE_0, 0x32107654);
hdmitx_wr_reg(HDMITX_TOP_NONCE_1, 0xba98fedc);
hdmitx_wr_reg(HDMITX_TOP_NONCE_2, 0xcdef89ab);
@@ -654,13 +656,10 @@ next:
hdmitx_wr_reg(HDMITX_TOP_NONCE_3, 0x01234567);
}
}
- if (data32 & (1 << 30)) {
- pr_info(HW "hdcp22: reg stat: 0x%x\n",
- hdmitx_rd_reg(HDMITX_DWC_HDCP22REG_STAT));
- hdmitx_wr_reg(HDMITX_DWC_HDCP22REG_STAT, 0xff);
- }
- /* ack INTERNAL_INTR or else we stuck with no interrupts at all */
- hdmitx_wr_reg(HDMITX_TOP_INTR_STAT_CLR, data32 | 0x7);
+ if (dat_top & (1 << 30))
+ pr_info("hdcp22: reg stat: 0x%x\n", dat_dwc);
+
+next:
return IRQ_HANDLED;
}
@@ -2649,11 +2648,9 @@ do { \
#define DUMP_HDMITXREG_SECTION(start, end) \
do { \
- if (start > end) { \
- pr_info("Error start = 0x%lx > end = 0x%lx\n", start, end); \
+ if (start > end) \
break; \
- } \
- pr_info("Start = 0x%lx End = 0x%lx\n", start, end); \
+\
for (addr = start; addr < end + 1; addr++) { \
val = hdmitx_rd_reg(addr); \
if (val) \
@@ -2665,7 +2662,12 @@ static void hdmitx_dump_intr(void)
{
unsigned int addr = 0, val = 0;
- DUMP_HDMITXREG_SECTION(HDMITX_DWC_IH_FC_STAT0, HDMITX_DWC_IH_MUTE);
+ DUMP_HDMITXREG_SECTION(HDMITX_DWC_IH_FC_STAT0,
+ HDMITX_DWC_IH_I2CMPHY_STAT0);
+ DUMP_HDMITXREG_SECTION(HDMITX_DWC_IH_DECODE, HDMITX_DWC_IH_DECODE);
+ DUMP_HDMITXREG_SECTION(HDMITX_DWC_IH_MUTE_FC_STAT0,
+ HDMITX_DWC_IH_MUTE_I2CMPHY_STAT0);
+ DUMP_HDMITXREG_SECTION(HDMITX_DWC_IH_MUTE, HDMITX_DWC_IH_MUTE);
}
static void mode420_half_horizontal_para(void)
diff --git a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h
index 6b0357a..ea3d76c 100644
--- a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h
+++ b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h
@@ -243,7 +243,7 @@ struct hdmitx_dev {
struct delayed_work work_hpd_plugout;
struct delayed_work work_aud_hpd_plug;
struct delayed_work work_rxsense;
- struct work_struct work_internal_intr;
+ struct delayed_work work_internal_intr;
struct work_struct work_hdr;
struct delayed_work work_do_hdcp;
#ifdef CONFIG_AML_HDMI_TX_14