@@ -146,14 +146,6 @@ MODULE_FIRMWARE(FIRMWARE_NAVI12_DMCU);
146
146
/* Number of bytes in PSP footer for firmware. */
147
147
#define PSP_FOOTER_BYTES 0x100
148
148
149
- /*
150
- * DMUB Async to Sync Mechanism Status
151
- */
152
- #define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1
153
- #define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2
154
- #define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3
155
- #define DMUB_ASYNC_TO_SYNC_ACCESS_INVALID 4
156
-
157
149
/**
158
150
* DOC: overview
159
151
*
@@ -1441,6 +1433,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
1441
1433
memset (& init_params , 0 , sizeof (init_params ));
1442
1434
#endif
1443
1435
1436
+ mutex_init (& adev -> dm .dpia_aux_lock );
1444
1437
mutex_init (& adev -> dm .dc_lock );
1445
1438
mutex_init (& adev -> dm .audio_lock );
1446
1439
@@ -1805,6 +1798,7 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
1805
1798
1806
1799
mutex_destroy (& adev -> dm .audio_lock );
1807
1800
mutex_destroy (& adev -> dm .dc_lock );
1801
+ mutex_destroy (& adev -> dm .dpia_aux_lock );
1808
1802
1809
1803
return ;
1810
1804
}
@@ -10204,91 +10198,92 @@ uint32_t dm_read_reg_func(const struct dc_context *ctx, uint32_t address,
10204
10198
return value ;
10205
10199
}
10206
10200
10207
- static int amdgpu_dm_set_dmub_async_sync_status (bool is_cmd_aux ,
10208
- struct dc_context * ctx ,
10209
- uint8_t status_type ,
10210
- uint32_t * operation_result )
10201
+ int amdgpu_dm_process_dmub_aux_transfer_sync (
10202
+ struct dc_context * ctx ,
10203
+ unsigned int link_index ,
10204
+ struct aux_payload * payload ,
10205
+ enum aux_return_code_type * operation_result )
10211
10206
{
10212
10207
struct amdgpu_device * adev = ctx -> driver_context ;
10213
- int return_status = -1 ;
10214
10208
struct dmub_notification * p_notify = adev -> dm .dmub_notify ;
10209
+ int ret = -1 ;
10215
10210
10216
- if (is_cmd_aux ) {
10217
- if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS ) {
10218
- return_status = p_notify -> aux_reply .length ;
10219
- * operation_result = p_notify -> result ;
10220
- } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT ) {
10221
- * operation_result = AUX_RET_ERROR_TIMEOUT ;
10222
- } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_FAIL ) {
10223
- * operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE ;
10224
- } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_INVALID ) {
10225
- * operation_result = AUX_RET_ERROR_INVALID_REPLY ;
10226
- } else {
10227
- * operation_result = AUX_RET_ERROR_UNKNOWN ;
10211
+ mutex_lock (& adev -> dm .dpia_aux_lock );
10212
+ if (!dc_process_dmub_aux_transfer_async (ctx -> dc , link_index , payload )) {
10213
+ * operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE ;
10214
+ goto out ;
10215
+ }
10216
+
10217
+ if (!wait_for_completion_timeout (& adev -> dm .dmub_aux_transfer_done , 10 * HZ )) {
10218
+ DRM_ERROR ("wait_for_completion_timeout timeout!" );
10219
+ * operation_result = AUX_RET_ERROR_TIMEOUT ;
10220
+ goto out ;
10221
+ }
10222
+
10223
+ if (p_notify -> result != AUX_RET_SUCCESS ) {
10224
+ /*
10225
+ * Transient states before tunneling is enabled could
10226
+ * lead to this error. We can ignore this for now.
10227
+ */
10228
+ if (p_notify -> result != AUX_RET_ERROR_PROTOCOL_ERROR ) {
10229
+ DRM_WARN ("DPIA AUX failed on 0x%x(%d), error %d\n" ,
10230
+ payload -> address , payload -> length ,
10231
+ p_notify -> result );
10228
10232
}
10229
- } else {
10230
- if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS ) {
10231
- return_status = 0 ;
10232
- * operation_result = p_notify -> sc_status ;
10233
- } else {
10234
- * operation_result = SET_CONFIG_UNKNOWN_ERROR ;
10233
+ * operation_result = AUX_RET_ERROR_INVALID_REPLY ;
10234
+ goto out ;
10235
+ }
10236
+
10237
+
10238
+ payload -> reply [0 ] = adev -> dm .dmub_notify -> aux_reply .command ;
10239
+ if (!payload -> write && p_notify -> aux_reply .length &&
10240
+ (payload -> reply [0 ] == AUX_TRANSACTION_REPLY_AUX_ACK )) {
10241
+
10242
+ if (payload -> length != p_notify -> aux_reply .length ) {
10243
+ DRM_WARN ("invalid read length %d from DPIA AUX 0x%x(%d)!\n" ,
10244
+ p_notify -> aux_reply .length ,
10245
+ payload -> address , payload -> length );
10246
+ * operation_result = AUX_RET_ERROR_INVALID_REPLY ;
10247
+ goto out ;
10235
10248
}
10249
+
10250
+ memcpy (payload -> data , p_notify -> aux_reply .data ,
10251
+ p_notify -> aux_reply .length );
10236
10252
}
10237
10253
10238
- return return_status ;
10254
+ /* success */
10255
+ ret = p_notify -> aux_reply .length ;
10256
+ * operation_result = p_notify -> result ;
10257
+ out :
10258
+ mutex_unlock (& adev -> dm .dpia_aux_lock );
10259
+ return ret ;
10239
10260
}
10240
10261
10241
- int amdgpu_dm_process_dmub_aux_transfer_sync (bool is_cmd_aux , struct dc_context * ctx ,
10242
- unsigned int link_index , void * cmd_payload , void * operation_result )
10262
+ int amdgpu_dm_process_dmub_set_config_sync (
10263
+ struct dc_context * ctx ,
10264
+ unsigned int link_index ,
10265
+ struct set_config_cmd_payload * payload ,
10266
+ enum set_config_status * operation_result )
10243
10267
{
10244
10268
struct amdgpu_device * adev = ctx -> driver_context ;
10245
- int ret = 0 ;
10269
+ bool is_cmd_complete ;
10270
+ int ret ;
10246
10271
10247
- if (is_cmd_aux ) {
10248
- dc_process_dmub_aux_transfer_async (ctx -> dc ,
10249
- link_index , (struct aux_payload * )cmd_payload );
10250
- } else if (dc_process_dmub_set_config_async (ctx -> dc , link_index ,
10251
- (struct set_config_cmd_payload * )cmd_payload ,
10252
- adev -> dm .dmub_notify )) {
10253
- return amdgpu_dm_set_dmub_async_sync_status (is_cmd_aux ,
10254
- ctx , DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS ,
10255
- (uint32_t * )operation_result );
10256
- }
10272
+ mutex_lock (& adev -> dm .dpia_aux_lock );
10273
+ is_cmd_complete = dc_process_dmub_set_config_async (ctx -> dc ,
10274
+ link_index , payload , adev -> dm .dmub_notify );
10257
10275
10258
- ret = wait_for_completion_timeout (& adev -> dm .dmub_aux_transfer_done , 10 * HZ );
10259
- if (ret == 0 ) {
10276
+ if (is_cmd_complete || wait_for_completion_timeout (& adev -> dm .dmub_aux_transfer_done , 10 * HZ )) {
10277
+ ret = 0 ;
10278
+ * operation_result = adev -> dm .dmub_notify -> sc_status ;
10279
+ } else {
10260
10280
DRM_ERROR ("wait_for_completion_timeout timeout!" );
10261
- return amdgpu_dm_set_dmub_async_sync_status (is_cmd_aux ,
10262
- ctx , DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT ,
10263
- (uint32_t * )operation_result );
10264
- }
10265
-
10266
- if (is_cmd_aux ) {
10267
- if (adev -> dm .dmub_notify -> result == AUX_RET_SUCCESS ) {
10268
- struct aux_payload * payload = (struct aux_payload * )cmd_payload ;
10269
-
10270
- payload -> reply [0 ] = adev -> dm .dmub_notify -> aux_reply .command ;
10271
- if (!payload -> write && adev -> dm .dmub_notify -> aux_reply .length &&
10272
- payload -> reply [0 ] == AUX_TRANSACTION_REPLY_AUX_ACK ) {
10273
-
10274
- if (payload -> length != adev -> dm .dmub_notify -> aux_reply .length ) {
10275
- DRM_WARN ("invalid read from DPIA AUX %x(%d) got length %d!\n" ,
10276
- payload -> address , payload -> length ,
10277
- adev -> dm .dmub_notify -> aux_reply .length );
10278
- return amdgpu_dm_set_dmub_async_sync_status (is_cmd_aux , ctx ,
10279
- DMUB_ASYNC_TO_SYNC_ACCESS_INVALID ,
10280
- (uint32_t * )operation_result );
10281
- }
10282
-
10283
- memcpy (payload -> data , adev -> dm .dmub_notify -> aux_reply .data ,
10284
- adev -> dm .dmub_notify -> aux_reply .length );
10285
- }
10286
- }
10281
+ ret = -1 ;
10282
+ * operation_result = SET_CONFIG_UNKNOWN_ERROR ;
10287
10283
}
10288
10284
10289
- return amdgpu_dm_set_dmub_async_sync_status (is_cmd_aux ,
10290
- ctx , DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS ,
10291
- (uint32_t * )operation_result );
10285
+ mutex_unlock (& adev -> dm .dpia_aux_lock );
10286
+ return ret ;
10292
10287
}
10293
10288
10294
10289
/*
0 commit comments