blob: 10435da1cab1f778827fdbd377c7cd5de836f5b4 [file] [log] [blame]
Abhinav Kumar2316fb92017-01-30 23:07:08 -08001/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
Alan Kwongf5dd86c2016-08-09 18:08:17 -040013#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
14
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070015#include <linux/irqdomain.h>
16#include <linux/irq.h>
Ben Chan78647cd2016-06-26 22:02:47 -040017#include <linux/kthread.h>
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070018
Alan Kwongf5dd86c2016-08-09 18:08:17 -040019#include "sde_irq.h"
20#include "sde_core_irq.h"
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070021
Lloyd Atkinsone5de09d2017-08-21 10:15:38 -040022static uint32_t g_sde_irq_status;
23
Harsh Sahu08a4a742017-09-18 11:42:39 -070024void sde_irq_update(struct msm_kms *msm_kms, bool enable)
25{
Harsh Sahu08a4a742017-09-18 11:42:39 -070026 struct sde_kms *sde_kms = to_sde_kms(msm_kms);
27
28 if (!msm_kms || !sde_kms) {
29 SDE_ERROR("invalid kms arguments\n");
30 return;
31 }
32
Harsh Sahu08a4a742017-09-18 11:42:39 -070033 if (enable)
Alan Kwong9485ecc2017-10-06 18:09:38 -040034 enable_irq(sde_kms->irq_num);
Harsh Sahu08a4a742017-09-18 11:42:39 -070035 else
Alan Kwong9485ecc2017-10-06 18:09:38 -040036 disable_irq(sde_kms->irq_num);
Harsh Sahu08a4a742017-09-18 11:42:39 -070037}
38
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070039irqreturn_t sde_irq(struct msm_kms *kms)
40{
Ben Chan78647cd2016-06-26 22:02:47 -040041 struct sde_kms *sde_kms = to_sde_kms(kms);
42 u32 interrupts;
43
44 sde_kms->hw_intr->ops.get_interrupt_sources(sde_kms->hw_intr,
45 &interrupts);
46
Lloyd Atkinsone5de09d2017-08-21 10:15:38 -040047 /* store irq status in case of irq-storm debugging */
48 g_sde_irq_status = interrupts;
49
Ben Chan78647cd2016-06-26 22:02:47 -040050 /*
51 * Taking care of MDP interrupt
52 */
53 if (interrupts & IRQ_SOURCE_MDP) {
54 interrupts &= ~IRQ_SOURCE_MDP;
Alan Kwongf5dd86c2016-08-09 18:08:17 -040055 sde_core_irq(sde_kms);
Ben Chan78647cd2016-06-26 22:02:47 -040056 }
57
58 /*
59 * Routing all other interrupts to external drivers
60 */
61 while (interrupts) {
62 irq_hw_number_t hwirq = fls(interrupts) - 1;
Lloyd Atkinsone5de09d2017-08-21 10:15:38 -040063 unsigned int mapping;
64 int rc;
Ben Chan78647cd2016-06-26 22:02:47 -040065
Lloyd Atkinsone5de09d2017-08-21 10:15:38 -040066 mapping = irq_find_mapping(sde_kms->irq_controller.domain,
67 hwirq);
68 if (mapping == 0) {
69 SDE_EVT32(hwirq, SDE_EVTLOG_ERROR);
70 goto error;
71 }
72
73 rc = generic_handle_irq(mapping);
74 if (rc < 0) {
75 SDE_EVT32(hwirq, mapping, rc, SDE_EVTLOG_ERROR);
76 goto error;
77 }
78
Ben Chan78647cd2016-06-26 22:02:47 -040079 interrupts &= ~(1 << hwirq);
80 }
81
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070082 return IRQ_HANDLED;
Lloyd Atkinsone5de09d2017-08-21 10:15:38 -040083
84error:
85 /* bad situation, inform irq system, it may disable overall MDSS irq */
86 return IRQ_NONE;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070087}
88
Alan Kwongf5dd86c2016-08-09 18:08:17 -040089void sde_irq_preinstall(struct msm_kms *kms)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070090{
Alan Kwongf5dd86c2016-08-09 18:08:17 -040091 struct sde_kms *sde_kms = to_sde_kms(kms);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070092
Alan Kwongf5dd86c2016-08-09 18:08:17 -040093 if (!sde_kms->dev || !sde_kms->dev->dev) {
94 pr_err("invalid device handles\n");
95 return;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070096 }
Alan Kwongf5dd86c2016-08-09 18:08:17 -040097
98 sde_core_irq_preinstall(sde_kms);
Alan Kwong9485ecc2017-10-06 18:09:38 -040099
100 sde_kms->irq_num = platform_get_irq(sde_kms->dev->platformdev, 0);
101 if (sde_kms->irq_num < 0) {
102 SDE_ERROR("invalid irq number %d\n", sde_kms->irq_num);
103 return;
104 }
105
106 /* disable irq until power event enables it */
Chandan Uddaraju3f2cf422017-06-15 15:37:39 -0700107 if (!sde_kms->cont_splash_en)
108 irq_set_status_flags(sde_kms->irq_num, IRQ_NOAUTOEN);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700109}
110
Alan Kwongf5dd86c2016-08-09 18:08:17 -0400111int sde_irq_postinstall(struct msm_kms *kms)
112{
113 struct sde_kms *sde_kms = to_sde_kms(kms);
114 int rc;
115
116 if (!kms) {
117 SDE_ERROR("invalid parameters\n");
118 return -EINVAL;
119 }
120
121 rc = sde_core_irq_postinstall(sde_kms);
122
123 return rc;
124}
125
126void sde_irq_uninstall(struct msm_kms *kms)
127{
128 struct sde_kms *sde_kms = to_sde_kms(kms);
129
130 if (!kms) {
131 SDE_ERROR("invalid parameters\n");
132 return;
133 }
134
135 sde_core_irq_uninstall(sde_kms);
Abhinav Kumar2316fb92017-01-30 23:07:08 -0800136 sde_core_irq_domain_fini(sde_kms);
Alan Kwongf5dd86c2016-08-09 18:08:17 -0400137}