Home | History | Annotate | Line # | Download | only in dce
      1 /*	$NetBSD: dce_aux.h,v 1.2 2021/12/18 23:45:02 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2012-15 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors: AMD
     25  *
     26  */
     27 
     28 #ifndef __DAL_AUX_ENGINE_DCE110_H__
     29 #define __DAL_AUX_ENGINE_DCE110_H__
     30 
     31 #include "i2caux_interface.h"
     32 #include "inc/hw/aux_engine.h"
     33 
     34 
     35 #define AUX_COMMON_REG_LIST0(id)\
     36 	SRI(AUX_CONTROL, DP_AUX, id), \
     37 	SRI(AUX_ARB_CONTROL, DP_AUX, id), \
     38 	SRI(AUX_SW_DATA, DP_AUX, id), \
     39 	SRI(AUX_SW_CONTROL, DP_AUX, id), \
     40 	SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \
     41 	SRI(AUX_DPHY_RX_CONTROL1, DP_AUX, id), \
     42 	SRI(AUX_SW_STATUS, DP_AUX, id)
     43 
     44 #define AUX_COMMON_REG_LIST(id)\
     45 	SRI(AUX_CONTROL, DP_AUX, id), \
     46 	SRI(AUX_ARB_CONTROL, DP_AUX, id), \
     47 	SRI(AUX_SW_DATA, DP_AUX, id), \
     48 	SRI(AUX_SW_CONTROL, DP_AUX, id), \
     49 	SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \
     50 	SRI(AUX_SW_STATUS, DP_AUX, id), \
     51 	SR(AUXN_IMPCAL), \
     52 	SR(AUXP_IMPCAL)
     53 
     54 struct dce110_aux_registers {
     55 	uint32_t AUX_CONTROL;
     56 	uint32_t AUX_ARB_CONTROL;
     57 	uint32_t AUX_SW_DATA;
     58 	uint32_t AUX_SW_CONTROL;
     59 	uint32_t AUX_INTERRUPT_CONTROL;
     60 	uint32_t AUX_DPHY_RX_CONTROL1;
     61 	uint32_t AUX_SW_STATUS;
     62 	uint32_t AUXN_IMPCAL;
     63 	uint32_t AUXP_IMPCAL;
     64 
     65 	uint32_t AUX_RESET_MASK;
     66 };
     67 
     68 #define DCE_AUX_REG_FIELD_LIST(type)\
     69 	type AUX_EN;\
     70 	type AUX_RESET;\
     71 	type AUX_RESET_DONE;\
     72 	type AUX_REG_RW_CNTL_STATUS;\
     73 	type AUX_SW_USE_AUX_REG_REQ;\
     74 	type AUX_SW_DONE_USING_AUX_REG;\
     75 	type AUX_SW_AUTOINCREMENT_DISABLE;\
     76 	type AUX_SW_DATA_RW;\
     77 	type AUX_SW_INDEX;\
     78 	type AUX_SW_GO;\
     79 	type AUX_SW_DATA;\
     80 	type AUX_SW_REPLY_BYTE_COUNT;\
     81 	type AUX_SW_DONE;\
     82 	type AUX_SW_DONE_ACK;\
     83 	type AUXN_IMPCAL_ENABLE;\
     84 	type AUXP_IMPCAL_ENABLE;\
     85 	type AUXN_IMPCAL_OVERRIDE_ENABLE;\
     86 	type AUXP_IMPCAL_OVERRIDE_ENABLE;\
     87 	type AUX_RX_TIMEOUT_LEN;\
     88 	type AUX_RX_TIMEOUT_LEN_MUL;\
     89 	type AUXN_CALOUT_ERROR_AK;\
     90 	type AUXP_CALOUT_ERROR_AK;\
     91 	type AUX_SW_START_DELAY;\
     92 	type AUX_SW_WR_BYTES
     93 
     94 #define DCE10_AUX_MASK_SH_LIST(mask_sh)\
     95 	AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\
     96 	AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
     97 	AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
     98 	AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
     99 	AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
    100 	AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
    101 	AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
    102 	AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
    103 	AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
    104 	AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
    105 	AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
    106 	AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
    107 	AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
    108 	AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
    109 	AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
    110 	AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
    111 	AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
    112 	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
    113 	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
    114 	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
    115 	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
    116 
    117 #define DCE_AUX_MASK_SH_LIST(mask_sh)\
    118 	AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\
    119 	AUX_SF(AUX_CONTROL, AUX_RESET, mask_sh),\
    120 	AUX_SF(AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
    121 	AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
    122 	AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
    123 	AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
    124 	AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
    125 	AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
    126 	AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
    127 	AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
    128 	AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
    129 	AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
    130 	AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
    131 	AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
    132 	AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
    133 	AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
    134 	AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
    135 	AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
    136 	AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
    137 	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
    138 	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
    139 	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
    140 	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
    141 
    142 #define DCE12_AUX_MASK_SH_LIST(mask_sh)\
    143 	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\
    144 	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\
    145 	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
    146 	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
    147 	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
    148 	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
    149 	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
    150 	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
    151 	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
    152 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
    153 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
    154 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
    155 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
    156 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
    157 	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
    158 	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
    159 	AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
    160 	AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
    161 	AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
    162 	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
    163 	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
    164 	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
    165 	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
    166 
    167 /* DCN10 MASK */
    168 #define DCN10_AUX_MASK_SH_LIST(mask_sh)\
    169 	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\
    170 	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\
    171 	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
    172 	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
    173 	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
    174 	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
    175 	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
    176 	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
    177 	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
    178 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
    179 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
    180 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
    181 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
    182 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
    183 	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
    184 	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
    185 	AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
    186 	AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\
    187 	AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\
    188 	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\
    189 	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\
    190 	AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\
    191 	AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh)
    192 
    193 /* for all other DCN */
    194 #define DCN_AUX_MASK_SH_LIST(mask_sh)\
    195 	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\
    196 	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\
    197 	AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\
    198 	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\
    199 	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\
    200 	AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\
    201 	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\
    202 	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\
    203 	AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\
    204 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
    205 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\
    206 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\
    207 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\
    208 	AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\
    209 	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
    210 	AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\
    211 	AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\
    212 	AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, mask_sh),\
    213 	AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN_MUL, mask_sh)
    214 
    215 #define AUX_SF(reg_name, field_name, post_fix)\
    216 	.field_name = reg_name ## __ ## field_name ## post_fix
    217 
    218 enum {	/* This is the timeout as defined in DP 1.2a,
    219 	 * 2.3.4 "Detailed uPacket TX AUX CH State Description".
    220 	 */
    221 	AUX_TIMEOUT_PERIOD = 400,
    222 
    223 	/* Ideally, the SW timeout should be just above 550usec
    224 	 * which is programmed in HW.
    225 	 * But the SW timeout of 600usec is not reliable,
    226 	 * because on some systems, delay_in_microseconds()
    227 	 * returns faster than it should.
    228 	 * EPR #379763: by trial-and-error on different systems,
    229 	 * 700usec is the minimum reliable SW timeout for polling
    230 	 * the AUX_SW_STATUS.AUX_SW_DONE bit.
    231 	 * This timeout expires *only* when there is
    232 	 * AUX Error or AUX Timeout conditions - not during normal operation.
    233 	 * During normal operation, AUX_SW_STATUS.AUX_SW_DONE bit is set
    234 	 * at most within ~240usec. That means,
    235 	 * increasing this timeout will not affect normal operation,
    236 	 * and we'll timeout after
    237 	 * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD = 2400usec.
    238 	 * This timeout is especially important for
    239 	 * converters, resume from S3, and CTS.
    240 	 */
    241 	SW_AUX_TIMEOUT_PERIOD_MULTIPLIER = 6
    242 };
    243 
    244 struct dce_aux {
    245 	uint32_t inst;
    246 	struct ddc *ddc;
    247 	struct dc_context *ctx;
    248 	/* following values are expressed in milliseconds */
    249 	uint32_t delay;
    250 	uint32_t max_defer_write_retry;
    251 
    252 	bool acquire_reset;
    253 	struct dce_aux_funcs *funcs;
    254 };
    255 
    256 struct dce110_aux_registers_mask {
    257 	DCE_AUX_REG_FIELD_LIST(uint32_t);
    258 };
    259 
    260 struct dce110_aux_registers_shift {
    261 	DCE_AUX_REG_FIELD_LIST(uint8_t);
    262 };
    263 
    264 
    265 struct aux_engine_dce110 {
    266 	struct dce_aux base;
    267 	const struct dce110_aux_registers *regs;
    268 	const struct dce110_aux_registers_mask *mask;
    269 	const struct dce110_aux_registers_shift *shift;
    270 	struct {
    271 		uint32_t aux_control;
    272 		uint32_t aux_arb_control;
    273 		uint32_t aux_sw_data;
    274 		uint32_t aux_sw_control;
    275 		uint32_t aux_interrupt_control;
    276 		uint32_t aux_dphy_rx_control1;
    277 		uint32_t aux_dphy_rx_control0;
    278 		uint32_t aux_sw_status;
    279 	} addr;
    280 	uint32_t polling_timeout_period;
    281 };
    282 
    283 struct aux_engine_dce110_init_data {
    284 	uint32_t engine_id;
    285 	uint32_t timeout_period;
    286 	struct dc_context *ctx;
    287 	const struct dce110_aux_registers *regs;
    288 };
    289 
    290 struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110,
    291 		struct dc_context *ctx,
    292 		uint32_t inst,
    293 		uint32_t timeout_period,
    294 		const struct dce110_aux_registers *regs,
    295 
    296 		const struct dce110_aux_registers_mask *mask,
    297 		const struct dce110_aux_registers_shift *shift,
    298 		bool is_ext_aux_timeout_configurable);
    299 
    300 void dce110_engine_destroy(struct dce_aux **engine);
    301 
    302 bool dce110_aux_engine_acquire(
    303 	struct dce_aux *aux_engine,
    304 	struct ddc *ddc);
    305 
    306 int dce_aux_transfer_raw(struct ddc_service *ddc,
    307 		struct aux_payload *cmd,
    308 		enum aux_channel_operation_result *operation_result);
    309 
    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