• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 
19 #include "msm_drv.h"
20 #include "mdp5_kms.h"
21 
mdp5_set_irqmask(struct mdp_kms * mdp_kms,uint32_t irqmask)22 void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask)
23 {
24 	mdp5_write(to_mdp5_kms(mdp_kms), REG_MDP5_INTR_EN, irqmask);
25 }
26 
mdp5_irq_error_handler(struct mdp_irq * irq,uint32_t irqstatus)27 static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
28 {
29 	DRM_ERROR("errors: %08x\n", irqstatus);
30 }
31 
mdp5_irq_preinstall(struct msm_kms * kms)32 void mdp5_irq_preinstall(struct msm_kms *kms)
33 {
34 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
35 	mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, 0xffffffff);
36 }
37 
mdp5_irq_postinstall(struct msm_kms * kms)38 int mdp5_irq_postinstall(struct msm_kms *kms)
39 {
40 	struct mdp_kms *mdp_kms = to_mdp_kms(kms);
41 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
42 	struct mdp_irq *error_handler = &mdp5_kms->error_handler;
43 
44 	error_handler->irq = mdp5_irq_error_handler;
45 	error_handler->irqmask = MDP5_IRQ_INTF0_UNDER_RUN |
46 			MDP5_IRQ_INTF1_UNDER_RUN |
47 			MDP5_IRQ_INTF2_UNDER_RUN |
48 			MDP5_IRQ_INTF3_UNDER_RUN;
49 
50 	mdp_irq_register(mdp_kms, error_handler);
51 
52 	return 0;
53 }
54 
mdp5_irq_uninstall(struct msm_kms * kms)55 void mdp5_irq_uninstall(struct msm_kms *kms)
56 {
57 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
58 	mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
59 }
60 
mdp5_irq_mdp(struct mdp_kms * mdp_kms)61 static void mdp5_irq_mdp(struct mdp_kms *mdp_kms)
62 {
63 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
64 	struct drm_device *dev = mdp5_kms->dev;
65 	struct msm_drm_private *priv = dev->dev_private;
66 	unsigned int id;
67 	uint32_t status;
68 
69 	status = mdp5_read(mdp5_kms, REG_MDP5_INTR_STATUS);
70 	mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, status);
71 
72 	VERB("status=%08x", status);
73 
74 	mdp_dispatch_irqs(mdp_kms, status);
75 
76 	for (id = 0; id < priv->num_crtcs; id++)
77 		if (status & mdp5_crtc_vblank(priv->crtcs[id]))
78 			drm_handle_vblank(dev, id);
79 }
80 
mdp5_irq(struct msm_kms * kms)81 irqreturn_t mdp5_irq(struct msm_kms *kms)
82 {
83 	struct mdp_kms *mdp_kms = to_mdp_kms(kms);
84 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
85 	uint32_t intr;
86 
87 	intr = mdp5_read(mdp5_kms, REG_MDP5_HW_INTR_STATUS);
88 
89 	VERB("intr=%08x", intr);
90 
91 	if (intr & MDP5_HW_INTR_STATUS_INTR_MDP)
92 		mdp5_irq_mdp(mdp_kms);
93 
94 	if (intr & MDP5_HW_INTR_STATUS_INTR_HDMI)
95 		hdmi_irq(0, mdp5_kms->hdmi);
96 
97 	return IRQ_HANDLED;
98 }
99 
mdp5_enable_vblank(struct msm_kms * kms,struct drm_crtc * crtc)100 int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
101 {
102 	mdp_update_vblank_mask(to_mdp_kms(kms),
103 			mdp5_crtc_vblank(crtc), true);
104 	return 0;
105 }
106 
mdp5_disable_vblank(struct msm_kms * kms,struct drm_crtc * crtc)107 void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
108 {
109 	mdp_update_vblank_mask(to_mdp_kms(kms),
110 			mdp5_crtc_vblank(crtc), false);
111 }
112