aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorjilai wang <jilaiw@codeaurora.org>2015-08-05 15:33:29 -0400
committerRob Clark <robdclark@gmail.com>2015-08-15 18:27:27 -0400
commit29f034d776209042f7aaaf1518a66841c1d42233 (patch)
treecb86d2a7efe98b87c4695b4b9322f8b414f9fdb5 /drivers/gpu/drm
parent8089082fae1975ad9d5abbd37c0ee8f688be28a0 (diff)
drm/msm/mdp: Clear pending interrupt status before enable interrupt
Pending interrupt status needs to be cleared before enable the interrupt. Otherwise it's possible to get a pending interrupt instead of an incoming interrupt. Signed-off-by: Jilai Wang <jilaiw@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c10
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h3
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c10
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h3
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp_kms.c3
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp_kms.h4
6 files changed, 23 insertions, 10 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c
index 64d24fcbf01a..5ed38cf548a1 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c
@@ -19,8 +19,11 @@
19#include "msm_drv.h" 19#include "msm_drv.h"
20#include "mdp4_kms.h" 20#include "mdp4_kms.h"
21 21
22void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask) 22void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
23 uint32_t old_irqmask)
23{ 24{
25 mdp4_write(to_mdp4_kms(mdp_kms), REG_MDP4_INTR_CLEAR,
26 irqmask ^ (irqmask & old_irqmask));
24 mdp4_write(to_mdp4_kms(mdp_kms), REG_MDP4_INTR_ENABLE, irqmask); 27 mdp4_write(to_mdp4_kms(mdp_kms), REG_MDP4_INTR_ENABLE, irqmask);
25} 28}
26 29
@@ -68,9 +71,10 @@ irqreturn_t mdp4_irq(struct msm_kms *kms)
68 struct drm_device *dev = mdp4_kms->dev; 71 struct drm_device *dev = mdp4_kms->dev;
69 struct msm_drm_private *priv = dev->dev_private; 72 struct msm_drm_private *priv = dev->dev_private;
70 unsigned int id; 73 unsigned int id;
71 uint32_t status; 74 uint32_t status, enable;
72 75
73 status = mdp4_read(mdp4_kms, REG_MDP4_INTR_STATUS); 76 enable = mdp4_read(mdp4_kms, REG_MDP4_INTR_ENABLE);
77 status = mdp4_read(mdp4_kms, REG_MDP4_INTR_STATUS) & enable;
74 mdp4_write(mdp4_kms, REG_MDP4_INTR_CLEAR, status); 78 mdp4_write(mdp4_kms, REG_MDP4_INTR_CLEAR, status);
75 79
76 VERB("status=%08x", status); 80 VERB("status=%08x", status);
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
index ec19c6c9538e..8a7f6e1e2bca 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
@@ -167,7 +167,8 @@ static inline uint32_t mixercfg(uint32_t mixer_cfg, int mixer,
167int mdp4_disable(struct mdp4_kms *mdp4_kms); 167int mdp4_disable(struct mdp4_kms *mdp4_kms);
168int mdp4_enable(struct mdp4_kms *mdp4_kms); 168int mdp4_enable(struct mdp4_kms *mdp4_kms);
169 169
170void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask); 170void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
171 uint32_t old_irqmask);
171void mdp4_irq_preinstall(struct msm_kms *kms); 172void mdp4_irq_preinstall(struct msm_kms *kms);
172int mdp4_irq_postinstall(struct msm_kms *kms); 173int mdp4_irq_postinstall(struct msm_kms *kms);
173void mdp4_irq_uninstall(struct msm_kms *kms); 174void mdp4_irq_uninstall(struct msm_kms *kms);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
index 2a578f2d36dd..b1f73bee1368 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
@@ -21,8 +21,11 @@
21#include "msm_drv.h" 21#include "msm_drv.h"
22#include "mdp5_kms.h" 22#include "mdp5_kms.h"
23 23
24void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask) 24void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
25 uint32_t old_irqmask)
25{ 26{
27 mdp5_write(to_mdp5_kms(mdp_kms), REG_MDP5_MDP_INTR_CLEAR(0),
28 irqmask ^ (irqmask & old_irqmask));
26 mdp5_write(to_mdp5_kms(mdp_kms), REG_MDP5_MDP_INTR_EN(0), irqmask); 29 mdp5_write(to_mdp5_kms(mdp_kms), REG_MDP5_MDP_INTR_EN(0), irqmask);
27} 30}
28 31
@@ -71,9 +74,10 @@ static void mdp5_irq_mdp(struct mdp_kms *mdp_kms)
71 struct drm_device *dev = mdp5_kms->dev; 74 struct drm_device *dev = mdp5_kms->dev;
72 struct msm_drm_private *priv = dev->dev_private; 75 struct msm_drm_private *priv = dev->dev_private;
73 unsigned int id; 76 unsigned int id;
74 uint32_t status; 77 uint32_t status, enable;
75 78
76 status = mdp5_read(mdp5_kms, REG_MDP5_MDP_INTR_STATUS(0)); 79 enable = mdp5_read(mdp5_kms, REG_MDP5_MDP_INTR_EN(0));
80 status = mdp5_read(mdp5_kms, REG_MDP5_MDP_INTR_STATUS(0)) & enable;
77 mdp5_write(mdp5_kms, REG_MDP5_MDP_INTR_CLEAR(0), status); 81 mdp5_write(mdp5_kms, REG_MDP5_MDP_INTR_CLEAR(0), status);
78 82
79 VERB("status=%08x", status); 83 VERB("status=%08x", status);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index 0ef7b992454b..0bb62423586e 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -186,7 +186,8 @@ static inline uint32_t lm2ppdone(int lm)
186int mdp5_disable(struct mdp5_kms *mdp5_kms); 186int mdp5_disable(struct mdp5_kms *mdp5_kms);
187int mdp5_enable(struct mdp5_kms *mdp5_kms); 187int mdp5_enable(struct mdp5_kms *mdp5_kms);
188 188
189void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask); 189void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
190 uint32_t old_irqmask);
190void mdp5_irq_preinstall(struct msm_kms *kms); 191void mdp5_irq_preinstall(struct msm_kms *kms);
191int mdp5_irq_postinstall(struct msm_kms *kms); 192int mdp5_irq_postinstall(struct msm_kms *kms);
192void mdp5_irq_uninstall(struct msm_kms *kms); 193void mdp5_irq_uninstall(struct msm_kms *kms);
diff --git a/drivers/gpu/drm/msm/mdp/mdp_kms.c b/drivers/gpu/drm/msm/mdp/mdp_kms.c
index 1988c243f437..64287304054d 100644
--- a/drivers/gpu/drm/msm/mdp/mdp_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp_kms.c
@@ -39,7 +39,8 @@ static void update_irq(struct mdp_kms *mdp_kms)
39 list_for_each_entry(irq, &mdp_kms->irq_list, node) 39 list_for_each_entry(irq, &mdp_kms->irq_list, node)
40 irqmask |= irq->irqmask; 40 irqmask |= irq->irqmask;
41 41
42 mdp_kms->funcs->set_irqmask(mdp_kms, irqmask); 42 mdp_kms->funcs->set_irqmask(mdp_kms, irqmask, mdp_kms->cur_irq_mask);
43 mdp_kms->cur_irq_mask = irqmask;
43} 44}
44 45
45/* if an mdp_irq's irqmask has changed, such as when mdp5 crtc<->encoder 46/* if an mdp_irq's irqmask has changed, such as when mdp5 crtc<->encoder
diff --git a/drivers/gpu/drm/msm/mdp/mdp_kms.h b/drivers/gpu/drm/msm/mdp/mdp_kms.h
index 867493df98c5..46a94e7d50e2 100644
--- a/drivers/gpu/drm/msm/mdp/mdp_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp_kms.h
@@ -30,7 +30,8 @@ struct mdp_kms;
30 30
31struct mdp_kms_funcs { 31struct mdp_kms_funcs {
32 struct msm_kms_funcs base; 32 struct msm_kms_funcs base;
33 void (*set_irqmask)(struct mdp_kms *mdp_kms, uint32_t irqmask); 33 void (*set_irqmask)(struct mdp_kms *mdp_kms, uint32_t irqmask,
34 uint32_t old_irqmask);
34}; 35};
35 36
36struct mdp_kms { 37struct mdp_kms {
@@ -42,6 +43,7 @@ struct mdp_kms {
42 bool in_irq; 43 bool in_irq;
43 struct list_head irq_list; /* list of mdp4_irq */ 44 struct list_head irq_list; /* list of mdp4_irq */
44 uint32_t vblank_mask; /* irq bits set for userspace vblank */ 45 uint32_t vblank_mask; /* irq bits set for userspace vblank */
46 uint32_t cur_irq_mask; /* current irq mask */
45}; 47};
46#define to_mdp_kms(x) container_of(x, struct mdp_kms, base) 48#define to_mdp_kms(x) container_of(x, struct mdp_kms, base)
47 49