GNU Linux-libre 4.19.207-gnu1
[releases.git] / drivers / gpu / drm / msm / disp / dpu1 / dpu_hw_interrupts.c
1 /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
2  *
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
13 #include <linux/bitops.h>
14 #include <linux/slab.h>
15
16 #include "dpu_kms.h"
17 #include "dpu_hw_interrupts.h"
18 #include "dpu_hw_util.h"
19 #include "dpu_hw_mdss.h"
20
21 /**
22  * Register offsets in MDSS register file for the interrupt registers
23  * w.r.t. to the MDP base
24  */
25 #define MDP_SSPP_TOP0_OFF               0x0
26 #define MDP_INTF_0_OFF                  0x6A000
27 #define MDP_INTF_1_OFF                  0x6A800
28 #define MDP_INTF_2_OFF                  0x6B000
29 #define MDP_INTF_3_OFF                  0x6B800
30 #define MDP_INTF_4_OFF                  0x6C000
31 #define MDP_AD4_0_OFF                   0x7C000
32 #define MDP_AD4_1_OFF                   0x7D000
33 #define MDP_AD4_INTR_EN_OFF             0x41c
34 #define MDP_AD4_INTR_CLEAR_OFF          0x424
35 #define MDP_AD4_INTR_STATUS_OFF         0x420
36
37 /**
38  * WB interrupt status bit definitions
39  */
40 #define DPU_INTR_WB_0_DONE BIT(0)
41 #define DPU_INTR_WB_1_DONE BIT(1)
42 #define DPU_INTR_WB_2_DONE BIT(4)
43
44 /**
45  * WDOG timer interrupt status bit definitions
46  */
47 #define DPU_INTR_WD_TIMER_0_DONE BIT(2)
48 #define DPU_INTR_WD_TIMER_1_DONE BIT(3)
49 #define DPU_INTR_WD_TIMER_2_DONE BIT(5)
50 #define DPU_INTR_WD_TIMER_3_DONE BIT(6)
51 #define DPU_INTR_WD_TIMER_4_DONE BIT(7)
52
53 /**
54  * Pingpong interrupt status bit definitions
55  */
56 #define DPU_INTR_PING_PONG_0_DONE BIT(8)
57 #define DPU_INTR_PING_PONG_1_DONE BIT(9)
58 #define DPU_INTR_PING_PONG_2_DONE BIT(10)
59 #define DPU_INTR_PING_PONG_3_DONE BIT(11)
60 #define DPU_INTR_PING_PONG_0_RD_PTR BIT(12)
61 #define DPU_INTR_PING_PONG_1_RD_PTR BIT(13)
62 #define DPU_INTR_PING_PONG_2_RD_PTR BIT(14)
63 #define DPU_INTR_PING_PONG_3_RD_PTR BIT(15)
64 #define DPU_INTR_PING_PONG_0_WR_PTR BIT(16)
65 #define DPU_INTR_PING_PONG_1_WR_PTR BIT(17)
66 #define DPU_INTR_PING_PONG_2_WR_PTR BIT(18)
67 #define DPU_INTR_PING_PONG_3_WR_PTR BIT(19)
68 #define DPU_INTR_PING_PONG_0_AUTOREFRESH_DONE BIT(20)
69 #define DPU_INTR_PING_PONG_1_AUTOREFRESH_DONE BIT(21)
70 #define DPU_INTR_PING_PONG_2_AUTOREFRESH_DONE BIT(22)
71 #define DPU_INTR_PING_PONG_3_AUTOREFRESH_DONE BIT(23)
72
73 /**
74  * Interface interrupt status bit definitions
75  */
76 #define DPU_INTR_INTF_0_UNDERRUN BIT(24)
77 #define DPU_INTR_INTF_1_UNDERRUN BIT(26)
78 #define DPU_INTR_INTF_2_UNDERRUN BIT(28)
79 #define DPU_INTR_INTF_3_UNDERRUN BIT(30)
80 #define DPU_INTR_INTF_0_VSYNC BIT(25)
81 #define DPU_INTR_INTF_1_VSYNC BIT(27)
82 #define DPU_INTR_INTF_2_VSYNC BIT(29)
83 #define DPU_INTR_INTF_3_VSYNC BIT(31)
84
85 /**
86  * Pingpong Secondary interrupt status bit definitions
87  */
88 #define DPU_INTR_PING_PONG_S0_AUTOREFRESH_DONE BIT(0)
89 #define DPU_INTR_PING_PONG_S0_WR_PTR BIT(4)
90 #define DPU_INTR_PING_PONG_S0_RD_PTR BIT(8)
91 #define DPU_INTR_PING_PONG_S0_TEAR_DETECTED BIT(22)
92 #define DPU_INTR_PING_PONG_S0_TE_DETECTED BIT(28)
93
94 /**
95  * Pingpong TEAR detection interrupt status bit definitions
96  */
97 #define DPU_INTR_PING_PONG_0_TEAR_DETECTED BIT(16)
98 #define DPU_INTR_PING_PONG_1_TEAR_DETECTED BIT(17)
99 #define DPU_INTR_PING_PONG_2_TEAR_DETECTED BIT(18)
100 #define DPU_INTR_PING_PONG_3_TEAR_DETECTED BIT(19)
101
102 /**
103  * Pingpong TE detection interrupt status bit definitions
104  */
105 #define DPU_INTR_PING_PONG_0_TE_DETECTED BIT(24)
106 #define DPU_INTR_PING_PONG_1_TE_DETECTED BIT(25)
107 #define DPU_INTR_PING_PONG_2_TE_DETECTED BIT(26)
108 #define DPU_INTR_PING_PONG_3_TE_DETECTED BIT(27)
109
110 /**
111  * Ctl start interrupt status bit definitions
112  */
113 #define DPU_INTR_CTL_0_START BIT(9)
114 #define DPU_INTR_CTL_1_START BIT(10)
115 #define DPU_INTR_CTL_2_START BIT(11)
116 #define DPU_INTR_CTL_3_START BIT(12)
117 #define DPU_INTR_CTL_4_START BIT(13)
118
119 /**
120  * Concurrent WB overflow interrupt status bit definitions
121  */
122 #define DPU_INTR_CWB_2_OVERFLOW BIT(14)
123 #define DPU_INTR_CWB_3_OVERFLOW BIT(15)
124
125 /**
126  * Histogram VIG done interrupt status bit definitions
127  */
128 #define DPU_INTR_HIST_VIG_0_DONE BIT(0)
129 #define DPU_INTR_HIST_VIG_1_DONE BIT(4)
130 #define DPU_INTR_HIST_VIG_2_DONE BIT(8)
131 #define DPU_INTR_HIST_VIG_3_DONE BIT(10)
132
133 /**
134  * Histogram VIG reset Sequence done interrupt status bit definitions
135  */
136 #define DPU_INTR_HIST_VIG_0_RSTSEQ_DONE BIT(1)
137 #define DPU_INTR_HIST_VIG_1_RSTSEQ_DONE BIT(5)
138 #define DPU_INTR_HIST_VIG_2_RSTSEQ_DONE BIT(9)
139 #define DPU_INTR_HIST_VIG_3_RSTSEQ_DONE BIT(11)
140
141 /**
142  * Histogram DSPP done interrupt status bit definitions
143  */
144 #define DPU_INTR_HIST_DSPP_0_DONE BIT(12)
145 #define DPU_INTR_HIST_DSPP_1_DONE BIT(16)
146 #define DPU_INTR_HIST_DSPP_2_DONE BIT(20)
147 #define DPU_INTR_HIST_DSPP_3_DONE BIT(22)
148
149 /**
150  * Histogram DSPP reset Sequence done interrupt status bit definitions
151  */
152 #define DPU_INTR_HIST_DSPP_0_RSTSEQ_DONE BIT(13)
153 #define DPU_INTR_HIST_DSPP_1_RSTSEQ_DONE BIT(17)
154 #define DPU_INTR_HIST_DSPP_2_RSTSEQ_DONE BIT(21)
155 #define DPU_INTR_HIST_DSPP_3_RSTSEQ_DONE BIT(23)
156
157 /**
158  * INTF interrupt status bit definitions
159  */
160 #define DPU_INTR_VIDEO_INTO_STATIC BIT(0)
161 #define DPU_INTR_VIDEO_OUTOF_STATIC BIT(1)
162 #define DPU_INTR_DSICMD_0_INTO_STATIC BIT(2)
163 #define DPU_INTR_DSICMD_0_OUTOF_STATIC BIT(3)
164 #define DPU_INTR_DSICMD_1_INTO_STATIC BIT(4)
165 #define DPU_INTR_DSICMD_1_OUTOF_STATIC BIT(5)
166 #define DPU_INTR_DSICMD_2_INTO_STATIC BIT(6)
167 #define DPU_INTR_DSICMD_2_OUTOF_STATIC BIT(7)
168 #define DPU_INTR_PROG_LINE BIT(8)
169
170 /**
171  * AD4 interrupt status bit definitions
172  */
173 #define DPU_INTR_BRIGHTPR_UPDATED BIT(4)
174 #define DPU_INTR_DARKENH_UPDATED BIT(3)
175 #define DPU_INTR_STREN_OUTROI_UPDATED BIT(2)
176 #define DPU_INTR_STREN_INROI_UPDATED BIT(1)
177 #define DPU_INTR_BACKLIGHT_UPDATED BIT(0)
178 /**
179  * struct dpu_intr_reg - array of DPU register sets
180  * @clr_off:    offset to CLEAR reg
181  * @en_off:     offset to ENABLE reg
182  * @status_off: offset to STATUS reg
183  */
184 struct dpu_intr_reg {
185         u32 clr_off;
186         u32 en_off;
187         u32 status_off;
188 };
189
190 /**
191  * struct dpu_irq_type - maps each irq with i/f
192  * @intr_type:          type of interrupt listed in dpu_intr_type
193  * @instance_idx:       instance index of the associated HW block in DPU
194  * @irq_mask:           corresponding bit in the interrupt status reg
195  * @reg_idx:            which reg set to use
196  */
197 struct dpu_irq_type {
198         u32 intr_type;
199         u32 instance_idx;
200         u32 irq_mask;
201         u32 reg_idx;
202 };
203
204 /**
205  * List of DPU interrupt registers
206  */
207 static const struct dpu_intr_reg dpu_intr_set[] = {
208         {
209                 MDP_SSPP_TOP0_OFF+INTR_CLEAR,
210                 MDP_SSPP_TOP0_OFF+INTR_EN,
211                 MDP_SSPP_TOP0_OFF+INTR_STATUS
212         },
213         {
214                 MDP_SSPP_TOP0_OFF+INTR2_CLEAR,
215                 MDP_SSPP_TOP0_OFF+INTR2_EN,
216                 MDP_SSPP_TOP0_OFF+INTR2_STATUS
217         },
218         {
219                 MDP_SSPP_TOP0_OFF+HIST_INTR_CLEAR,
220                 MDP_SSPP_TOP0_OFF+HIST_INTR_EN,
221                 MDP_SSPP_TOP0_OFF+HIST_INTR_STATUS
222         },
223         {
224                 MDP_INTF_0_OFF+INTF_INTR_CLEAR,
225                 MDP_INTF_0_OFF+INTF_INTR_EN,
226                 MDP_INTF_0_OFF+INTF_INTR_STATUS
227         },
228         {
229                 MDP_INTF_1_OFF+INTF_INTR_CLEAR,
230                 MDP_INTF_1_OFF+INTF_INTR_EN,
231                 MDP_INTF_1_OFF+INTF_INTR_STATUS
232         },
233         {
234                 MDP_INTF_2_OFF+INTF_INTR_CLEAR,
235                 MDP_INTF_2_OFF+INTF_INTR_EN,
236                 MDP_INTF_2_OFF+INTF_INTR_STATUS
237         },
238         {
239                 MDP_INTF_3_OFF+INTF_INTR_CLEAR,
240                 MDP_INTF_3_OFF+INTF_INTR_EN,
241                 MDP_INTF_3_OFF+INTF_INTR_STATUS
242         },
243         {
244                 MDP_INTF_4_OFF+INTF_INTR_CLEAR,
245                 MDP_INTF_4_OFF+INTF_INTR_EN,
246                 MDP_INTF_4_OFF+INTF_INTR_STATUS
247         },
248         {
249                 MDP_AD4_0_OFF + MDP_AD4_INTR_CLEAR_OFF,
250                 MDP_AD4_0_OFF + MDP_AD4_INTR_EN_OFF,
251                 MDP_AD4_0_OFF + MDP_AD4_INTR_STATUS_OFF,
252         },
253         {
254                 MDP_AD4_1_OFF + MDP_AD4_INTR_CLEAR_OFF,
255                 MDP_AD4_1_OFF + MDP_AD4_INTR_EN_OFF,
256                 MDP_AD4_1_OFF + MDP_AD4_INTR_STATUS_OFF,
257         }
258 };
259
260 /**
261  * IRQ mapping table - use for lookup an irq_idx in this table that have
262  *                     a matching interface type and instance index.
263  */
264 static const struct dpu_irq_type dpu_irq_map[] = {
265         /* BEGIN MAP_RANGE: 0-31, INTR */
266         /* irq_idx: 0-3 */
267         { DPU_IRQ_TYPE_WB_ROT_COMP, WB_0, DPU_INTR_WB_0_DONE, 0},
268         { DPU_IRQ_TYPE_WB_ROT_COMP, WB_1, DPU_INTR_WB_1_DONE, 0},
269         { DPU_IRQ_TYPE_WD_TIMER, WD_TIMER_0, DPU_INTR_WD_TIMER_0_DONE, 0},
270         { DPU_IRQ_TYPE_WD_TIMER, WD_TIMER_1, DPU_INTR_WD_TIMER_1_DONE, 0},
271         /* irq_idx: 4-7 */
272         { DPU_IRQ_TYPE_WB_WFD_COMP, WB_2, DPU_INTR_WB_2_DONE, 0},
273         { DPU_IRQ_TYPE_WD_TIMER, WD_TIMER_2, DPU_INTR_WD_TIMER_2_DONE, 0},
274         { DPU_IRQ_TYPE_WD_TIMER, WD_TIMER_3, DPU_INTR_WD_TIMER_3_DONE, 0},
275         { DPU_IRQ_TYPE_WD_TIMER, WD_TIMER_4, DPU_INTR_WD_TIMER_4_DONE, 0},
276         /* irq_idx: 8-11 */
277         { DPU_IRQ_TYPE_PING_PONG_COMP, PINGPONG_0,
278                 DPU_INTR_PING_PONG_0_DONE, 0},
279         { DPU_IRQ_TYPE_PING_PONG_COMP, PINGPONG_1,
280                 DPU_INTR_PING_PONG_1_DONE, 0},
281         { DPU_IRQ_TYPE_PING_PONG_COMP, PINGPONG_2,
282                 DPU_INTR_PING_PONG_2_DONE, 0},
283         { DPU_IRQ_TYPE_PING_PONG_COMP, PINGPONG_3,
284                 DPU_INTR_PING_PONG_3_DONE, 0},
285         /* irq_idx: 12-15 */
286         { DPU_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_0,
287                 DPU_INTR_PING_PONG_0_RD_PTR, 0},
288         { DPU_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_1,
289                 DPU_INTR_PING_PONG_1_RD_PTR, 0},
290         { DPU_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_2,
291                 DPU_INTR_PING_PONG_2_RD_PTR, 0},
292         { DPU_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_3,
293                 DPU_INTR_PING_PONG_3_RD_PTR, 0},
294         /* irq_idx: 16-19 */
295         { DPU_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_0,
296                 DPU_INTR_PING_PONG_0_WR_PTR, 0},
297         { DPU_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_1,
298                 DPU_INTR_PING_PONG_1_WR_PTR, 0},
299         { DPU_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_2,
300                 DPU_INTR_PING_PONG_2_WR_PTR, 0},
301         { DPU_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_3,
302                 DPU_INTR_PING_PONG_3_WR_PTR, 0},
303         /* irq_idx: 20-23 */
304         { DPU_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_0,
305                 DPU_INTR_PING_PONG_0_AUTOREFRESH_DONE, 0},
306         { DPU_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_1,
307                 DPU_INTR_PING_PONG_1_AUTOREFRESH_DONE, 0},
308         { DPU_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_2,
309                 DPU_INTR_PING_PONG_2_AUTOREFRESH_DONE, 0},
310         { DPU_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_3,
311                 DPU_INTR_PING_PONG_3_AUTOREFRESH_DONE, 0},
312         /* irq_idx: 24-27 */
313         { DPU_IRQ_TYPE_INTF_UNDER_RUN, INTF_0, DPU_INTR_INTF_0_UNDERRUN, 0},
314         { DPU_IRQ_TYPE_INTF_VSYNC, INTF_0, DPU_INTR_INTF_0_VSYNC, 0},
315         { DPU_IRQ_TYPE_INTF_UNDER_RUN, INTF_1, DPU_INTR_INTF_1_UNDERRUN, 0},
316         { DPU_IRQ_TYPE_INTF_VSYNC, INTF_1, DPU_INTR_INTF_1_VSYNC, 0},
317         /* irq_idx: 28-31 */
318         { DPU_IRQ_TYPE_INTF_UNDER_RUN, INTF_2, DPU_INTR_INTF_2_UNDERRUN, 0},
319         { DPU_IRQ_TYPE_INTF_VSYNC, INTF_2, DPU_INTR_INTF_2_VSYNC, 0},
320         { DPU_IRQ_TYPE_INTF_UNDER_RUN, INTF_3, DPU_INTR_INTF_3_UNDERRUN, 0},
321         { DPU_IRQ_TYPE_INTF_VSYNC, INTF_3, DPU_INTR_INTF_3_VSYNC, 0},
322
323         /* BEGIN MAP_RANGE: 32-64, INTR2 */
324         /* irq_idx: 32-35 */
325         { DPU_IRQ_TYPE_PING_PONG_AUTO_REF, PINGPONG_S0,
326                 DPU_INTR_PING_PONG_S0_AUTOREFRESH_DONE, 1},
327         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
328         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
329         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
330         /* irq_idx: 36-39 */
331         { DPU_IRQ_TYPE_PING_PONG_WR_PTR, PINGPONG_S0,
332                 DPU_INTR_PING_PONG_S0_WR_PTR, 1},
333         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
334         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
335         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
336         /* irq_idx: 40 */
337         { DPU_IRQ_TYPE_PING_PONG_RD_PTR, PINGPONG_S0,
338                 DPU_INTR_PING_PONG_S0_RD_PTR, 1},
339         /* irq_idx: 41-45 */
340         { DPU_IRQ_TYPE_CTL_START, CTL_0,
341                 DPU_INTR_CTL_0_START, 1},
342         { DPU_IRQ_TYPE_CTL_START, CTL_1,
343                 DPU_INTR_CTL_1_START, 1},
344         { DPU_IRQ_TYPE_CTL_START, CTL_2,
345                 DPU_INTR_CTL_2_START, 1},
346         { DPU_IRQ_TYPE_CTL_START, CTL_3,
347                 DPU_INTR_CTL_3_START, 1},
348         { DPU_IRQ_TYPE_CTL_START, CTL_4,
349                 DPU_INTR_CTL_4_START, 1},
350         /* irq_idx: 46-47 */
351         { DPU_IRQ_TYPE_CWB_OVERFLOW, CWB_2, DPU_INTR_CWB_2_OVERFLOW, 1},
352         { DPU_IRQ_TYPE_CWB_OVERFLOW, CWB_3, DPU_INTR_CWB_3_OVERFLOW, 1},
353         /* irq_idx: 48-51 */
354         { DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_0,
355                 DPU_INTR_PING_PONG_0_TEAR_DETECTED, 1},
356         { DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_1,
357                 DPU_INTR_PING_PONG_1_TEAR_DETECTED, 1},
358         { DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_2,
359                 DPU_INTR_PING_PONG_2_TEAR_DETECTED, 1},
360         { DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_3,
361                 DPU_INTR_PING_PONG_3_TEAR_DETECTED, 1},
362         /* irq_idx: 52-55 */
363         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
364         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
365         { DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, PINGPONG_S0,
366                 DPU_INTR_PING_PONG_S0_TEAR_DETECTED, 1},
367         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
368         /* irq_idx: 56-59 */
369         { DPU_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_0,
370                 DPU_INTR_PING_PONG_0_TE_DETECTED, 1},
371         { DPU_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_1,
372                 DPU_INTR_PING_PONG_1_TE_DETECTED, 1},
373         { DPU_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_2,
374                 DPU_INTR_PING_PONG_2_TE_DETECTED, 1},
375         { DPU_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_3,
376                 DPU_INTR_PING_PONG_3_TE_DETECTED, 1},
377         /* irq_idx: 60-63 */
378         { DPU_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_S0,
379                 DPU_INTR_PING_PONG_S0_TE_DETECTED, 1},
380         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
381         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
382         { DPU_IRQ_TYPE_RESERVED, 0, 0, 1},
383
384         /* BEGIN MAP_RANGE: 64-95 HIST */
385         /* irq_idx: 64-67 */
386         { DPU_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG0, DPU_INTR_HIST_VIG_0_DONE, 2},
387         { DPU_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG0,
388                 DPU_INTR_HIST_VIG_0_RSTSEQ_DONE, 2},
389         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
390         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
391         /* irq_idx: 68-71 */
392         { DPU_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG1, DPU_INTR_HIST_VIG_1_DONE, 2},
393         { DPU_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG1,
394                 DPU_INTR_HIST_VIG_1_RSTSEQ_DONE, 2},
395         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
396         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
397         /* irq_idx: 72-75 */
398         { DPU_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG2, DPU_INTR_HIST_VIG_2_DONE, 2},
399         { DPU_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG2,
400                 DPU_INTR_HIST_VIG_2_RSTSEQ_DONE, 2},
401         { DPU_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG3, DPU_INTR_HIST_VIG_3_DONE, 2},
402         { DPU_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG3,
403                 DPU_INTR_HIST_VIG_3_RSTSEQ_DONE, 2},
404         /* irq_idx: 76-79 */
405         { DPU_IRQ_TYPE_HIST_DSPP_DONE, DSPP_0, DPU_INTR_HIST_DSPP_0_DONE, 2},
406         { DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_0,
407                 DPU_INTR_HIST_DSPP_0_RSTSEQ_DONE, 2},
408         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
409         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
410         /* irq_idx: 80-83 */
411         { DPU_IRQ_TYPE_HIST_DSPP_DONE, DSPP_1, DPU_INTR_HIST_DSPP_1_DONE, 2},
412         { DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_1,
413                 DPU_INTR_HIST_DSPP_1_RSTSEQ_DONE, 2},
414         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
415         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
416         /* irq_idx: 84-87 */
417         { DPU_IRQ_TYPE_HIST_DSPP_DONE, DSPP_2, DPU_INTR_HIST_DSPP_2_DONE, 2},
418         { DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_2,
419                 DPU_INTR_HIST_DSPP_2_RSTSEQ_DONE, 2},
420         { DPU_IRQ_TYPE_HIST_DSPP_DONE, DSPP_3, DPU_INTR_HIST_DSPP_3_DONE, 2},
421         { DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_3,
422                 DPU_INTR_HIST_DSPP_3_RSTSEQ_DONE, 2},
423         /* irq_idx: 88-91 */
424         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
425         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
426         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
427         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
428         /* irq_idx: 92-95 */
429         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
430         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
431         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
432         { DPU_IRQ_TYPE_RESERVED, 0, 0, 2},
433
434         /* BEGIN MAP_RANGE: 96-127 INTF_0_INTR */
435         /* irq_idx: 96-99 */
436         { DPU_IRQ_TYPE_SFI_VIDEO_IN, INTF_0,
437                 DPU_INTR_VIDEO_INTO_STATIC, 3},
438         { DPU_IRQ_TYPE_SFI_VIDEO_OUT, INTF_0,
439                 DPU_INTR_VIDEO_OUTOF_STATIC, 3},
440         { DPU_IRQ_TYPE_SFI_CMD_0_IN, INTF_0,
441                 DPU_INTR_DSICMD_0_INTO_STATIC, 3},
442         { DPU_IRQ_TYPE_SFI_CMD_0_OUT, INTF_0,
443                 DPU_INTR_DSICMD_0_OUTOF_STATIC, 3},
444         /* irq_idx: 100-103 */
445         { DPU_IRQ_TYPE_SFI_CMD_1_IN, INTF_0,
446                 DPU_INTR_DSICMD_1_INTO_STATIC, 3},
447         { DPU_IRQ_TYPE_SFI_CMD_1_OUT, INTF_0,
448                 DPU_INTR_DSICMD_1_OUTOF_STATIC, 3},
449         { DPU_IRQ_TYPE_SFI_CMD_2_IN, INTF_0,
450                 DPU_INTR_DSICMD_2_INTO_STATIC, 3},
451         { DPU_IRQ_TYPE_SFI_CMD_2_OUT, INTF_0,
452                 DPU_INTR_DSICMD_2_OUTOF_STATIC, 3},
453         /* irq_idx: 104-107 */
454         { DPU_IRQ_TYPE_PROG_LINE, INTF_0, DPU_INTR_PROG_LINE, 3},
455         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
456         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
457         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
458         /* irq_idx: 108-111 */
459         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
460         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
461         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
462         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
463         /* irq_idx: 112-115 */
464         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
465         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
466         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
467         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
468         /* irq_idx: 116-119 */
469         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
470         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
471         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
472         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
473         /* irq_idx: 120-123 */
474         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
475         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
476         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
477         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
478         /* irq_idx: 124-127 */
479         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
480         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
481         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
482         { DPU_IRQ_TYPE_RESERVED, 0, 0, 3},
483
484         /* BEGIN MAP_RANGE: 128-159 INTF_1_INTR */
485         /* irq_idx: 128-131 */
486         { DPU_IRQ_TYPE_SFI_VIDEO_IN, INTF_1,
487                 DPU_INTR_VIDEO_INTO_STATIC, 4},
488         { DPU_IRQ_TYPE_SFI_VIDEO_OUT, INTF_1,
489                 DPU_INTR_VIDEO_OUTOF_STATIC, 4},
490         { DPU_IRQ_TYPE_SFI_CMD_0_IN, INTF_1,
491                 DPU_INTR_DSICMD_0_INTO_STATIC, 4},
492         { DPU_IRQ_TYPE_SFI_CMD_0_OUT, INTF_1,
493                 DPU_INTR_DSICMD_0_OUTOF_STATIC, 4},
494         /* irq_idx: 132-135 */
495         { DPU_IRQ_TYPE_SFI_CMD_1_IN, INTF_1,
496                 DPU_INTR_DSICMD_1_INTO_STATIC, 4},
497         { DPU_IRQ_TYPE_SFI_CMD_1_OUT, INTF_1,
498                 DPU_INTR_DSICMD_1_OUTOF_STATIC, 4},
499         { DPU_IRQ_TYPE_SFI_CMD_2_IN, INTF_1,
500                 DPU_INTR_DSICMD_2_INTO_STATIC, 4},
501         { DPU_IRQ_TYPE_SFI_CMD_2_OUT, INTF_1,
502                 DPU_INTR_DSICMD_2_OUTOF_STATIC, 4},
503         /* irq_idx: 136-139 */
504         { DPU_IRQ_TYPE_PROG_LINE, INTF_1, DPU_INTR_PROG_LINE, 4},
505         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
506         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
507         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
508         /* irq_idx: 140-143 */
509         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
510         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
511         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
512         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
513         /* irq_idx: 144-147 */
514         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
515         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
516         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
517         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
518         /* irq_idx: 148-151 */
519         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
520         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
521         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
522         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
523         /* irq_idx: 152-155 */
524         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
525         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
526         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
527         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
528         /* irq_idx: 156-159 */
529         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
530         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
531         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
532         { DPU_IRQ_TYPE_RESERVED, 0, 0, 4},
533
534         /* BEGIN MAP_RANGE: 160-191 INTF_2_INTR */
535         /* irq_idx: 160-163 */
536         { DPU_IRQ_TYPE_SFI_VIDEO_IN, INTF_2,
537                 DPU_INTR_VIDEO_INTO_STATIC, 5},
538         { DPU_IRQ_TYPE_SFI_VIDEO_OUT, INTF_2,
539                 DPU_INTR_VIDEO_OUTOF_STATIC, 5},
540         { DPU_IRQ_TYPE_SFI_CMD_0_IN, INTF_2,
541                 DPU_INTR_DSICMD_0_INTO_STATIC, 5},
542         { DPU_IRQ_TYPE_SFI_CMD_0_OUT, INTF_2,
543                 DPU_INTR_DSICMD_0_OUTOF_STATIC, 5},
544         /* irq_idx: 164-167 */
545         { DPU_IRQ_TYPE_SFI_CMD_1_IN, INTF_2,
546                 DPU_INTR_DSICMD_1_INTO_STATIC, 5},
547         { DPU_IRQ_TYPE_SFI_CMD_1_OUT, INTF_2,
548                 DPU_INTR_DSICMD_1_OUTOF_STATIC, 5},
549         { DPU_IRQ_TYPE_SFI_CMD_2_IN, INTF_2,
550                 DPU_INTR_DSICMD_2_INTO_STATIC, 5},
551         { DPU_IRQ_TYPE_SFI_CMD_2_OUT, INTF_2,
552                 DPU_INTR_DSICMD_2_OUTOF_STATIC, 5},
553         /* irq_idx: 168-171 */
554         { DPU_IRQ_TYPE_PROG_LINE, INTF_2, DPU_INTR_PROG_LINE, 5},
555         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
556         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
557         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
558         /* irq_idx: 172-175 */
559         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
560         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
561         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
562         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
563         /* irq_idx: 176-179 */
564         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
565         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
566         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
567         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
568         /* irq_idx: 180-183 */
569         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
570         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
571         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
572         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
573         /* irq_idx: 184-187 */
574         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
575         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
576         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
577         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
578         /* irq_idx: 188-191 */
579         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
580         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
581         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
582         { DPU_IRQ_TYPE_RESERVED, 0, 0, 5},
583
584         /* BEGIN MAP_RANGE: 192-223 INTF_3_INTR */
585         /* irq_idx: 192-195 */
586         { DPU_IRQ_TYPE_SFI_VIDEO_IN, INTF_3,
587                 DPU_INTR_VIDEO_INTO_STATIC, 6},
588         { DPU_IRQ_TYPE_SFI_VIDEO_OUT, INTF_3,
589                 DPU_INTR_VIDEO_OUTOF_STATIC, 6},
590         { DPU_IRQ_TYPE_SFI_CMD_0_IN, INTF_3,
591                 DPU_INTR_DSICMD_0_INTO_STATIC, 6},
592         { DPU_IRQ_TYPE_SFI_CMD_0_OUT, INTF_3,
593                 DPU_INTR_DSICMD_0_OUTOF_STATIC, 6},
594         /* irq_idx: 196-199 */
595         { DPU_IRQ_TYPE_SFI_CMD_1_IN, INTF_3,
596                 DPU_INTR_DSICMD_1_INTO_STATIC, 6},
597         { DPU_IRQ_TYPE_SFI_CMD_1_OUT, INTF_3,
598                 DPU_INTR_DSICMD_1_OUTOF_STATIC, 6},
599         { DPU_IRQ_TYPE_SFI_CMD_2_IN, INTF_3,
600                 DPU_INTR_DSICMD_2_INTO_STATIC, 6},
601         { DPU_IRQ_TYPE_SFI_CMD_2_OUT, INTF_3,
602                 DPU_INTR_DSICMD_2_OUTOF_STATIC, 6},
603         /* irq_idx: 200-203 */
604         { DPU_IRQ_TYPE_PROG_LINE, INTF_3, DPU_INTR_PROG_LINE, 6},
605         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
606         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
607         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
608         /* irq_idx: 204-207 */
609         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
610         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
611         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
612         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
613         /* irq_idx: 208-211 */
614         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
615         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
616         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
617         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
618         /* irq_idx: 212-215 */
619         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
620         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
621         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
622         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
623         /* irq_idx: 216-219 */
624         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
625         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
626         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
627         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
628         /* irq_idx: 220-223 */
629         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
630         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
631         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
632         { DPU_IRQ_TYPE_RESERVED, 0, 0, 6},
633
634         /* BEGIN MAP_RANGE: 224-255 INTF_4_INTR */
635         /* irq_idx: 224-227 */
636         { DPU_IRQ_TYPE_SFI_VIDEO_IN, INTF_4,
637                 DPU_INTR_VIDEO_INTO_STATIC, 7},
638         { DPU_IRQ_TYPE_SFI_VIDEO_OUT, INTF_4,
639                 DPU_INTR_VIDEO_OUTOF_STATIC, 7},
640         { DPU_IRQ_TYPE_SFI_CMD_0_IN, INTF_4,
641                 DPU_INTR_DSICMD_0_INTO_STATIC, 7},
642         { DPU_IRQ_TYPE_SFI_CMD_0_OUT, INTF_4,
643                 DPU_INTR_DSICMD_0_OUTOF_STATIC, 7},
644         /* irq_idx: 228-231 */
645         { DPU_IRQ_TYPE_SFI_CMD_1_IN, INTF_4,
646                 DPU_INTR_DSICMD_1_INTO_STATIC, 7},
647         { DPU_IRQ_TYPE_SFI_CMD_1_OUT, INTF_4,
648                 DPU_INTR_DSICMD_1_OUTOF_STATIC, 7},
649         { DPU_IRQ_TYPE_SFI_CMD_2_IN, INTF_4,
650                 DPU_INTR_DSICMD_2_INTO_STATIC, 7},
651         { DPU_IRQ_TYPE_SFI_CMD_2_OUT, INTF_4,
652                 DPU_INTR_DSICMD_2_OUTOF_STATIC, 7},
653         /* irq_idx: 232-235 */
654         { DPU_IRQ_TYPE_PROG_LINE, INTF_4, DPU_INTR_PROG_LINE, 7},
655         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
656         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
657         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
658         /* irq_idx: 236-239 */
659         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
660         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
661         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
662         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
663         /* irq_idx: 240-243 */
664         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
665         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
666         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
667         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
668         /* irq_idx: 244-247 */
669         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
670         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
671         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
672         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
673         /* irq_idx: 248-251 */
674         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
675         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
676         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
677         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
678         /* irq_idx: 252-255 */
679         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
680         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
681         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
682         { DPU_IRQ_TYPE_RESERVED, 0, 0, 7},
683
684         /* BEGIN MAP_RANGE: 256-287 AD4_0_INTR */
685         /* irq_idx: 256-259 */
686         { DPU_IRQ_TYPE_AD4_BL_DONE, DSPP_0, DPU_INTR_BACKLIGHT_UPDATED, 8},
687         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
688         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
689         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
690         /* irq_idx: 260-263 */
691         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
692         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
693         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
694         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
695         /* irq_idx: 264-267 */
696         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
697         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
698         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
699         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
700         /* irq_idx: 268-271 */
701         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
702         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
703         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
704         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
705         /* irq_idx: 272-275 */
706         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
707         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
708         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
709         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
710         /* irq_idx: 276-279 */
711         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
712         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
713         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
714         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
715         /* irq_idx: 280-283 */
716         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
717         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
718         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
719         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
720         /* irq_idx: 284-287 */
721         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
722         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
723         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
724         { DPU_IRQ_TYPE_RESERVED, 0, 0, 8},
725
726         /* BEGIN MAP_RANGE: 288-319 AD4_1_INTR */
727         /* irq_idx: 288-291 */
728         { DPU_IRQ_TYPE_AD4_BL_DONE, DSPP_1, DPU_INTR_BACKLIGHT_UPDATED, 9},
729         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
730         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
731         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
732         /* irq_idx: 292-295 */
733         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
734         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
735         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
736         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
737         /* irq_idx: 296-299 */
738         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
739         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
740         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
741         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
742         /* irq_idx: 300-303 */
743         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
744         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
745         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
746         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
747         /* irq_idx: 304-307 */
748         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
749         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
750         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
751         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
752         /* irq_idx: 308-311 */
753         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
754         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
755         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
756         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
757         /* irq_idx: 312-315 */
758         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
759         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
760         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
761         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
762         /* irq_idx: 315-319 */
763         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
764         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
765         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
766         { DPU_IRQ_TYPE_RESERVED, 0, 0, 9},
767 };
768
769 static int dpu_hw_intr_irqidx_lookup(enum dpu_intr_type intr_type,
770                 u32 instance_idx)
771 {
772         int i;
773
774         for (i = 0; i < ARRAY_SIZE(dpu_irq_map); i++) {
775                 if (intr_type == dpu_irq_map[i].intr_type &&
776                         instance_idx == dpu_irq_map[i].instance_idx)
777                         return i;
778         }
779
780         pr_debug("IRQ lookup fail!! intr_type=%d, instance_idx=%d\n",
781                         intr_type, instance_idx);
782         return -EINVAL;
783 }
784
785 static void dpu_hw_intr_set_mask(struct dpu_hw_intr *intr, uint32_t reg_off,
786                 uint32_t mask)
787 {
788         if (!intr)
789                 return;
790
791         DPU_REG_WRITE(&intr->hw, reg_off, mask);
792
793         /* ensure register writes go through */
794         wmb();
795 }
796
797 static void dpu_hw_intr_dispatch_irq(struct dpu_hw_intr *intr,
798                 void (*cbfunc)(void *, int),
799                 void *arg)
800 {
801         int reg_idx;
802         int irq_idx;
803         int start_idx;
804         int end_idx;
805         u32 irq_status;
806         unsigned long irq_flags;
807
808         if (!intr)
809                 return;
810
811         /*
812          * The dispatcher will save the IRQ status before calling here.
813          * Now need to go through each IRQ status and find matching
814          * irq lookup index.
815          */
816         spin_lock_irqsave(&intr->irq_lock, irq_flags);
817         for (reg_idx = 0; reg_idx < ARRAY_SIZE(dpu_intr_set); reg_idx++) {
818                 irq_status = intr->save_irq_status[reg_idx];
819
820                 /*
821                  * Each Interrupt register has a range of 32 indexes, and
822                  * that is static for dpu_irq_map.
823                  */
824                 start_idx = reg_idx * 32;
825                 end_idx = start_idx + 32;
826
827                 if (start_idx >= ARRAY_SIZE(dpu_irq_map) ||
828                                 end_idx > ARRAY_SIZE(dpu_irq_map))
829                         continue;
830
831                 /*
832                  * Search through matching intr status from irq map.
833                  * start_idx and end_idx defined the search range in
834                  * the dpu_irq_map.
835                  */
836                 for (irq_idx = start_idx;
837                                 (irq_idx < end_idx) && irq_status;
838                                 irq_idx++)
839                         if ((irq_status & dpu_irq_map[irq_idx].irq_mask) &&
840                                 (dpu_irq_map[irq_idx].reg_idx == reg_idx)) {
841                                 /*
842                                  * Once a match on irq mask, perform a callback
843                                  * to the given cbfunc. cbfunc will take care
844                                  * the interrupt status clearing. If cbfunc is
845                                  * not provided, then the interrupt clearing
846                                  * is here.
847                                  */
848                                 if (cbfunc)
849                                         cbfunc(arg, irq_idx);
850                                 else
851                                         intr->ops.clear_intr_status_nolock(
852                                                         intr, irq_idx);
853
854                                 /*
855                                  * When callback finish, clear the irq_status
856                                  * with the matching mask. Once irq_status
857                                  * is all cleared, the search can be stopped.
858                                  */
859                                 irq_status &= ~dpu_irq_map[irq_idx].irq_mask;
860                         }
861         }
862         spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
863 }
864
865 static int dpu_hw_intr_enable_irq(struct dpu_hw_intr *intr, int irq_idx)
866 {
867         int reg_idx;
868         unsigned long irq_flags;
869         const struct dpu_intr_reg *reg;
870         const struct dpu_irq_type *irq;
871         const char *dbgstr = NULL;
872         uint32_t cache_irq_mask;
873
874         if (!intr)
875                 return -EINVAL;
876
877         if (irq_idx < 0 || irq_idx >= ARRAY_SIZE(dpu_irq_map)) {
878                 pr_err("invalid IRQ index: [%d]\n", irq_idx);
879                 return -EINVAL;
880         }
881
882         irq = &dpu_irq_map[irq_idx];
883         reg_idx = irq->reg_idx;
884         reg = &dpu_intr_set[reg_idx];
885
886         spin_lock_irqsave(&intr->irq_lock, irq_flags);
887         cache_irq_mask = intr->cache_irq_mask[reg_idx];
888         if (cache_irq_mask & irq->irq_mask) {
889                 dbgstr = "DPU IRQ already set:";
890         } else {
891                 dbgstr = "DPU IRQ enabled:";
892
893                 cache_irq_mask |= irq->irq_mask;
894                 /* Cleaning any pending interrupt */
895                 DPU_REG_WRITE(&intr->hw, reg->clr_off, irq->irq_mask);
896                 /* Enabling interrupts with the new mask */
897                 DPU_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask);
898
899                 /* ensure register write goes through */
900                 wmb();
901
902                 intr->cache_irq_mask[reg_idx] = cache_irq_mask;
903         }
904         spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
905
906         pr_debug("%s MASK:0x%.8x, CACHE-MASK:0x%.8x\n", dbgstr,
907                         irq->irq_mask, cache_irq_mask);
908
909         return 0;
910 }
911
912 static int dpu_hw_intr_disable_irq_nolock(struct dpu_hw_intr *intr, int irq_idx)
913 {
914         int reg_idx;
915         const struct dpu_intr_reg *reg;
916         const struct dpu_irq_type *irq;
917         const char *dbgstr = NULL;
918         uint32_t cache_irq_mask;
919
920         if (!intr)
921                 return -EINVAL;
922
923         if (irq_idx < 0 || irq_idx >= ARRAY_SIZE(dpu_irq_map)) {
924                 pr_err("invalid IRQ index: [%d]\n", irq_idx);
925                 return -EINVAL;
926         }
927
928         irq = &dpu_irq_map[irq_idx];
929         reg_idx = irq->reg_idx;
930         reg = &dpu_intr_set[reg_idx];
931
932         cache_irq_mask = intr->cache_irq_mask[reg_idx];
933         if ((cache_irq_mask & irq->irq_mask) == 0) {
934                 dbgstr = "DPU IRQ is already cleared:";
935         } else {
936                 dbgstr = "DPU IRQ mask disable:";
937
938                 cache_irq_mask &= ~irq->irq_mask;
939                 /* Disable interrupts based on the new mask */
940                 DPU_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask);
941                 /* Cleaning any pending interrupt */
942                 DPU_REG_WRITE(&intr->hw, reg->clr_off, irq->irq_mask);
943
944                 /* ensure register write goes through */
945                 wmb();
946
947                 intr->cache_irq_mask[reg_idx] = cache_irq_mask;
948         }
949
950         pr_debug("%s MASK:0x%.8x, CACHE-MASK:0x%.8x\n", dbgstr,
951                         irq->irq_mask, cache_irq_mask);
952
953         return 0;
954 }
955
956 static int dpu_hw_intr_disable_irq(struct dpu_hw_intr *intr, int irq_idx)
957 {
958         unsigned long irq_flags;
959
960         if (!intr)
961                 return -EINVAL;
962
963         if (irq_idx < 0 || irq_idx >= ARRAY_SIZE(dpu_irq_map)) {
964                 pr_err("invalid IRQ index: [%d]\n", irq_idx);
965                 return -EINVAL;
966         }
967
968         spin_lock_irqsave(&intr->irq_lock, irq_flags);
969         dpu_hw_intr_disable_irq_nolock(intr, irq_idx);
970         spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
971
972         return 0;
973 }
974
975 static int dpu_hw_intr_clear_irqs(struct dpu_hw_intr *intr)
976 {
977         int i;
978
979         if (!intr)
980                 return -EINVAL;
981
982         for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++)
983                 DPU_REG_WRITE(&intr->hw, dpu_intr_set[i].clr_off, 0xffffffff);
984
985         /* ensure register writes go through */
986         wmb();
987
988         return 0;
989 }
990
991 static int dpu_hw_intr_disable_irqs(struct dpu_hw_intr *intr)
992 {
993         int i;
994
995         if (!intr)
996                 return -EINVAL;
997
998         for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++)
999                 DPU_REG_WRITE(&intr->hw, dpu_intr_set[i].en_off, 0x00000000);
1000
1001         /* ensure register writes go through */
1002         wmb();
1003
1004         return 0;
1005 }
1006
1007 static int dpu_hw_intr_get_valid_interrupts(struct dpu_hw_intr *intr,
1008                 uint32_t *mask)
1009 {
1010         if (!intr || !mask)
1011                 return -EINVAL;
1012
1013         *mask = IRQ_SOURCE_MDP | IRQ_SOURCE_DSI0 | IRQ_SOURCE_DSI1
1014                 | IRQ_SOURCE_HDMI | IRQ_SOURCE_EDP;
1015
1016         return 0;
1017 }
1018
1019 static void dpu_hw_intr_get_interrupt_statuses(struct dpu_hw_intr *intr)
1020 {
1021         int i;
1022         u32 enable_mask;
1023         unsigned long irq_flags;
1024
1025         if (!intr)
1026                 return;
1027
1028         spin_lock_irqsave(&intr->irq_lock, irq_flags);
1029         for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) {
1030                 /* Read interrupt status */
1031                 intr->save_irq_status[i] = DPU_REG_READ(&intr->hw,
1032                                 dpu_intr_set[i].status_off);
1033
1034                 /* Read enable mask */
1035                 enable_mask = DPU_REG_READ(&intr->hw, dpu_intr_set[i].en_off);
1036
1037                 /* and clear the interrupt */
1038                 if (intr->save_irq_status[i])
1039                         DPU_REG_WRITE(&intr->hw, dpu_intr_set[i].clr_off,
1040                                         intr->save_irq_status[i]);
1041
1042                 /* Finally update IRQ status based on enable mask */
1043                 intr->save_irq_status[i] &= enable_mask;
1044         }
1045
1046         /* ensure register writes go through */
1047         wmb();
1048
1049         spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
1050 }
1051
1052 static void dpu_hw_intr_clear_intr_status_nolock(struct dpu_hw_intr *intr,
1053                 int irq_idx)
1054 {
1055         int reg_idx;
1056
1057         if (!intr)
1058                 return;
1059
1060         reg_idx = dpu_irq_map[irq_idx].reg_idx;
1061         DPU_REG_WRITE(&intr->hw, dpu_intr_set[reg_idx].clr_off,
1062                         dpu_irq_map[irq_idx].irq_mask);
1063
1064         /* ensure register writes go through */
1065         wmb();
1066 }
1067
1068 static void dpu_hw_intr_clear_interrupt_status(struct dpu_hw_intr *intr,
1069                 int irq_idx)
1070 {
1071         unsigned long irq_flags;
1072
1073         if (!intr)
1074                 return;
1075
1076         spin_lock_irqsave(&intr->irq_lock, irq_flags);
1077         dpu_hw_intr_clear_intr_status_nolock(intr, irq_idx);
1078         spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
1079 }
1080
1081 static u32 dpu_hw_intr_get_interrupt_status(struct dpu_hw_intr *intr,
1082                 int irq_idx, bool clear)
1083 {
1084         int reg_idx;
1085         unsigned long irq_flags;
1086         u32 intr_status;
1087
1088         if (!intr)
1089                 return 0;
1090
1091         if (irq_idx >= ARRAY_SIZE(dpu_irq_map) || irq_idx < 0) {
1092                 pr_err("invalid IRQ index: [%d]\n", irq_idx);
1093                 return 0;
1094         }
1095
1096         spin_lock_irqsave(&intr->irq_lock, irq_flags);
1097
1098         reg_idx = dpu_irq_map[irq_idx].reg_idx;
1099         intr_status = DPU_REG_READ(&intr->hw,
1100                         dpu_intr_set[reg_idx].status_off) &
1101                                         dpu_irq_map[irq_idx].irq_mask;
1102         if (intr_status && clear)
1103                 DPU_REG_WRITE(&intr->hw, dpu_intr_set[reg_idx].clr_off,
1104                                 intr_status);
1105
1106         /* ensure register writes go through */
1107         wmb();
1108
1109         spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
1110
1111         return intr_status;
1112 }
1113
1114 static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)
1115 {
1116         ops->set_mask = dpu_hw_intr_set_mask;
1117         ops->irq_idx_lookup = dpu_hw_intr_irqidx_lookup;
1118         ops->enable_irq = dpu_hw_intr_enable_irq;
1119         ops->disable_irq = dpu_hw_intr_disable_irq;
1120         ops->dispatch_irqs = dpu_hw_intr_dispatch_irq;
1121         ops->clear_all_irqs = dpu_hw_intr_clear_irqs;
1122         ops->disable_all_irqs = dpu_hw_intr_disable_irqs;
1123         ops->get_valid_interrupts = dpu_hw_intr_get_valid_interrupts;
1124         ops->get_interrupt_statuses = dpu_hw_intr_get_interrupt_statuses;
1125         ops->clear_interrupt_status = dpu_hw_intr_clear_interrupt_status;
1126         ops->clear_intr_status_nolock = dpu_hw_intr_clear_intr_status_nolock;
1127         ops->get_interrupt_status = dpu_hw_intr_get_interrupt_status;
1128 }
1129
1130 static void __intr_offset(struct dpu_mdss_cfg *m,
1131                 void __iomem *addr, struct dpu_hw_blk_reg_map *hw)
1132 {
1133         hw->base_off = addr;
1134         hw->blk_off = m->mdp[0].base;
1135         hw->hwversion = m->hwversion;
1136 }
1137
1138 struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
1139                 struct dpu_mdss_cfg *m)
1140 {
1141         struct dpu_hw_intr *intr;
1142
1143         if (!addr || !m)
1144                 return ERR_PTR(-EINVAL);
1145
1146         intr = kzalloc(sizeof(*intr), GFP_KERNEL);
1147         if (!intr)
1148                 return ERR_PTR(-ENOMEM);
1149
1150         __intr_offset(m, addr, &intr->hw);
1151         __setup_intr_ops(&intr->ops);
1152
1153         intr->irq_idx_tbl_size = ARRAY_SIZE(dpu_irq_map);
1154
1155         intr->cache_irq_mask = kcalloc(ARRAY_SIZE(dpu_intr_set), sizeof(u32),
1156                         GFP_KERNEL);
1157         if (intr->cache_irq_mask == NULL) {
1158                 kfree(intr);
1159                 return ERR_PTR(-ENOMEM);
1160         }
1161
1162         intr->save_irq_status = kcalloc(ARRAY_SIZE(dpu_intr_set), sizeof(u32),
1163                         GFP_KERNEL);
1164         if (intr->save_irq_status == NULL) {
1165                 kfree(intr->cache_irq_mask);
1166                 kfree(intr);
1167                 return ERR_PTR(-ENOMEM);
1168         }
1169
1170         spin_lock_init(&intr->irq_lock);
1171
1172         return intr;
1173 }
1174
1175 void dpu_hw_intr_destroy(struct dpu_hw_intr *intr)
1176 {
1177         if (intr) {
1178                 kfree(intr->cache_irq_mask);
1179                 kfree(intr->save_irq_status);
1180                 kfree(intr);
1181         }
1182 }
1183