1 /*
2 * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15 #ifndef __DPU_ENCODER_PHYS_H__
16 #define __DPU_ENCODER_PHYS_H__
17
18 #include <linux/jiffies.h>
19
20 #include "dpu_kms.h"
21 #include "dpu_hw_intf.h"
22 #include "dpu_hw_pingpong.h"
23 #include "dpu_hw_ctl.h"
24 #include "dpu_hw_top.h"
25 #include "dpu_hw_cdm.h"
26 #include "dpu_encoder.h"
27
28 #define DPU_ENCODER_NAME_MAX 16
29
30 /* wait for at most 2 vsync for lowest refresh rate (24hz) */
31 #define KICKOFF_TIMEOUT_MS 84
32 #define KICKOFF_TIMEOUT_JIFFIES msecs_to_jiffies(KICKOFF_TIMEOUT_MS)
33
34 /**
35 * enum dpu_enc_split_role - Role this physical encoder will play in a
36 * split-panel configuration, where one panel is master, and others slaves.
37 * Masters have extra responsibilities, like managing the VBLANK IRQ.
38 * @ENC_ROLE_SOLO: This is the one and only panel. This encoder is master.
39 * @ENC_ROLE_MASTER: This encoder is the master of a split panel config.
40 * @ENC_ROLE_SLAVE: This encoder is not the master of a split panel config.
41 */
42 enum dpu_enc_split_role {
43 ENC_ROLE_SOLO,
44 ENC_ROLE_MASTER,
45 ENC_ROLE_SLAVE,
46 };
47
48 /**
49 * enum dpu_enc_enable_state - current enabled state of the physical encoder
50 * @DPU_ENC_DISABLING: Encoder transitioning to disable state
51 * Events bounding transition are encoder type specific
52 * @DPU_ENC_DISABLED: Encoder is disabled
53 * @DPU_ENC_ENABLING: Encoder transitioning to enabled
54 * Events bounding transition are encoder type specific
55 * @DPU_ENC_ENABLED: Encoder is enabled
56 * @DPU_ENC_ERR_NEEDS_HW_RESET: Encoder is enabled, but requires a hw_reset
57 * to recover from a previous error
58 */
59 enum dpu_enc_enable_state {
60 DPU_ENC_DISABLING,
61 DPU_ENC_DISABLED,
62 DPU_ENC_ENABLING,
63 DPU_ENC_ENABLED,
64 DPU_ENC_ERR_NEEDS_HW_RESET
65 };
66
67 struct dpu_encoder_phys;
68
69 /**
70 * struct dpu_encoder_virt_ops - Interface the containing virtual encoder
71 * provides for the physical encoders to use to callback.
72 * @handle_vblank_virt: Notify virtual encoder of vblank IRQ reception
73 * Note: This is called from IRQ handler context.
74 * @handle_underrun_virt: Notify virtual encoder of underrun IRQ reception
75 * Note: This is called from IRQ handler context.
76 * @handle_frame_done: Notify virtual encoder that this phys encoder
77 * completes last request frame.
78 */
79 struct dpu_encoder_virt_ops {
80 void (*handle_vblank_virt)(struct drm_encoder *,
81 struct dpu_encoder_phys *phys);
82 void (*handle_underrun_virt)(struct drm_encoder *,
83 struct dpu_encoder_phys *phys);
84 void (*handle_frame_done)(struct drm_encoder *,
85 struct dpu_encoder_phys *phys, u32 event);
86 };
87
88 /**
89 * struct dpu_encoder_phys_ops - Interface the physical encoders provide to
90 * the containing virtual encoder.
91 * @late_register: DRM Call. Add Userspace interfaces, debugfs.
92 * @prepare_commit: MSM Atomic Call, start of atomic commit sequence
93 * @is_master: Whether this phys_enc is the current master
94 * encoder. Can be switched at enable time. Based
95 * on split_role and current mode (CMD/VID).
96 * @mode_fixup: DRM Call. Fixup a DRM mode.
97 * @mode_set: DRM Call. Set a DRM mode.
98 * This likely caches the mode, for use at enable.
99 * @enable: DRM Call. Enable a DRM mode.
100 * @disable: DRM Call. Disable mode.
101 * @atomic_check: DRM Call. Atomic check new DRM state.
102 * @destroy: DRM Call. Destroy and release resources.
103 * @get_hw_resources: Populate the structure with the hardware
104 * resources that this phys_enc is using.
105 * Expect no overlap between phys_encs.
106 * @control_vblank_irq Register/Deregister for VBLANK IRQ
107 * @wait_for_commit_done: Wait for hardware to have flushed the
108 * current pending frames to hardware
109 * @wait_for_tx_complete: Wait for hardware to transfer the pixels
110 * to the panel
111 * @wait_for_vblank: Wait for VBLANK, for sub-driver internal use
112 * @prepare_for_kickoff: Do any work necessary prior to a kickoff
113 * For CMD encoder, may wait for previous tx done
114 * @handle_post_kickoff: Do any work necessary post-kickoff work
115 * @trigger_start: Process start event on physical encoder
116 * @needs_single_flush: Whether encoder slaves need to be flushed
117 * @setup_misr: Sets up MISR, enable and disables based on sysfs
118 * @collect_misr: Collects MISR data on frame update
119 * @hw_reset: Issue HW recovery such as CTL reset and clear
120 * DPU_ENC_ERR_NEEDS_HW_RESET state
121 * @irq_control: Handler to enable/disable all the encoder IRQs
122 * @prepare_idle_pc: phys encoder can update the vsync_enable status
123 * on idle power collapse prepare
124 * @restore: Restore all the encoder configs.
125 * @get_line_count: Obtain current vertical line count
126 */
127
128 struct dpu_encoder_phys_ops {
129 int (*late_register)(struct dpu_encoder_phys *encoder,
130 struct dentry *debugfs_root);
131 void (*prepare_commit)(struct dpu_encoder_phys *encoder);
132 bool (*is_master)(struct dpu_encoder_phys *encoder);
133 bool (*mode_fixup)(struct dpu_encoder_phys *encoder,
134 const struct drm_display_mode *mode,
135 struct drm_display_mode *adjusted_mode);
136 void (*mode_set)(struct dpu_encoder_phys *encoder,
137 struct drm_display_mode *mode,
138 struct drm_display_mode *adjusted_mode);
139 void (*enable)(struct dpu_encoder_phys *encoder);
140 void (*disable)(struct dpu_encoder_phys *encoder);
141 int (*atomic_check)(struct dpu_encoder_phys *encoder,
142 struct drm_crtc_state *crtc_state,
143 struct drm_connector_state *conn_state);
144 void (*destroy)(struct dpu_encoder_phys *encoder);
145 void (*get_hw_resources)(struct dpu_encoder_phys *encoder,
146 struct dpu_encoder_hw_resources *hw_res,
147 struct drm_connector_state *conn_state);
148 int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable);
149 int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc);
150 int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc);
151 int (*wait_for_vblank)(struct dpu_encoder_phys *phys_enc);
152 void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc,
153 struct dpu_encoder_kickoff_params *params);
154 void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc);
155 void (*trigger_start)(struct dpu_encoder_phys *phys_enc);
156 bool (*needs_single_flush)(struct dpu_encoder_phys *phys_enc);
157
158 void (*setup_misr)(struct dpu_encoder_phys *phys_encs,
159 bool enable, u32 frame_count);
160 u32 (*collect_misr)(struct dpu_encoder_phys *phys_enc);
161 void (*hw_reset)(struct dpu_encoder_phys *phys_enc);
162 void (*irq_control)(struct dpu_encoder_phys *phys, bool enable);
163 void (*prepare_idle_pc)(struct dpu_encoder_phys *phys_enc);
164 void (*restore)(struct dpu_encoder_phys *phys);
165 int (*get_line_count)(struct dpu_encoder_phys *phys);
166 };
167
168 /**
169 * enum dpu_intr_idx - dpu encoder interrupt index
170 * @INTR_IDX_VSYNC: Vsync interrupt for video mode panel
171 * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
172 * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
173 * @INTR_IDX_RDPTR: Readpointer done unterrupt for cmd mode panel
174 */
175 enum dpu_intr_idx {
176 INTR_IDX_VSYNC,
177 INTR_IDX_PINGPONG,
178 INTR_IDX_UNDERRUN,
179 INTR_IDX_CTL_START,
180 INTR_IDX_RDPTR,
181 INTR_IDX_MAX,
182 };
183
184 /**
185 * dpu_encoder_irq - tracking structure for interrupts
186 * @name: string name of interrupt
187 * @intr_type: Encoder interrupt type
188 * @intr_idx: Encoder interrupt enumeration
189 * @hw_idx: HW Block ID
190 * @irq_idx: IRQ interface lookup index from DPU IRQ framework
191 * will be -EINVAL if IRQ is not registered
192 * @irq_cb: interrupt callback
193 */
194 struct dpu_encoder_irq {
195 const char *name;
196 enum dpu_intr_type intr_type;
197 enum dpu_intr_idx intr_idx;
198 int hw_idx;
199 int irq_idx;
200 struct dpu_irq_callback cb;
201 };
202
203 /**
204 * struct dpu_encoder_phys - physical encoder that drives a single INTF block
205 * tied to a specific panel / sub-panel. Abstract type, sub-classed by
206 * phys_vid or phys_cmd for video mode or command mode encs respectively.
207 * @parent: Pointer to the containing virtual encoder
208 * @connector: If a mode is set, cached pointer to the active connector
209 * @ops: Operations exposed to the virtual encoder
210 * @parent_ops: Callbacks exposed by the parent to the phys_enc
211 * @hw_mdptop: Hardware interface to the top registers
212 * @hw_ctl: Hardware interface to the ctl registers
213 * @hw_cdm: Hardware interface to the cdm registers
214 * @cdm_cfg: Chroma-down hardware configuration
215 * @hw_pp: Hardware interface to the ping pong registers
216 * @dpu_kms: Pointer to the dpu_kms top level
217 * @cached_mode: DRM mode cached at mode_set time, acted on in enable
218 * @enabled: Whether the encoder has enabled and running a mode
219 * @split_role: Role to play in a split-panel configuration
220 * @intf_mode: Interface mode
221 * @intf_idx: Interface index on dpu hardware
222 * @topology_name: topology selected for the display
223 * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
224 * @enable_state: Enable state tracking
225 * @vblank_refcount: Reference count of vblank request
226 * @vsync_cnt: Vsync count for the physical encoder
227 * @underrun_cnt: Underrun count for the physical encoder
228 * @pending_kickoff_cnt: Atomic counter tracking the number of kickoffs
229 * vs. the number of done/vblank irqs. Should hover
230 * between 0-2 Incremented when a new kickoff is
231 * scheduled. Decremented in irq handler
232 * @pending_ctlstart_cnt: Atomic counter tracking the number of ctl start
233 * pending.
234 * @pending_kickoff_wq: Wait queue for blocking until kickoff completes
235 * @irq: IRQ tracking structures
236 */
237 struct dpu_encoder_phys {
238 struct drm_encoder *parent;
239 struct drm_connector *connector;
240 struct dpu_encoder_phys_ops ops;
241 const struct dpu_encoder_virt_ops *parent_ops;
242 struct dpu_hw_mdp *hw_mdptop;
243 struct dpu_hw_ctl *hw_ctl;
244 struct dpu_hw_cdm *hw_cdm;
245 struct dpu_hw_cdm_cfg cdm_cfg;
246 struct dpu_hw_pingpong *hw_pp;
247 struct dpu_kms *dpu_kms;
248 struct drm_display_mode cached_mode;
249 enum dpu_enc_split_role split_role;
250 enum dpu_intf_mode intf_mode;
251 enum dpu_intf intf_idx;
252 enum dpu_rm_topology_name topology_name;
253 spinlock_t *enc_spinlock;
254 enum dpu_enc_enable_state enable_state;
255 atomic_t vblank_refcount;
256 atomic_t vsync_cnt;
257 atomic_t underrun_cnt;
258 atomic_t pending_ctlstart_cnt;
259 atomic_t pending_kickoff_cnt;
260 wait_queue_head_t pending_kickoff_wq;
261 struct dpu_encoder_irq irq[INTR_IDX_MAX];
262 };
263
dpu_encoder_phys_inc_pending(struct dpu_encoder_phys * phys)264 static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
265 {
266 atomic_inc_return(&phys->pending_ctlstart_cnt);
267 return atomic_inc_return(&phys->pending_kickoff_cnt);
268 }
269
270 /**
271 * struct dpu_encoder_phys_vid - sub-class of dpu_encoder_phys to handle video
272 * mode specific operations
273 * @base: Baseclass physical encoder structure
274 * @hw_intf: Hardware interface to the intf registers
275 * @timing_params: Current timing parameter
276 */
277 struct dpu_encoder_phys_vid {
278 struct dpu_encoder_phys base;
279 struct dpu_hw_intf *hw_intf;
280 struct intf_timing_params timing_params;
281 };
282
283 /**
284 * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to handle command
285 * mode specific operations
286 * @base: Baseclass physical encoder structure
287 * @intf_idx: Intf Block index used by this phys encoder
288 * @stream_sel: Stream selection for multi-stream interfaces
289 * @serialize_wait4pp: serialize wait4pp feature waits for pp_done interrupt
290 * after ctl_start instead of before next frame kickoff
291 * @pp_timeout_report_cnt: number of pingpong done irq timeout errors
292 * @pending_vblank_cnt: Atomic counter tracking pending wait for VBLANK
293 * @pending_vblank_wq: Wait queue for blocking until VBLANK received
294 */
295 struct dpu_encoder_phys_cmd {
296 struct dpu_encoder_phys base;
297 int stream_sel;
298 bool serialize_wait4pp;
299 int pp_timeout_report_cnt;
300 atomic_t pending_vblank_cnt;
301 wait_queue_head_t pending_vblank_wq;
302 };
303
304 /**
305 * struct dpu_enc_phys_init_params - initialization parameters for phys encs
306 * @dpu_kms: Pointer to the dpu_kms top level
307 * @parent: Pointer to the containing virtual encoder
308 * @parent_ops: Callbacks exposed by the parent to the phys_enc
309 * @split_role: Role to play in a split-panel configuration
310 * @intf_idx: Interface index this phys_enc will control
311 * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
312 */
313 struct dpu_enc_phys_init_params {
314 struct dpu_kms *dpu_kms;
315 struct drm_encoder *parent;
316 const struct dpu_encoder_virt_ops *parent_ops;
317 enum dpu_enc_split_role split_role;
318 enum dpu_intf intf_idx;
319 spinlock_t *enc_spinlock;
320 };
321
322 /**
323 * dpu_encoder_wait_info - container for passing arguments to irq wait functions
324 * @wq: wait queue structure
325 * @atomic_cnt: wait until atomic_cnt equals zero
326 * @timeout_ms: timeout value in milliseconds
327 */
328 struct dpu_encoder_wait_info {
329 wait_queue_head_t *wq;
330 atomic_t *atomic_cnt;
331 s64 timeout_ms;
332 };
333
334 /**
335 * dpu_encoder_phys_vid_init - Construct a new video mode physical encoder
336 * @p: Pointer to init params structure
337 * Return: Error code or newly allocated encoder
338 */
339 struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
340 struct dpu_enc_phys_init_params *p);
341
342 /**
343 * dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder
344 * @p: Pointer to init params structure
345 * Return: Error code or newly allocated encoder
346 */
347 struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
348 struct dpu_enc_phys_init_params *p);
349
350 /**
351 * dpu_encoder_helper_trigger_start - control start helper function
352 * This helper function may be optionally specified by physical
353 * encoders if they require ctl_start triggering.
354 * @phys_enc: Pointer to physical encoder structure
355 */
356 void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc);
357
358 /**
359 * dpu_encoder_helper_hw_reset - issue ctl hw reset
360 * This helper function may be optionally specified by physical
361 * encoders if they require ctl hw reset. If state is currently
362 * DPU_ENC_ERR_NEEDS_HW_RESET, it is set back to DPU_ENC_ENABLED.
363 * @phys_enc: Pointer to physical encoder structure
364 */
365 void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc);
366
dpu_encoder_helper_get_3d_blend_mode(struct dpu_encoder_phys * phys_enc)367 static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
368 struct dpu_encoder_phys *phys_enc)
369 {
370 if (!phys_enc || phys_enc->enable_state == DPU_ENC_DISABLING)
371 return BLEND_3D_NONE;
372
373 if (phys_enc->split_role == ENC_ROLE_SOLO &&
374 phys_enc->topology_name == DPU_RM_TOPOLOGY_DUALPIPE_3DMERGE)
375 return BLEND_3D_H_ROW_INT;
376
377 return BLEND_3D_NONE;
378 }
379
380 /**
381 * dpu_encoder_helper_split_config - split display configuration helper function
382 * This helper function may be used by physical encoders to configure
383 * the split display related registers.
384 * @phys_enc: Pointer to physical encoder structure
385 * @interface: enum dpu_intf setting
386 */
387 void dpu_encoder_helper_split_config(
388 struct dpu_encoder_phys *phys_enc,
389 enum dpu_intf interface);
390
391 /**
392 * dpu_encoder_helper_report_irq_timeout - utility to report error that irq has
393 * timed out, including reporting frame error event to crtc and debug dump
394 * @phys_enc: Pointer to physical encoder structure
395 * @intr_idx: Failing interrupt index
396 */
397 void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
398 enum dpu_intr_idx intr_idx);
399
400 /**
401 * dpu_encoder_helper_wait_for_irq - utility to wait on an irq.
402 * note: will call dpu_encoder_helper_wait_for_irq on timeout
403 * @phys_enc: Pointer to physical encoder structure
404 * @intr_idx: encoder interrupt index
405 * @wait_info: wait info struct
406 * @Return: 0 or -ERROR
407 */
408 int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
409 enum dpu_intr_idx intr_idx,
410 struct dpu_encoder_wait_info *wait_info);
411
412 /**
413 * dpu_encoder_helper_register_irq - register and enable an irq
414 * @phys_enc: Pointer to physical encoder structure
415 * @intr_idx: encoder interrupt index
416 * @Return: 0 or -ERROR
417 */
418 int dpu_encoder_helper_register_irq(struct dpu_encoder_phys *phys_enc,
419 enum dpu_intr_idx intr_idx);
420
421 /**
422 * dpu_encoder_helper_unregister_irq - unregister and disable an irq
423 * @phys_enc: Pointer to physical encoder structure
424 * @intr_idx: encoder interrupt index
425 * @Return: 0 or -ERROR
426 */
427 int dpu_encoder_helper_unregister_irq(struct dpu_encoder_phys *phys_enc,
428 enum dpu_intr_idx intr_idx);
429
430 #endif /* __dpu_encoder_phys_H__ */
431