diff options
| author | jilai wang <jilaiw@codeaurora.org> | 2015-08-05 15:33:29 -0400 |
|---|---|---|
| committer | Rob Clark <robdclark@gmail.com> | 2015-08-15 18:27:27 -0400 |
| commit | 29f034d776209042f7aaaf1518a66841c1d42233 (patch) | |
| tree | cb86d2a7efe98b87c4695b4b9322f8b414f9fdb5 /drivers/gpu/drm | |
| parent | 8089082fae1975ad9d5abbd37c0ee8f688be28a0 (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.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp_kms.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp_kms.h | 4 |
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 | ||
| 22 | void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask) | 22 | void 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, | |||
| 167 | int mdp4_disable(struct mdp4_kms *mdp4_kms); | 167 | int mdp4_disable(struct mdp4_kms *mdp4_kms); |
| 168 | int mdp4_enable(struct mdp4_kms *mdp4_kms); | 168 | int mdp4_enable(struct mdp4_kms *mdp4_kms); |
| 169 | 169 | ||
| 170 | void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask); | 170 | void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask, |
| 171 | uint32_t old_irqmask); | ||
| 171 | void mdp4_irq_preinstall(struct msm_kms *kms); | 172 | void mdp4_irq_preinstall(struct msm_kms *kms); |
| 172 | int mdp4_irq_postinstall(struct msm_kms *kms); | 173 | int mdp4_irq_postinstall(struct msm_kms *kms); |
| 173 | void mdp4_irq_uninstall(struct msm_kms *kms); | 174 | void 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 | ||
| 24 | void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask) | 24 | void 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) | |||
| 186 | int mdp5_disable(struct mdp5_kms *mdp5_kms); | 186 | int mdp5_disable(struct mdp5_kms *mdp5_kms); |
| 187 | int mdp5_enable(struct mdp5_kms *mdp5_kms); | 187 | int mdp5_enable(struct mdp5_kms *mdp5_kms); |
| 188 | 188 | ||
| 189 | void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask); | 189 | void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask, |
| 190 | uint32_t old_irqmask); | ||
| 190 | void mdp5_irq_preinstall(struct msm_kms *kms); | 191 | void mdp5_irq_preinstall(struct msm_kms *kms); |
| 191 | int mdp5_irq_postinstall(struct msm_kms *kms); | 192 | int mdp5_irq_postinstall(struct msm_kms *kms); |
| 192 | void mdp5_irq_uninstall(struct msm_kms *kms); | 193 | void 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 | ||
| 31 | struct mdp_kms_funcs { | 31 | struct 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 | ||
| 36 | struct mdp_kms { | 37 | struct 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 | ||
