]>
Commit | Line | Data |
---|---|---|
06c0dd96 RC |
1 | /* |
2 | * Copyright (C) 2013 Red Hat | |
3 | * Author: Rob Clark <robdclark@gmail.com> | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms of the GNU General Public License version 2 as published by | |
7 | * the Free Software Foundation. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
12 | * more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along with | |
15 | * this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | */ | |
17 | ||
f6a8eaca | 18 | #include <linux/irq.h> |
06c0dd96 RC |
19 | |
20 | #include "msm_drv.h" | |
21 | #include "mdp5_kms.h" | |
22 | ||
29f034d7 | 23 | void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask, |
24 | uint32_t old_irqmask) | |
06c0dd96 | 25 | { |
7b59c7e4 AT |
26 | mdp5_write(to_mdp5_kms(mdp_kms), REG_MDP5_INTR_CLEAR, |
27 | irqmask ^ (irqmask & old_irqmask)); | |
28 | mdp5_write(to_mdp5_kms(mdp_kms), REG_MDP5_INTR_EN, irqmask); | |
06c0dd96 RC |
29 | } |
30 | ||
31 | static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus) | |
32 | { | |
49d93e78 | 33 | DRM_ERROR_RATELIMITED("errors: %08x\n", irqstatus); |
06c0dd96 RC |
34 | } |
35 | ||
36 | void mdp5_irq_preinstall(struct msm_kms *kms) | |
37 | { | |
38 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); | |
aa80a4a5 | 39 | mdp5_enable(mdp5_kms); |
7b59c7e4 AT |
40 | mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, 0xffffffff); |
41 | mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000); | |
aa80a4a5 | 42 | mdp5_disable(mdp5_kms); |
06c0dd96 RC |
43 | } |
44 | ||
45 | int mdp5_irq_postinstall(struct msm_kms *kms) | |
46 | { | |
47 | struct mdp_kms *mdp_kms = to_mdp_kms(kms); | |
48 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms); | |
49 | struct mdp_irq *error_handler = &mdp5_kms->error_handler; | |
50 | ||
51 | error_handler->irq = mdp5_irq_error_handler; | |
52 | error_handler->irqmask = MDP5_IRQ_INTF0_UNDER_RUN | | |
53 | MDP5_IRQ_INTF1_UNDER_RUN | | |
54 | MDP5_IRQ_INTF2_UNDER_RUN | | |
55 | MDP5_IRQ_INTF3_UNDER_RUN; | |
56 | ||
7c8f0235 | 57 | mdp5_enable(mdp5_kms); |
06c0dd96 | 58 | mdp_irq_register(mdp_kms, error_handler); |
7c8f0235 | 59 | mdp5_disable(mdp5_kms); |
06c0dd96 RC |
60 | |
61 | return 0; | |
62 | } | |
63 | ||
64 | void mdp5_irq_uninstall(struct msm_kms *kms) | |
65 | { | |
66 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); | |
aa80a4a5 | 67 | mdp5_enable(mdp5_kms); |
7b59c7e4 | 68 | mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000); |
aa80a4a5 | 69 | mdp5_disable(mdp5_kms); |
06c0dd96 RC |
70 | } |
71 | ||
0a6030d2 | 72 | irqreturn_t mdp5_irq(struct msm_kms *kms) |
06c0dd96 | 73 | { |
0a6030d2 | 74 | struct mdp_kms *mdp_kms = to_mdp_kms(kms); |
06c0dd96 RC |
75 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms); |
76 | struct drm_device *dev = mdp5_kms->dev; | |
77 | struct msm_drm_private *priv = dev->dev_private; | |
78 | unsigned int id; | |
29f034d7 | 79 | uint32_t status, enable; |
06c0dd96 | 80 | |
7b59c7e4 AT |
81 | enable = mdp5_read(mdp5_kms, REG_MDP5_INTR_EN); |
82 | status = mdp5_read(mdp5_kms, REG_MDP5_INTR_STATUS) & enable; | |
83 | mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, status); | |
06c0dd96 RC |
84 | |
85 | VERB("status=%08x", status); | |
86 | ||
7d8d9f67 RC |
87 | mdp_dispatch_irqs(mdp_kms, status); |
88 | ||
06c0dd96 RC |
89 | for (id = 0; id < priv->num_crtcs; id++) |
90 | if (status & mdp5_crtc_vblank(priv->crtcs[id])) | |
91 | drm_handle_vblank(dev, id); | |
06c0dd96 RC |
92 | |
93 | return IRQ_HANDLED; | |
94 | } | |
95 | ||
96 | int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) | |
97 | { | |
78b1d470 HL |
98 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); |
99 | ||
100 | mdp5_enable(mdp5_kms); | |
06c0dd96 RC |
101 | mdp_update_vblank_mask(to_mdp_kms(kms), |
102 | mdp5_crtc_vblank(crtc), true); | |
78b1d470 HL |
103 | mdp5_disable(mdp5_kms); |
104 | ||
06c0dd96 RC |
105 | return 0; |
106 | } | |
107 | ||
108 | void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) | |
109 | { | |
78b1d470 HL |
110 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); |
111 | ||
112 | mdp5_enable(mdp5_kms); | |
06c0dd96 RC |
113 | mdp_update_vblank_mask(to_mdp_kms(kms), |
114 | mdp5_crtc_vblank(crtc), false); | |
78b1d470 | 115 | mdp5_disable(mdp5_kms); |
06c0dd96 | 116 | } |