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 __DAL_AUX_ENGINE_DCE110_H__
27  #define __DAL_AUX_ENGINE_DCE110_H__
28  
29  #include "gpio_service_interface.h"
30  #include "inc/hw/aux_engine.h"
31  
32  enum aux_return_code_type;
33  
34  #define AUX_COMMON_REG_LIST0(id)\
35  	SRI(AUX_CONTROL, DP_AUX, id), \
36  	SRI(AUX_ARB_CONTROL, DP_AUX, id), \
37  	SRI(AUX_SW_DATA, DP_AUX, id), \
38  	SRI(AUX_SW_CONTROL, DP_AUX, id), \
39  	SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \
40  	SRI(AUX_DPHY_RX_CONTROL1, DP_AUX, id), \
41  	SRI(AUX_SW_STATUS, DP_AUX, id)
42  
43  #define AUX_COMMON_REG_LIST(id)\
44  	SRI(AUX_CONTROL, DP_AUX, id), \
45  	SRI(AUX_ARB_CONTROL, DP_AUX, id), \
46  	SRI(AUX_SW_DATA, DP_AUX, id), \
47  	SRI(AUX_SW_CONTROL, DP_AUX, id), \
48  	SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \
49  	SRI(AUX_SW_STATUS, DP_AUX, id), \
50  	SR(AUXN_IMPCAL), \
51  	SR(AUXP_IMPCAL)
52  
53  struct dce110_aux_registers {
54  	uint32_t AUX_CONTROL;
55  	uint32_t AUX_ARB_CONTROL;
56  	uint32_t AUX_SW_DATA;
57  	uint32_t AUX_SW_CONTROL;
58  	uint32_t AUX_INTERRUPT_CONTROL;
59  	uint32_t AUX_DPHY_RX_CONTROL1;
60  	uint32_t AUX_SW_STATUS;
61  	uint32_t AUXN_IMPCAL;
62  	uint32_t AUXP_IMPCAL;
63  
64  	uint32_t AUX_RESET_MASK;
65  };
66  
67  #define DCE_AUX_REG_FIELD_LIST(type)\
68  	type AUX_EN;\
69  	type AUX_RESET;\
70  	type AUX_RESET_DONE;\
71  	type AUX_REG_RW_CNTL_STATUS;\
72  	type AUX_SW_USE_AUX_REG_REQ;\
73  	type AUX_SW_DONE_USING_AUX_REG;\
74  	type AUX_SW_AUTOINCREMENT_DISABLE;\
75  	type AUX_SW_DATA_RW;\
76  	type AUX_SW_INDEX;\
77  	type AUX_SW_GO;\
78  	type AUX_SW_DATA;\
79  	type AUX_SW_REPLY_BYTE_COUNT;\
80  	type AUX_SW_DONE;\
81  	type AUX_SW_DONE_ACK;\
82  	type AUXN_IMPCAL_ENABLE;\
83  	type AUXP_IMPCAL_ENABLE;\
84  	type AUXN_IMPCAL_OVERRIDE_ENABLE;\
85  	type AUXP_IMPCAL_OVERRIDE_ENABLE;\
86  	type AUX_RX_TIMEOUT_LEN;\
87  	type AUX_RX_TIMEOUT_LEN_MUL;\
88  	type AUXN_CALOUT_ERROR_AK;\
89  	type AUXP_CALOUT_ERROR_AK;\
90  	type AUX_SW_START_DELAY;\
91  	type AUX_SW_WR_BYTES
92  
93  #define DCE10_AUX_MASK_SH_LIST(mask_sh)\
94  	AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\
95  	AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
96  	AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
97  	AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
98  	AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
99  	AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
100  	AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
101  	AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
102  	AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
103  	AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
104  	AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
105  	AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
106  	AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
107  	AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
108  	AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
109  	AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
110  	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
111  	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
112  	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
113  	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
114  
115  #define DCE_AUX_MASK_SH_LIST(mask_sh)\
116  	AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\
117  	AUX_SF(AUX_CONTROL, AUX_RESET, mask_sh),\
118  	AUX_SF(AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
119  	AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
120  	AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
121  	AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
122  	AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
123  	AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
124  	AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
125  	AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
126  	AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
127  	AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
128  	AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
129  	AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
130  	AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
131  	AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
132  	AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
133  	AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
134  	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
135  	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
136  	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
137  	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
138  
139  #define DCE12_AUX_MASK_SH_LIST(mask_sh)\
140  	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\
141  	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\
142  	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
143  	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
144  	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
145  	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
146  	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
147  	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
148  	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
149  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
150  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
151  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
152  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
153  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
154  	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
155  	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
156  	AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
157  	AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
158  	AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
159  	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
160  	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
161  	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
162  	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
163  
164  /* DCN10 MASK */
165  #define DCN10_AUX_MASK_SH_LIST(mask_sh)\
166  	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\
167  	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\
168  	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
169  	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
170  	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
171  	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
172  	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
173  	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
174  	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
175  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
176  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
177  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
178  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
179  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
180  	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
181  	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
182  	AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
183  	AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
184  	AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
185  	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
186  	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
187  	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
188  	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
189  
190  /* for all other DCN */
191  #define DCN_AUX_MASK_SH_LIST(mask_sh)\
192  	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\
193  	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\
194  	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
195  	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
196  	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
197  	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
198  	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
199  	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
200  	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
201  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
202  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
203  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
204  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
205  	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
206  	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
207  	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
208  	AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
209  	AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, mask_sh),\
210  	AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN_MUL, mask_sh)
211  
212  #define AUX_SF(reg_name, field_name, post_fix)\
213  	.field_name = reg_name ## __ ## field_name ## post_fix
214  
215  enum {	/* This is the timeout as defined in DP 1.2a,
216  	 * 2.3.4 "Detailed uPacket TX AUX CH State Description".
217  	 */
218  	AUX_TIMEOUT_PERIOD = 400,
219  
220  	/* Ideally, the SW timeout should be just above 550usec
221  	 * which is programmed in HW.
222  	 * But the SW timeout of 600usec is not reliable,
223  	 * because on some systems, delay_in_microseconds()
224  	 * returns faster than it should.
225  	 * EPR #379763: by trial-and-error on different systems,
226  	 * 700usec is the minimum reliable SW timeout for polling
227  	 * the AUX_SW_STATUS.AUX_SW_DONE bit.
228  	 * This timeout expires *only* when there is
229  	 * AUX Error or AUX Timeout conditions - not during normal operation.
230  	 * During normal operation, AUX_SW_STATUS.AUX_SW_DONE bit is set
231  	 * at most within ~240usec. That means,
232  	 * increasing this timeout will not affect normal operation,
233  	 * and we'll timeout after
234  	 * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD = 2400usec.
235  	 * This timeout is especially important for
236  	 * converters, resume from S3, and CTS.
237  	 */
238  	SW_AUX_TIMEOUT_PERIOD_MULTIPLIER = 6
239  };
240  
241  struct dce_aux {
242  	uint32_t inst;
243  	struct ddc *ddc;
244  	struct dc_context *ctx;
245  	/* following values are expressed in milliseconds */
246  	uint32_t delay;
247  	uint32_t max_defer_write_retry;
248  
249  	bool acquire_reset;
250  	struct dce_aux_funcs *funcs;
251  };
252  
253  struct dce110_aux_registers_mask {
254  	DCE_AUX_REG_FIELD_LIST(uint32_t);
255  };
256  
257  struct dce110_aux_registers_shift {
258  	DCE_AUX_REG_FIELD_LIST(uint8_t);
259  };
260  
261  
262  struct aux_engine_dce110 {
263  	struct dce_aux base;
264  	const struct dce110_aux_registers *regs;
265  	const struct dce110_aux_registers_mask *mask;
266  	const struct dce110_aux_registers_shift *shift;
267  	struct {
268  		uint32_t aux_control;
269  		uint32_t aux_arb_control;
270  		uint32_t aux_sw_data;
271  		uint32_t aux_sw_control;
272  		uint32_t aux_interrupt_control;
273  		uint32_t aux_dphy_rx_control1;
274  		uint32_t aux_dphy_rx_control0;
275  		uint32_t aux_sw_status;
276  	} addr;
277  	uint32_t polling_timeout_period;
278  };
279  
280  struct aux_engine_dce110_init_data {
281  	uint32_t engine_id;
282  	uint32_t timeout_period;
283  	struct dc_context *ctx;
284  	const struct dce110_aux_registers *regs;
285  };
286  
287  struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110,
288  		struct dc_context *ctx,
289  		uint32_t inst,
290  		uint32_t timeout_period,
291  		const struct dce110_aux_registers *regs,
292  
293  		const struct dce110_aux_registers_mask *mask,
294  		const struct dce110_aux_registers_shift *shift,
295  		bool is_ext_aux_timeout_configurable);
296  
297  void dce110_engine_destroy(struct dce_aux **engine);
298  
299  bool dce110_aux_engine_acquire(
300  	struct dce_aux *aux_engine,
301  	struct ddc *ddc);
302  
303  int dce_aux_transfer_raw(struct ddc_service *ddc,
304  		struct aux_payload *cmd,
305  		enum aux_return_code_type *operation_result);
306  
307  int dce_aux_transfer_dmub_raw(struct ddc_service *ddc,
308  		struct aux_payload *payload,
309  		enum aux_return_code_type *operation_result);
310  bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
311  		struct aux_payload *cmd);
312  
313  struct dce_aux_funcs {
314  	uint32_t (*configure_timeout)
315  		(struct ddc_service *ddc,
316  		 uint32_t timeout);
317  	void (*destroy)
318  		(struct aux_engine **ptr);
319  };
320  
321  #endif
322