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 #ifndef _DPU_HW_INTERRUPTS_H
14 #define _DPU_HW_INTERRUPTS_H
15 
16 #include <linux/types.h>
17 
18 #include "dpu_hwio.h"
19 #include "dpu_hw_catalog.h"
20 #include "dpu_hw_util.h"
21 #include "dpu_hw_mdss.h"
22 
23 #define IRQ_SOURCE_MDP		BIT(0)
24 #define IRQ_SOURCE_DSI0		BIT(4)
25 #define IRQ_SOURCE_DSI1		BIT(5)
26 #define IRQ_SOURCE_HDMI		BIT(8)
27 #define IRQ_SOURCE_EDP		BIT(12)
28 #define IRQ_SOURCE_MHL		BIT(16)
29 
30 /**
31  * dpu_intr_type - HW Interrupt Type
32  * @DPU_IRQ_TYPE_WB_ROT_COMP:		WB rotator done
33  * @DPU_IRQ_TYPE_WB_WFD_COMP:		WB WFD done
34  * @DPU_IRQ_TYPE_PING_PONG_COMP:	PingPong done
35  * @DPU_IRQ_TYPE_PING_PONG_RD_PTR:	PingPong read pointer
36  * @DPU_IRQ_TYPE_PING_PONG_WR_PTR:	PingPong write pointer
37  * @DPU_IRQ_TYPE_PING_PONG_AUTO_REF:	PingPong auto refresh
38  * @DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK:	PingPong Tear check
39  * @DPU_IRQ_TYPE_PING_PONG_TE_CHECK:	PingPong TE detection
40  * @DPU_IRQ_TYPE_INTF_UNDER_RUN:	INTF underrun
41  * @DPU_IRQ_TYPE_INTF_VSYNC:		INTF VSYNC
42  * @DPU_IRQ_TYPE_CWB_OVERFLOW:		Concurrent WB overflow
43  * @DPU_IRQ_TYPE_HIST_VIG_DONE:		VIG Histogram done
44  * @DPU_IRQ_TYPE_HIST_VIG_RSTSEQ:	VIG Histogram reset
45  * @DPU_IRQ_TYPE_HIST_DSPP_DONE:	DSPP Histogram done
46  * @DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ:	DSPP Histogram reset
47  * @DPU_IRQ_TYPE_WD_TIMER:		Watchdog timer
48  * @DPU_IRQ_TYPE_SFI_VIDEO_IN:		Video static frame INTR into static
49  * @DPU_IRQ_TYPE_SFI_VIDEO_OUT:		Video static frame INTR out-of static
50  * @DPU_IRQ_TYPE_SFI_CMD_0_IN:		DSI CMD0 static frame INTR into static
51  * @DPU_IRQ_TYPE_SFI_CMD_0_OUT:		DSI CMD0 static frame INTR out-of static
52  * @DPU_IRQ_TYPE_SFI_CMD_1_IN:		DSI CMD1 static frame INTR into static
53  * @DPU_IRQ_TYPE_SFI_CMD_1_OUT:		DSI CMD1 static frame INTR out-of static
54  * @DPU_IRQ_TYPE_SFI_CMD_2_IN:		DSI CMD2 static frame INTR into static
55  * @DPU_IRQ_TYPE_SFI_CMD_2_OUT:		DSI CMD2 static frame INTR out-of static
56  * @DPU_IRQ_TYPE_PROG_LINE:		Programmable Line interrupt
57  * @DPU_IRQ_TYPE_AD4_BL_DONE:		AD4 backlight
58  * @DPU_IRQ_TYPE_CTL_START:		Control start
59  * @DPU_IRQ_TYPE_RESERVED:		Reserved for expansion
60  */
61 enum dpu_intr_type {
62 	DPU_IRQ_TYPE_WB_ROT_COMP,
63 	DPU_IRQ_TYPE_WB_WFD_COMP,
64 	DPU_IRQ_TYPE_PING_PONG_COMP,
65 	DPU_IRQ_TYPE_PING_PONG_RD_PTR,
66 	DPU_IRQ_TYPE_PING_PONG_WR_PTR,
67 	DPU_IRQ_TYPE_PING_PONG_AUTO_REF,
68 	DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK,
69 	DPU_IRQ_TYPE_PING_PONG_TE_CHECK,
70 	DPU_IRQ_TYPE_INTF_UNDER_RUN,
71 	DPU_IRQ_TYPE_INTF_VSYNC,
72 	DPU_IRQ_TYPE_CWB_OVERFLOW,
73 	DPU_IRQ_TYPE_HIST_VIG_DONE,
74 	DPU_IRQ_TYPE_HIST_VIG_RSTSEQ,
75 	DPU_IRQ_TYPE_HIST_DSPP_DONE,
76 	DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ,
77 	DPU_IRQ_TYPE_WD_TIMER,
78 	DPU_IRQ_TYPE_SFI_VIDEO_IN,
79 	DPU_IRQ_TYPE_SFI_VIDEO_OUT,
80 	DPU_IRQ_TYPE_SFI_CMD_0_IN,
81 	DPU_IRQ_TYPE_SFI_CMD_0_OUT,
82 	DPU_IRQ_TYPE_SFI_CMD_1_IN,
83 	DPU_IRQ_TYPE_SFI_CMD_1_OUT,
84 	DPU_IRQ_TYPE_SFI_CMD_2_IN,
85 	DPU_IRQ_TYPE_SFI_CMD_2_OUT,
86 	DPU_IRQ_TYPE_PROG_LINE,
87 	DPU_IRQ_TYPE_AD4_BL_DONE,
88 	DPU_IRQ_TYPE_CTL_START,
89 	DPU_IRQ_TYPE_RESERVED,
90 };
91 
92 struct dpu_hw_intr;
93 
94 /**
95  * Interrupt operations.
96  */
97 struct dpu_hw_intr_ops {
98 	/**
99 	 * set_mask - Programs the given interrupt register with the
100 	 *            given interrupt mask. Register value will get overwritten.
101 	 * @intr:	HW interrupt handle
102 	 * @reg_off:	MDSS HW register offset
103 	 * @irqmask:	IRQ mask value
104 	 */
105 	void (*set_mask)(
106 			struct dpu_hw_intr *intr,
107 			uint32_t reg,
108 			uint32_t irqmask);
109 
110 	/**
111 	 * irq_idx_lookup - Lookup IRQ index on the HW interrupt type
112 	 *                 Used for all irq related ops
113 	 * @intr_type:		Interrupt type defined in dpu_intr_type
114 	 * @instance_idx:	HW interrupt block instance
115 	 * @return:		irq_idx or -EINVAL for lookup fail
116 	 */
117 	int (*irq_idx_lookup)(
118 			enum dpu_intr_type intr_type,
119 			u32 instance_idx);
120 
121 	/**
122 	 * enable_irq - Enable IRQ based on lookup IRQ index
123 	 * @intr:	HW interrupt handle
124 	 * @irq_idx:	Lookup irq index return from irq_idx_lookup
125 	 * @return:	0 for success, otherwise failure
126 	 */
127 	int (*enable_irq)(
128 			struct dpu_hw_intr *intr,
129 			int irq_idx);
130 
131 	/**
132 	 * disable_irq - Disable IRQ based on lookup IRQ index
133 	 * @intr:	HW interrupt handle
134 	 * @irq_idx:	Lookup irq index return from irq_idx_lookup
135 	 * @return:	0 for success, otherwise failure
136 	 */
137 	int (*disable_irq)(
138 			struct dpu_hw_intr *intr,
139 			int irq_idx);
140 
141 	/**
142 	 * clear_all_irqs - Clears all the interrupts (i.e. acknowledges
143 	 *                  any asserted IRQs). Useful during reset.
144 	 * @intr:	HW interrupt handle
145 	 * @return:	0 for success, otherwise failure
146 	 */
147 	int (*clear_all_irqs)(
148 			struct dpu_hw_intr *intr);
149 
150 	/**
151 	 * disable_all_irqs - Disables all the interrupts. Useful during reset.
152 	 * @intr:	HW interrupt handle
153 	 * @return:	0 for success, otherwise failure
154 	 */
155 	int (*disable_all_irqs)(
156 			struct dpu_hw_intr *intr);
157 
158 	/**
159 	 * dispatch_irqs - IRQ dispatcher will call the given callback
160 	 *                 function when a matching interrupt status bit is
161 	 *                 found in the irq mapping table.
162 	 * @intr:	HW interrupt handle
163 	 * @cbfunc:	Callback function pointer
164 	 * @arg:	Argument to pass back during callback
165 	 */
166 	void (*dispatch_irqs)(
167 			struct dpu_hw_intr *intr,
168 			void (*cbfunc)(void *arg, int irq_idx),
169 			void *arg);
170 
171 	/**
172 	 * get_interrupt_statuses - Gets and store value from all interrupt
173 	 *                          status registers that are currently fired.
174 	 * @intr:	HW interrupt handle
175 	 */
176 	void (*get_interrupt_statuses)(
177 			struct dpu_hw_intr *intr);
178 
179 	/**
180 	 * clear_interrupt_status - Clears HW interrupt status based on given
181 	 *                          lookup IRQ index.
182 	 * @intr:	HW interrupt handle
183 	 * @irq_idx:	Lookup irq index return from irq_idx_lookup
184 	 */
185 	void (*clear_interrupt_status)(
186 			struct dpu_hw_intr *intr,
187 			int irq_idx);
188 
189 	/**
190 	 * clear_intr_status_nolock() - clears the HW interrupts without lock
191 	 * @intr:	HW interrupt handle
192 	 * @irq_idx:	Lookup irq index return from irq_idx_lookup
193 	 */
194 	void (*clear_intr_status_nolock)(
195 			struct dpu_hw_intr *intr,
196 			int irq_idx);
197 
198 	/**
199 	 * get_interrupt_status - Gets HW interrupt status, and clear if set,
200 	 *                        based on given lookup IRQ index.
201 	 * @intr:	HW interrupt handle
202 	 * @irq_idx:	Lookup irq index return from irq_idx_lookup
203 	 * @clear:	True to clear irq after read
204 	 */
205 	u32 (*get_interrupt_status)(
206 			struct dpu_hw_intr *intr,
207 			int irq_idx,
208 			bool clear);
209 
210 	/**
211 	 * get_valid_interrupts - Gets a mask of all valid interrupt sources
212 	 *                        within DPU. These are actually status bits
213 	 *                        within interrupt registers that specify the
214 	 *                        source of the interrupt in IRQs. For example,
215 	 *                        valid interrupt sources can be MDP, DSI,
216 	 *                        HDMI etc.
217 	 * @intr:	HW interrupt handle
218 	 * @mask:	Returning the interrupt source MASK
219 	 * @return:	0 for success, otherwise failure
220 	 */
221 	int (*get_valid_interrupts)(
222 			struct dpu_hw_intr *intr,
223 			uint32_t *mask);
224 };
225 
226 /**
227  * struct dpu_hw_intr: hw interrupts handling data structure
228  * @hw:               virtual address mapping
229  * @ops:              function pointer mapping for IRQ handling
230  * @cache_irq_mask:   array of IRQ enable masks reg storage created during init
231  * @save_irq_status:  array of IRQ status reg storage created during init
232  * @irq_idx_tbl_size: total number of irq_idx mapped in the hw_interrupts
233  * @irq_lock:         spinlock for accessing IRQ resources
234  */
235 struct dpu_hw_intr {
236 	struct dpu_hw_blk_reg_map hw;
237 	struct dpu_hw_intr_ops ops;
238 	u32 *cache_irq_mask;
239 	u32 *save_irq_status;
240 	u32 irq_idx_tbl_size;
241 	spinlock_t irq_lock;
242 };
243 
244 /**
245  * dpu_hw_intr_init(): Initializes the interrupts hw object
246  * @addr: mapped register io address of MDP
247  * @m :   pointer to mdss catalog data
248  */
249 struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
250 		struct dpu_mdss_cfg *m);
251 
252 /**
253  * dpu_hw_intr_destroy(): Cleanup interrutps hw object
254  * @intr: pointer to interrupts hw object
255  */
256 void dpu_hw_intr_destroy(struct dpu_hw_intr *intr);
257 #endif
258