1 | /* |
2 | * Copyright 2012-15 Advanced Micro Devices, Inc. |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
11 | * The above copyright notice and this permission notice shall be included in |
12 | * all copies or substantial portions of the Software. |
13 | * |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * |
22 | * Authors: AMD |
23 | * |
24 | */ |
25 | |
26 | #ifndef __DC_TIMING_GENERATOR_DCE110_H__ |
27 | #define __DC_TIMING_GENERATOR_DCE110_H__ |
28 | |
29 | #include "timing_generator.h" |
30 | #include "../include/grph_object_id.h" |
31 | |
32 | /* GSL Sync related values */ |
33 | |
34 | /* In VSync mode, after 4 units of time, master pipe will generate |
35 | * flip_ready signal */ |
36 | #define VFLIP_READY_DELAY 4 |
37 | /* In HSync mode, after 2 units of time, master pipe will generate |
38 | * flip_ready signal */ |
39 | #define HFLIP_READY_DELAY 2 |
40 | /* 6 lines delay between forcing flip and checking all pipes ready */ |
41 | #define HFLIP_CHECK_DELAY 6 |
42 | /* 3 lines before end of frame */ |
43 | #define FLIP_READY_BACK_LOOKUP 3 |
44 | |
45 | /* Trigger Source Select - ASIC-defendant, actual values for the |
46 | * register programming */ |
47 | enum trigger_source_select { |
48 | TRIGGER_SOURCE_SELECT_LOGIC_ZERO = 0, |
49 | TRIGGER_SOURCE_SELECT_CRTC_VSYNCA = 1, |
50 | TRIGGER_SOURCE_SELECT_CRTC_HSYNCA = 2, |
51 | TRIGGER_SOURCE_SELECT_CRTC_VSYNCB = 3, |
52 | TRIGGER_SOURCE_SELECT_CRTC_HSYNCB = 4, |
53 | TRIGGER_SOURCE_SELECT_GENERICF = 5, |
54 | TRIGGER_SOURCE_SELECT_GENERICE = 6, |
55 | TRIGGER_SOURCE_SELECT_VSYNCA = 7, |
56 | TRIGGER_SOURCE_SELECT_HSYNCA = 8, |
57 | TRIGGER_SOURCE_SELECT_VSYNCB = 9, |
58 | TRIGGER_SOURCE_SELECT_HSYNCB = 10, |
59 | TRIGGER_SOURCE_SELECT_HPD1 = 11, |
60 | TRIGGER_SOURCE_SELECT_HPD2 = 12, |
61 | TRIGGER_SOURCE_SELECT_GENERICD = 13, |
62 | TRIGGER_SOURCE_SELECT_GENERICC = 14, |
63 | TRIGGER_SOURCE_SELECT_VIDEO_CAPTURE = 15, |
64 | TRIGGER_SOURCE_SELECT_GSL_GROUP0 = 16, |
65 | TRIGGER_SOURCE_SELECT_GSL_GROUP1 = 17, |
66 | TRIGGER_SOURCE_SELECT_GSL_GROUP2 = 18, |
67 | TRIGGER_SOURCE_SELECT_BLONY = 19, |
68 | TRIGGER_SOURCE_SELECT_GENERICA = 20, |
69 | TRIGGER_SOURCE_SELECT_GENERICB = 21, |
70 | TRIGGER_SOURCE_SELECT_GSL_ALLOW_FLIP = 22, |
71 | TRIGGER_SOURCE_SELECT_MANUAL_TRIGGER = 23 |
72 | }; |
73 | |
74 | /* Trigger Source Select - ASIC-dependant, actual values for the |
75 | * register programming */ |
76 | enum trigger_polarity_select { |
77 | TRIGGER_POLARITY_SELECT_LOGIC_ZERO = 0, |
78 | TRIGGER_POLARITY_SELECT_CRTC = 1, |
79 | TRIGGER_POLARITY_SELECT_GENERICA = 2, |
80 | TRIGGER_POLARITY_SELECT_GENERICB = 3, |
81 | TRIGGER_POLARITY_SELECT_HSYNCA = 4, |
82 | TRIGGER_POLARITY_SELECT_HSYNCB = 5, |
83 | TRIGGER_POLARITY_SELECT_VIDEO_CAPTURE = 6, |
84 | TRIGGER_POLARITY_SELECT_GENERICC = 7 |
85 | }; |
86 | |
87 | |
88 | struct dce110_timing_generator_offsets { |
89 | int32_t crtc; |
90 | int32_t dcp; |
91 | |
92 | /* DCE80 use only */ |
93 | int32_t dmif; |
94 | }; |
95 | |
96 | struct dce110_timing_generator { |
97 | struct timing_generator base; |
98 | struct dce110_timing_generator_offsets offsets; |
99 | struct dce110_timing_generator_offsets derived_offsets; |
100 | |
101 | enum controller_id controller_id; |
102 | |
103 | uint32_t max_h_total; |
104 | uint32_t max_v_total; |
105 | |
106 | uint32_t min_h_blank; |
107 | uint32_t min_h_front_porch; |
108 | uint32_t min_h_back_porch; |
109 | |
110 | /* DCE 12 */ |
111 | uint32_t min_h_sync_width; |
112 | uint32_t min_v_sync_width; |
113 | uint32_t min_v_blank; |
114 | |
115 | }; |
116 | |
117 | #define DCE110TG_FROM_TG(tg)\ |
118 | container_of(tg, struct dce110_timing_generator, base) |
119 | |
120 | void dce110_timing_generator_construct( |
121 | struct dce110_timing_generator *tg, |
122 | struct dc_context *ctx, |
123 | uint32_t instance, |
124 | const struct dce110_timing_generator_offsets *offsets); |
125 | |
126 | /* determine if given timing can be supported by TG */ |
127 | bool dce110_timing_generator_validate_timing( |
128 | struct timing_generator *tg, |
129 | const struct dc_crtc_timing *timing, |
130 | enum signal_type signal); |
131 | |
132 | /******** HW programming ************/ |
133 | |
134 | /* Program timing generator with given timing */ |
135 | bool dce110_timing_generator_program_timing_generator( |
136 | struct timing_generator *tg, |
137 | const struct dc_crtc_timing *dc_crtc_timing); |
138 | |
139 | /* Disable/Enable Timing Generator */ |
140 | bool dce110_timing_generator_enable_crtc(struct timing_generator *tg); |
141 | bool dce110_timing_generator_disable_crtc(struct timing_generator *tg); |
142 | |
143 | void dce110_timing_generator_set_early_control( |
144 | struct timing_generator *tg, |
145 | uint32_t early_cntl); |
146 | |
147 | /**************** TG current status ******************/ |
148 | |
149 | /* return the current frame counter. Used by Linux kernel DRM */ |
150 | uint32_t dce110_timing_generator_get_vblank_counter( |
151 | struct timing_generator *tg); |
152 | |
153 | void dce110_timing_generator_get_position( |
154 | struct timing_generator *tg, |
155 | struct crtc_position *position); |
156 | |
157 | /* return true if TG counter is moving. false if TG is stopped */ |
158 | bool dce110_timing_generator_is_counter_moving(struct timing_generator *tg); |
159 | |
160 | /* wait until TG is in beginning of vertical blank region */ |
161 | void dce110_timing_generator_wait_for_vblank(struct timing_generator *tg); |
162 | |
163 | /* wait until TG is in beginning of active region */ |
164 | void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg); |
165 | |
166 | /*********** Timing Generator Synchronization routines ****/ |
167 | |
168 | /* Setups Global Swap Lock group, TimingServer or TimingClient*/ |
169 | void dce110_timing_generator_setup_global_swap_lock( |
170 | struct timing_generator *tg, |
171 | const struct dcp_gsl_params *gsl_params); |
172 | |
173 | /* Clear all the register writes done by setup_global_swap_lock */ |
174 | void dce110_timing_generator_tear_down_global_swap_lock( |
175 | struct timing_generator *tg); |
176 | |
177 | /* Reset crtc position on master VSync */ |
178 | void dce110_timing_generator_enable_crtc_reset( |
179 | struct timing_generator *tg, |
180 | int source, |
181 | struct crtc_trigger_info *crtc_tp); |
182 | |
183 | /* Reset slave controllers on master VSync */ |
184 | void dce110_timing_generator_enable_reset_trigger( |
185 | struct timing_generator *tg, |
186 | int source); |
187 | |
188 | /* disabling trigger-reset */ |
189 | void dce110_timing_generator_disable_reset_trigger( |
190 | struct timing_generator *tg); |
191 | |
192 | /* Checks whether CRTC triggered reset occurred */ |
193 | bool dce110_timing_generator_did_triggered_reset_occur( |
194 | struct timing_generator *tg); |
195 | |
196 | /******** Stuff to move to other virtual HW objects *****************/ |
197 | /* Move to enable accelerated mode */ |
198 | void dce110_timing_generator_disable_vga(struct timing_generator *tg); |
199 | /* TODO: Should we move it to transform */ |
200 | /* Fully program CRTC timing in timing generator */ |
201 | void dce110_timing_generator_program_blanking( |
202 | struct timing_generator *tg, |
203 | const struct dc_crtc_timing *timing); |
204 | |
205 | /* TODO: Should we move it to opp? */ |
206 | /* Combine with below and move YUV/RGB color conversion to SW layer */ |
207 | void dce110_timing_generator_program_blank_color( |
208 | struct timing_generator *tg, |
209 | const struct tg_color *black_color); |
210 | /* Combine with above and move YUV/RGB color conversion to SW layer */ |
211 | void dce110_timing_generator_set_overscan_color_black( |
212 | struct timing_generator *tg, |
213 | const struct tg_color *color); |
214 | void dce110_timing_generator_color_space_to_black_color( |
215 | enum dc_color_space colorspace, |
216 | struct tg_color *black_color); |
217 | /*************** End-of-move ********************/ |
218 | |
219 | /* Not called yet */ |
220 | void dce110_timing_generator_set_test_pattern( |
221 | struct timing_generator *tg, |
222 | /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode' |
223 | * because this is not DP-specific (which is probably somewhere in DP |
224 | * encoder) */ |
225 | enum controller_dp_test_pattern test_pattern, |
226 | enum dc_color_depth color_depth); |
227 | |
228 | void dce110_timing_generator_set_drr( |
229 | struct timing_generator *tg, |
230 | const struct drr_params *params); |
231 | |
232 | void dce110_timing_generator_set_static_screen_control( |
233 | struct timing_generator *tg, |
234 | uint32_t event_triggers, |
235 | uint32_t num_frames); |
236 | |
237 | void dce110_timing_generator_get_crtc_scanoutpos( |
238 | struct timing_generator *tg, |
239 | uint32_t *v_blank_start, |
240 | uint32_t *v_blank_end, |
241 | uint32_t *h_position, |
242 | uint32_t *v_position); |
243 | |
244 | void dce110_timing_generator_enable_advanced_request( |
245 | struct timing_generator *tg, |
246 | bool enable, |
247 | const struct dc_crtc_timing *timing); |
248 | |
249 | void dce110_timing_generator_set_lock_master(struct timing_generator *tg, |
250 | bool lock); |
251 | |
252 | void dce110_tg_program_blank_color(struct timing_generator *tg, |
253 | const struct tg_color *black_color); |
254 | |
255 | void dce110_tg_set_overscan_color(struct timing_generator *tg, |
256 | const struct tg_color *overscan_color); |
257 | |
258 | void dce110_tg_program_timing(struct timing_generator *tg, |
259 | const struct dc_crtc_timing *timing, |
260 | int vready_offset, |
261 | int vstartup_start, |
262 | int vupdate_offset, |
263 | int vupdate_width, |
264 | const enum signal_type signal, |
265 | bool use_vbios); |
266 | |
267 | bool dce110_tg_is_blanked(struct timing_generator *tg); |
268 | |
269 | void dce110_tg_set_blank(struct timing_generator *tg, |
270 | bool enable_blanking); |
271 | |
272 | bool dce110_tg_validate_timing(struct timing_generator *tg, |
273 | const struct dc_crtc_timing *timing); |
274 | |
275 | void dce110_tg_wait_for_state(struct timing_generator *tg, |
276 | enum crtc_state state); |
277 | |
278 | void dce110_tg_set_colors(struct timing_generator *tg, |
279 | const struct tg_color *blank_color, |
280 | const struct tg_color *overscan_color); |
281 | |
282 | bool dce110_arm_vert_intr( |
283 | struct timing_generator *tg, uint8_t width); |
284 | |
285 | bool dce110_configure_crc(struct timing_generator *tg, |
286 | const struct crc_params *params); |
287 | |
288 | bool dce110_get_crc(struct timing_generator *tg, |
289 | uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb); |
290 | |
291 | #endif /* __DC_TIMING_GENERATOR_DCE110_H__ */ |
292 | |