1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2015 MediaTek Inc.
4  */
5 
6 #ifndef MTK_DDP_COMP_H
7 #define MTK_DDP_COMP_H
8 
9 #include <linux/io.h>
10 #include <linux/pm_runtime.h>
11 #include <linux/soc/mediatek/mtk-cmdq.h>
12 #include <linux/soc/mediatek/mtk-mmsys.h>
13 #include <linux/soc/mediatek/mtk-mutex.h>
14 
15 #include <drm/drm_modes.h>
16 
17 struct device;
18 struct device_node;
19 struct drm_crtc;
20 struct drm_device;
21 struct mtk_plane_state;
22 struct drm_crtc_state;
23 
24 enum mtk_ddp_comp_type {
25 	MTK_DISP_AAL,
26 	MTK_DISP_BLS,
27 	MTK_DISP_CCORR,
28 	MTK_DISP_COLOR,
29 	MTK_DISP_DITHER,
30 	MTK_DISP_DSC,
31 	MTK_DISP_GAMMA,
32 	MTK_DISP_MERGE,
33 	MTK_DISP_MUTEX,
34 	MTK_DISP_OD,
35 	MTK_DISP_OVL,
36 	MTK_DISP_OVL_2L,
37 	MTK_DISP_OVL_ADAPTOR,
38 	MTK_DISP_POSTMASK,
39 	MTK_DISP_PWM,
40 	MTK_DISP_RDMA,
41 	MTK_DISP_UFOE,
42 	MTK_DISP_WDMA,
43 	MTK_DPI,
44 	MTK_DP_INTF,
45 	MTK_DSI,
46 	MTK_DDP_COMP_TYPE_MAX,
47 };
48 
49 struct mtk_ddp_comp;
50 struct cmdq_pkt;
51 struct mtk_ddp_comp_funcs {
52 	int (*power_on)(struct device *dev);
53 	void (*power_off)(struct device *dev);
54 	int (*clk_enable)(struct device *dev);
55 	void (*clk_disable)(struct device *dev);
56 	void (*config)(struct device *dev, unsigned int w,
57 		       unsigned int h, unsigned int vrefresh,
58 		       unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
59 	void (*start)(struct device *dev);
60 	void (*stop)(struct device *dev);
61 	void (*register_vblank_cb)(struct device *dev,
62 				   void (*vblank_cb)(void *),
63 				   void *vblank_cb_data);
64 	void (*unregister_vblank_cb)(struct device *dev);
65 	void (*enable_vblank)(struct device *dev);
66 	void (*disable_vblank)(struct device *dev);
67 	unsigned int (*supported_rotations)(struct device *dev);
68 	unsigned int (*layer_nr)(struct device *dev);
69 	int (*layer_check)(struct device *dev,
70 			   unsigned int idx,
71 			   struct mtk_plane_state *state);
72 	void (*layer_config)(struct device *dev, unsigned int idx,
73 			     struct mtk_plane_state *state,
74 			     struct cmdq_pkt *cmdq_pkt);
75 	unsigned int (*gamma_get_lut_size)(struct device *dev);
76 	void (*gamma_set)(struct device *dev,
77 			  struct drm_crtc_state *state);
78 	void (*bgclr_in_on)(struct device *dev);
79 	void (*bgclr_in_off)(struct device *dev);
80 	void (*ctm_set)(struct device *dev,
81 			struct drm_crtc_state *state);
82 	struct device * (*dma_dev_get)(struct device *dev);
83 	u32 (*get_blend_modes)(struct device *dev);
84 	const u32 *(*get_formats)(struct device *dev);
85 	size_t (*get_num_formats)(struct device *dev);
86 	void (*connect)(struct device *dev, struct device *mmsys_dev, unsigned int next);
87 	void (*disconnect)(struct device *dev, struct device *mmsys_dev, unsigned int next);
88 	void (*add)(struct device *dev, struct mtk_mutex *mutex);
89 	void (*remove)(struct device *dev, struct mtk_mutex *mutex);
90 	unsigned int (*encoder_index)(struct device *dev);
91 	enum drm_mode_status (*mode_valid)(struct device *dev, const struct drm_display_mode *mode);
92 };
93 
94 struct mtk_ddp_comp {
95 	struct device *dev;
96 	int irq;
97 	unsigned int id;
98 	int encoder_index;
99 	const struct mtk_ddp_comp_funcs *funcs;
100 };
101 
mtk_ddp_comp_power_on(struct mtk_ddp_comp * comp)102 static inline int mtk_ddp_comp_power_on(struct mtk_ddp_comp *comp)
103 {
104 	if (comp->funcs && comp->funcs->power_on)
105 		return comp->funcs->power_on(comp->dev);
106 	else
107 		return pm_runtime_resume_and_get(comp->dev);
108 	return 0;
109 }
110 
mtk_ddp_comp_power_off(struct mtk_ddp_comp * comp)111 static inline void mtk_ddp_comp_power_off(struct mtk_ddp_comp *comp)
112 {
113 	if (comp->funcs && comp->funcs->power_off)
114 		comp->funcs->power_off(comp->dev);
115 	else
116 		pm_runtime_put(comp->dev);
117 }
118 
mtk_ddp_comp_clk_enable(struct mtk_ddp_comp * comp)119 static inline int mtk_ddp_comp_clk_enable(struct mtk_ddp_comp *comp)
120 {
121 	if (comp->funcs && comp->funcs->clk_enable)
122 		return comp->funcs->clk_enable(comp->dev);
123 
124 	return 0;
125 }
126 
mtk_ddp_comp_clk_disable(struct mtk_ddp_comp * comp)127 static inline void mtk_ddp_comp_clk_disable(struct mtk_ddp_comp *comp)
128 {
129 	if (comp->funcs && comp->funcs->clk_disable)
130 		comp->funcs->clk_disable(comp->dev);
131 }
132 
133 static inline
mtk_ddp_comp_mode_valid(struct mtk_ddp_comp * comp,const struct drm_display_mode * mode)134 enum drm_mode_status mtk_ddp_comp_mode_valid(struct mtk_ddp_comp *comp,
135 					     const struct drm_display_mode *mode)
136 {
137 	if (comp && comp->funcs && comp->funcs->mode_valid)
138 		return comp->funcs->mode_valid(comp->dev, mode);
139 	return MODE_OK;
140 }
141 
mtk_ddp_comp_config(struct mtk_ddp_comp * comp,unsigned int w,unsigned int h,unsigned int vrefresh,unsigned int bpc,struct cmdq_pkt * cmdq_pkt)142 static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
143 				       unsigned int w, unsigned int h,
144 				       unsigned int vrefresh, unsigned int bpc,
145 				       struct cmdq_pkt *cmdq_pkt)
146 {
147 	if (comp->funcs && comp->funcs->config)
148 		comp->funcs->config(comp->dev, w, h, vrefresh, bpc, cmdq_pkt);
149 }
150 
mtk_ddp_comp_start(struct mtk_ddp_comp * comp)151 static inline void mtk_ddp_comp_start(struct mtk_ddp_comp *comp)
152 {
153 	if (comp->funcs && comp->funcs->start)
154 		comp->funcs->start(comp->dev);
155 }
156 
mtk_ddp_comp_stop(struct mtk_ddp_comp * comp)157 static inline void mtk_ddp_comp_stop(struct mtk_ddp_comp *comp)
158 {
159 	if (comp->funcs && comp->funcs->stop)
160 		comp->funcs->stop(comp->dev);
161 }
162 
mtk_ddp_comp_register_vblank_cb(struct mtk_ddp_comp * comp,void (* vblank_cb)(void *),void * vblank_cb_data)163 static inline void mtk_ddp_comp_register_vblank_cb(struct mtk_ddp_comp *comp,
164 						   void (*vblank_cb)(void *),
165 						   void *vblank_cb_data)
166 {
167 	if (comp->funcs && comp->funcs->register_vblank_cb)
168 		comp->funcs->register_vblank_cb(comp->dev, vblank_cb,
169 						vblank_cb_data);
170 }
171 
mtk_ddp_comp_unregister_vblank_cb(struct mtk_ddp_comp * comp)172 static inline void mtk_ddp_comp_unregister_vblank_cb(struct mtk_ddp_comp *comp)
173 {
174 	if (comp->funcs && comp->funcs->unregister_vblank_cb)
175 		comp->funcs->unregister_vblank_cb(comp->dev);
176 }
177 
mtk_ddp_comp_enable_vblank(struct mtk_ddp_comp * comp)178 static inline void mtk_ddp_comp_enable_vblank(struct mtk_ddp_comp *comp)
179 {
180 	if (comp->funcs && comp->funcs->enable_vblank)
181 		comp->funcs->enable_vblank(comp->dev);
182 }
183 
mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp * comp)184 static inline void mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp *comp)
185 {
186 	if (comp->funcs && comp->funcs->disable_vblank)
187 		comp->funcs->disable_vblank(comp->dev);
188 }
189 
190 static inline
mtk_ddp_comp_supported_rotations(struct mtk_ddp_comp * comp)191 unsigned int mtk_ddp_comp_supported_rotations(struct mtk_ddp_comp *comp)
192 {
193 	if (comp->funcs && comp->funcs->supported_rotations)
194 		return comp->funcs->supported_rotations(comp->dev);
195 
196 	/*
197 	 * In order to pass IGT tests, DRM_MODE_ROTATE_0 is required when
198 	 * rotation is not supported.
199 	 */
200 	return DRM_MODE_ROTATE_0;
201 }
202 
mtk_ddp_comp_layer_nr(struct mtk_ddp_comp * comp)203 static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp)
204 {
205 	if (comp->funcs && comp->funcs->layer_nr)
206 		return comp->funcs->layer_nr(comp->dev);
207 
208 	return 0;
209 }
210 
mtk_ddp_comp_layer_check(struct mtk_ddp_comp * comp,unsigned int idx,struct mtk_plane_state * state)211 static inline int mtk_ddp_comp_layer_check(struct mtk_ddp_comp *comp,
212 					   unsigned int idx,
213 					   struct mtk_plane_state *state)
214 {
215 	if (comp->funcs && comp->funcs->layer_check)
216 		return comp->funcs->layer_check(comp->dev, idx, state);
217 	return 0;
218 }
219 
mtk_ddp_comp_layer_config(struct mtk_ddp_comp * comp,unsigned int idx,struct mtk_plane_state * state,struct cmdq_pkt * cmdq_pkt)220 static inline void mtk_ddp_comp_layer_config(struct mtk_ddp_comp *comp,
221 					     unsigned int idx,
222 					     struct mtk_plane_state *state,
223 					     struct cmdq_pkt *cmdq_pkt)
224 {
225 	if (comp->funcs && comp->funcs->layer_config)
226 		comp->funcs->layer_config(comp->dev, idx, state, cmdq_pkt);
227 }
228 
mtk_ddp_gamma_get_lut_size(struct mtk_ddp_comp * comp)229 static inline unsigned int mtk_ddp_gamma_get_lut_size(struct mtk_ddp_comp *comp)
230 {
231 	if (comp->funcs && comp->funcs->gamma_get_lut_size)
232 		return comp->funcs->gamma_get_lut_size(comp->dev);
233 
234 	return 0;
235 }
236 
mtk_ddp_gamma_set(struct mtk_ddp_comp * comp,struct drm_crtc_state * state)237 static inline void mtk_ddp_gamma_set(struct mtk_ddp_comp *comp,
238 				     struct drm_crtc_state *state)
239 {
240 	if (comp->funcs && comp->funcs->gamma_set)
241 		comp->funcs->gamma_set(comp->dev, state);
242 }
243 
mtk_ddp_comp_bgclr_in_on(struct mtk_ddp_comp * comp)244 static inline void mtk_ddp_comp_bgclr_in_on(struct mtk_ddp_comp *comp)
245 {
246 	if (comp->funcs && comp->funcs->bgclr_in_on)
247 		comp->funcs->bgclr_in_on(comp->dev);
248 }
249 
mtk_ddp_comp_bgclr_in_off(struct mtk_ddp_comp * comp)250 static inline void mtk_ddp_comp_bgclr_in_off(struct mtk_ddp_comp *comp)
251 {
252 	if (comp->funcs && comp->funcs->bgclr_in_off)
253 		comp->funcs->bgclr_in_off(comp->dev);
254 }
255 
mtk_ddp_ctm_set(struct mtk_ddp_comp * comp,struct drm_crtc_state * state)256 static inline void mtk_ddp_ctm_set(struct mtk_ddp_comp *comp,
257 				   struct drm_crtc_state *state)
258 {
259 	if (comp->funcs && comp->funcs->ctm_set)
260 		comp->funcs->ctm_set(comp->dev, state);
261 }
262 
mtk_ddp_comp_dma_dev_get(struct mtk_ddp_comp * comp)263 static inline struct device *mtk_ddp_comp_dma_dev_get(struct mtk_ddp_comp *comp)
264 {
265 	if (comp->funcs && comp->funcs->dma_dev_get)
266 		return comp->funcs->dma_dev_get(comp->dev);
267 	return comp->dev;
268 }
269 
270 static inline
mtk_ddp_comp_get_blend_modes(struct mtk_ddp_comp * comp)271 u32 mtk_ddp_comp_get_blend_modes(struct mtk_ddp_comp *comp)
272 {
273 	if (comp->funcs && comp->funcs->get_blend_modes)
274 		return comp->funcs->get_blend_modes(comp->dev);
275 
276 	return 0;
277 }
278 
279 static inline
mtk_ddp_comp_get_formats(struct mtk_ddp_comp * comp)280 const u32 *mtk_ddp_comp_get_formats(struct mtk_ddp_comp *comp)
281 {
282 	if (comp->funcs && comp->funcs->get_formats)
283 		return comp->funcs->get_formats(comp->dev);
284 
285 	return NULL;
286 }
287 
288 static inline
mtk_ddp_comp_get_num_formats(struct mtk_ddp_comp * comp)289 size_t mtk_ddp_comp_get_num_formats(struct mtk_ddp_comp *comp)
290 {
291 	if (comp->funcs && comp->funcs->get_num_formats)
292 		return comp->funcs->get_num_formats(comp->dev);
293 
294 	return 0;
295 }
296 
mtk_ddp_comp_add(struct mtk_ddp_comp * comp,struct mtk_mutex * mutex)297 static inline bool mtk_ddp_comp_add(struct mtk_ddp_comp *comp, struct mtk_mutex *mutex)
298 {
299 	if (comp->funcs && comp->funcs->add) {
300 		comp->funcs->add(comp->dev, mutex);
301 		return true;
302 	}
303 	return false;
304 }
305 
mtk_ddp_comp_remove(struct mtk_ddp_comp * comp,struct mtk_mutex * mutex)306 static inline bool mtk_ddp_comp_remove(struct mtk_ddp_comp *comp, struct mtk_mutex *mutex)
307 {
308 	if (comp->funcs && comp->funcs->remove) {
309 		comp->funcs->remove(comp->dev, mutex);
310 		return true;
311 	}
312 	return false;
313 }
314 
mtk_ddp_comp_connect(struct mtk_ddp_comp * comp,struct device * mmsys_dev,unsigned int next)315 static inline bool mtk_ddp_comp_connect(struct mtk_ddp_comp *comp, struct device *mmsys_dev,
316 					unsigned int next)
317 {
318 	if (comp->funcs && comp->funcs->connect) {
319 		comp->funcs->connect(comp->dev, mmsys_dev, next);
320 		return true;
321 	}
322 	return false;
323 }
324 
mtk_ddp_comp_disconnect(struct mtk_ddp_comp * comp,struct device * mmsys_dev,unsigned int next)325 static inline bool mtk_ddp_comp_disconnect(struct mtk_ddp_comp *comp, struct device *mmsys_dev,
326 					   unsigned int next)
327 {
328 	if (comp->funcs && comp->funcs->disconnect) {
329 		comp->funcs->disconnect(comp->dev, mmsys_dev, next);
330 		return true;
331 	}
332 	return false;
333 }
334 
mtk_ddp_comp_encoder_index_set(struct mtk_ddp_comp * comp)335 static inline void mtk_ddp_comp_encoder_index_set(struct mtk_ddp_comp *comp)
336 {
337 	if (comp->funcs && comp->funcs->encoder_index)
338 		comp->encoder_index = (int)comp->funcs->encoder_index(comp->dev);
339 }
340 
341 int mtk_ddp_comp_get_id(struct device_node *node,
342 			enum mtk_ddp_comp_type comp_type);
343 int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev);
344 int mtk_ddp_comp_init(struct device_node *comp_node, struct mtk_ddp_comp *comp,
345 		      unsigned int comp_id);
346 enum mtk_ddp_comp_type mtk_ddp_comp_get_type(unsigned int comp_id);
347 void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
348 		   struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
349 		   unsigned int offset);
350 void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value,
351 			   struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
352 			   unsigned int offset);
353 void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
354 			struct cmdq_client_reg *cmdq_reg, void __iomem *regs,
355 			unsigned int offset, unsigned int mask);
356 #endif /* MTK_DDP_COMP_H */
357