Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Support for DMUB AUX

[WHY]
To process AUX transactions with DMUB using inbox1 and outbox1 mail boxes.

[HOW]
1) Added inbox1 command DMUB_CMD__DP_AUX_ACCESS to issue AUX commands
to DMUB in dc_process_dmub_aux_transfer_async(). DMUB processes AUX cmd
with DCN and sends reply back in an outbox1 message triggering an
outbox1 interrupt to driver.
2) In existing driver implementation, AUX commands are processed
synchronously by configuring DCN reg. But in DMUB AUX, driver sends an
inbox1 message and waits for a conditional variable (CV) which will be
signaled by outbox1 ISR.
3) As the driver holds dal and dc locks while waiting for CV, the outbox1
ISR is registered with noMutexWait set to true, which allows ISR to run
and signal CV. This sets a constraint on ISR to not modify variables
such as dc, dmub, etc.
4) Created dmub_outbox.c with dmub_enable_outbox_notification() to enable
outbox1 mailbox.
5) New mailbox address ranges allocated for outbox1 of size DMUB_RB_SIZE.
Created dmub functions for Outbox1: dmub_dcn20_setup_out_mailbox(),
dmub_dcn20_get_outbox1_wptr() and dmub_dcn20_set_outbox1_rptr().
6) Added functions dc_stat_get_dmub_notification() and
dmub_srv_stat_get_notification() to retrieve Outbox1 message.
7) Currently, DMUB doesn't opens DDC in AUX mode before issuing AUX
transaction. A workaround is added in dce_aux_transfer_dmub_raw() to
open in DDC in AUX mode for every AUX transaction.
8) Added dc debug option enable_dmub_aux_for_legacy_ddc enable/disable
DMUB AUX. This debug option is checked dce_aux_transfer_with_retries()
to select the method to process AUX transactions.

Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Meenakshikumar Somasundaram and committed by
Alex Deucher
4f8e37db c524c1c9

+612 -47
+10 -7
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
··· 38 38 #include "dc_link_ddc.h" 39 39 40 40 #include "i2caux_interface.h" 41 + #include "dmub_cmd.h" 41 42 #if defined(CONFIG_DEBUG_FS) 42 43 #include "amdgpu_dm_debugfs.h" 43 44 #endif ··· 52 51 { 53 52 ssize_t result = 0; 54 53 struct aux_payload payload; 55 - enum aux_channel_operation_result operation_result; 54 + enum aux_return_code_type operation_result; 56 55 57 56 if (WARN_ON(msg->size > 16)) 58 57 return -E2BIG; ··· 74 73 75 74 if (result < 0) 76 75 switch (operation_result) { 77 - case AUX_CHANNEL_OPERATION_SUCCEEDED: 76 + case AUX_RET_SUCCESS: 78 77 break; 79 - case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: 80 - case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN: 78 + case AUX_RET_ERROR_HPD_DISCON: 79 + case AUX_RET_ERROR_UNKNOWN: 80 + case AUX_RET_ERROR_INVALID_OPERATION: 81 + case AUX_RET_ERROR_PROTOCOL_ERROR: 81 82 result = -EIO; 82 83 break; 83 - case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY: 84 - case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE: 84 + case AUX_RET_ERROR_INVALID_REPLY: 85 + case AUX_RET_ERROR_ENGINE_ACQUIRE: 85 86 result = -EBUSY; 86 87 break; 87 - case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT: 88 + case AUX_RET_ERROR_TIMEOUT: 88 89 result = -ETIMEDOUT; 89 90 break; 90 91 }
+1 -1
drivers/gpu/drm/amd/display/dc/Makefile
··· 54 54 55 55 include $(AMD_DC) 56 56 57 - DISPLAY_CORE = dc.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \ 57 + DISPLAY_CORE = dc.o dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \ 58 58 dc_surface.o dc_link_hwss.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o 59 59 60 60 ifdef CONFIG_DRM_AMD_DC_DCN
+94
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 68 68 69 69 #include "dmub/dmub_srv.h" 70 70 71 + #include "i2caux_interface.h" 71 72 #include "dce/dmub_hw_lock_mgr.h" 72 73 73 74 #include "dc_trace.h" ··· 3191 3190 dc->hwss.hardware_release(dc); 3192 3191 } 3193 3192 #endif 3193 + 3194 + /** 3195 + ***************************************************************************** 3196 + * Function: dc_enable_dmub_notifications 3197 + * 3198 + * @brief 3199 + * Returns whether dmub notification can be enabled 3200 + * 3201 + * @param 3202 + * [in] dc: dc structure 3203 + * 3204 + * @return 3205 + * True to enable dmub notifications, False otherwise 3206 + ***************************************************************************** 3207 + */ 3208 + bool dc_enable_dmub_notifications(struct dc *dc) 3209 + { 3210 + /* dmub aux needs dmub notifications to be enabled */ 3211 + return dc->debug.enable_dmub_aux_for_legacy_ddc; 3212 + } 3213 + 3214 + /** 3215 + ***************************************************************************** 3216 + * Function: dc_process_dmub_aux_transfer_async 3217 + * 3218 + * @brief 3219 + * Submits aux command to dmub via inbox message 3220 + * Sets port index appropriately for legacy DDC 3221 + * 3222 + * @param 3223 + * [in] dc: dc structure 3224 + * [in] link_index: link index 3225 + * [in] payload: aux payload 3226 + * 3227 + * @return 3228 + * True if successful, False if failure 3229 + ***************************************************************************** 3230 + */ 3231 + bool dc_process_dmub_aux_transfer_async(struct dc *dc, 3232 + uint32_t link_index, 3233 + struct aux_payload *payload) 3234 + { 3235 + uint8_t action; 3236 + union dmub_rb_cmd cmd = {0}; 3237 + struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv; 3238 + 3239 + ASSERT(payload->length <= 16); 3240 + 3241 + cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS; 3242 + cmd.dp_aux_access.header.payload_bytes = 0; 3243 + cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC; 3244 + cmd.dp_aux_access.aux_control.instance = dc->links[link_index]->ddc_hw_inst; 3245 + cmd.dp_aux_access.aux_control.sw_crc_enabled = 0; 3246 + cmd.dp_aux_access.aux_control.timeout = 0; 3247 + cmd.dp_aux_access.aux_control.dpaux.address = payload->address; 3248 + cmd.dp_aux_access.aux_control.dpaux.is_i2c_over_aux = payload->i2c_over_aux; 3249 + cmd.dp_aux_access.aux_control.dpaux.length = payload->length; 3250 + 3251 + /* set aux action */ 3252 + if (payload->i2c_over_aux) { 3253 + if (payload->write) { 3254 + if (payload->mot) 3255 + action = DP_AUX_REQ_ACTION_I2C_WRITE_MOT; 3256 + else 3257 + action = DP_AUX_REQ_ACTION_I2C_WRITE; 3258 + } else { 3259 + if (payload->mot) 3260 + action = DP_AUX_REQ_ACTION_I2C_READ_MOT; 3261 + else 3262 + action = DP_AUX_REQ_ACTION_I2C_READ; 3263 + } 3264 + } else { 3265 + if (payload->write) 3266 + action = DP_AUX_REQ_ACTION_DPCD_WRITE; 3267 + else 3268 + action = DP_AUX_REQ_ACTION_DPCD_READ; 3269 + } 3270 + 3271 + cmd.dp_aux_access.aux_control.dpaux.action = action; 3272 + 3273 + if (payload->length && payload->write) { 3274 + memcpy(cmd.dp_aux_access.aux_control.dpaux.data, 3275 + payload->data, 3276 + payload->length 3277 + ); 3278 + } 3279 + 3280 + dc_dmub_srv_cmd_queue(dmub_srv, &cmd); 3281 + dc_dmub_srv_cmd_execute(dmub_srv); 3282 + dc_dmub_srv_wait_idle(dmub_srv); 3283 + 3284 + return true; 3285 + }
+64
drivers/gpu/drm/amd/display/dc/core/dc_stat.c
··· 1 + /* 2 + * Copyright 2020 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 + #include "dc/dc_stat.h" 26 + #include "dmub/dmub_srv_stat.h" 27 + #include "dc_dmub_srv.h" 28 + 29 + /** 30 + * DOC: DC STAT Interface 31 + * 32 + * These interfaces are called without acquiring DAL and DC locks. 33 + * Hence, there is limitations on whese interfaces can access. Only 34 + * variables exclusively defined for these interfaces can be modified. 35 + */ 36 + 37 + /** 38 + ***************************************************************************** 39 + * Function: dc_stat_get_dmub_notification 40 + * 41 + * @brief 42 + * Calls dmub layer to retrieve dmub notification 43 + * 44 + * @param 45 + * [in] dc: dc structure 46 + * [in] notify: dmub notification structure 47 + * 48 + * @return 49 + * None 50 + ***************************************************************************** 51 + */ 52 + void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification *notify) 53 + { 54 + /** 55 + * This function is called without dal and dc locks, so 56 + * we shall not modify any dc, dc_dmub_srv or dmub variables 57 + * except variables exclusively accessed by this function 58 + */ 59 + struct dmub_srv *dmub = dc->ctx->dmub_srv->dmub; 60 + enum dmub_status status; 61 + 62 + status = dmub_srv_stat_get_notification(dmub, notify); 63 + ASSERT(status == DMUB_STATUS_OK); 64 + }
+12
drivers/gpu/drm/amd/display/dc/dc.h
··· 42 42 #include "inc/hw/dmcu.h" 43 43 #include "dml/display_mode_lib.h" 44 44 45 + /* forward declaration */ 46 + struct aux_payload; 47 + 45 48 #define DC_VER "3.2.124" 46 49 47 50 #define MAX_SURFACES 3 ··· 534 531 bool enable_dram_clock_change_one_display_vactive; 535 532 union mem_low_power_enable_options enable_mem_low_power; 536 533 bool force_vblank_alignment; 534 + 535 + /* Enable dmub aux for legacy ddc */ 536 + bool enable_dmub_aux_for_legacy_ddc; 537 537 }; 538 538 539 539 struct dc_debug_data { ··· 1298 1292 #endif 1299 1293 1300 1294 bool dc_set_psr_allow_active(struct dc *dc, bool enable); 1295 + 1296 + bool dc_enable_dmub_notifications(struct dc *dc); 1297 + 1298 + bool dc_process_dmub_aux_transfer_async(struct dc *dc, 1299 + uint32_t link_index, 1300 + struct aux_payload *payload); 1301 1301 1302 1302 /******************************************************************************* 1303 1303 * DSC Interfaces
-10
drivers/gpu/drm/amd/display/dc/dc_ddc_types.h
··· 44 44 I2CAUX_TRANSACTION_ACTION_DP_READ = 0x90 45 45 }; 46 46 47 - enum aux_channel_operation_result { 48 - AUX_CHANNEL_OPERATION_SUCCEEDED, 49 - AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN, 50 - AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY, 51 - AUX_CHANNEL_OPERATION_FAILED_TIMEOUT, 52 - AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON, 53 - AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE 54 - }; 55 - 56 - 57 47 struct aux_request_transaction_data { 58 48 enum aux_transaction_type type; 59 49 enum i2caux_transaction_action action;
+42
drivers/gpu/drm/amd/display/dc/dc_stat.h
··· 1 + /* 2 + * Copyright 2020 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_STAT_H_ 27 + #define _DC_STAT_H_ 28 + 29 + /** 30 + * DOC: DC STAT Interface 31 + * 32 + * These interfaces are called without acquiring DAL and DC locks. 33 + * Hence, there is limitations on whese interfaces can access. Only 34 + * variables exclusively defined for these interfaces can be modified. 35 + */ 36 + 37 + #include "dc.h" 38 + #include "dmub/dmub_srv.h" 39 + 40 + void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification *notify); 41 + 42 + #endif /* _DC_STAT_H_ */
+1 -1
drivers/gpu/drm/amd/display/dc/dce/Makefile
··· 30 30 dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \ 31 31 dce_opp.o dce_dmcu.o dce_abm.o dce_ipp.o dce_aux.o \ 32 32 dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o dmub_psr.o dmub_abm.o dce_panel_cntl.o \ 33 - dmub_hw_lock_mgr.o 33 + dmub_hw_lock_mgr.o dmub_outbox.o 34 34 35 35 AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE)) 36 36
+22 -18
drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
··· 31 31 #include "dce_aux.h" 32 32 #include "dce/dce_11_0_sh_mask.h" 33 33 #include "dm_event_log.h" 34 + #include "dm_helpers.h" 35 + #include "dmub/inc/dmub_cmd.h" 34 36 35 37 #define CTX \ 36 38 aux110->base.ctx ··· 326 324 return 0; 327 325 } 328 326 329 - static enum aux_channel_operation_result get_channel_status( 327 + static enum aux_return_code_type get_channel_status( 330 328 struct dce_aux *engine, 331 329 uint8_t *returned_bytes) 332 330 { ··· 337 335 if (returned_bytes == NULL) { 338 336 /*caller pass NULL pointer*/ 339 337 ASSERT_CRITICAL(false); 340 - return AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN; 338 + return AUX_RET_ERROR_UNKNOWN; 341 339 } 342 340 *returned_bytes = 0; 343 341 ··· 348 346 value = REG_READ(AUX_SW_STATUS); 349 347 /* in case HPD is LOW, exit AUX transaction */ 350 348 if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK)) 351 - return AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON; 349 + return AUX_RET_ERROR_HPD_DISCON; 352 350 353 351 /* Note that the following bits are set in 'status.bits' 354 352 * during CTS 4.2.1.2 (FW 3.3.1): ··· 361 359 if (value & AUX_SW_STATUS__AUX_SW_DONE_MASK) { 362 360 if ((value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_STATE_MASK) || 363 361 (value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_MASK)) 364 - return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT; 362 + return AUX_RET_ERROR_TIMEOUT; 365 363 366 364 else if ((value & AUX_SW_STATUS__AUX_SW_RX_INVALID_STOP_MASK) || 367 365 (value & AUX_SW_STATUS__AUX_SW_RX_RECV_NO_DET_MASK) || 368 366 (value & 369 367 AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_H_MASK) || 370 368 (value & AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_L_MASK)) 371 - return AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY; 369 + return AUX_RET_ERROR_INVALID_REPLY; 372 370 373 371 *returned_bytes = get_reg_field_value(value, 374 372 AUX_SW_STATUS, ··· 376 374 377 375 if (*returned_bytes == 0) 378 376 return 379 - AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY; 377 + AUX_RET_ERROR_INVALID_REPLY; 380 378 else { 381 379 *returned_bytes -= 1; 382 - return AUX_CHANNEL_OPERATION_SUCCEEDED; 380 + return AUX_RET_SUCCESS; 383 381 } 384 382 } else { 385 383 /*time_elapsed >= aux_engine->timeout_period 386 384 * AUX_SW_STATUS__AUX_SW_HPD_DISCON = at this point 387 385 */ 388 386 ASSERT_CRITICAL(false); 389 - return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT; 387 + return AUX_RET_ERROR_TIMEOUT; 390 388 } 391 389 } 392 390 ··· 543 541 544 542 int dce_aux_transfer_raw(struct ddc_service *ddc, 545 543 struct aux_payload *payload, 546 - enum aux_channel_operation_result *operation_result) 544 + enum aux_return_code_type *operation_result) 547 545 { 548 546 struct ddc *ddc_pin = ddc->ddc_pin; 549 547 struct dce_aux *aux_engine; ··· 558 556 559 557 aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]; 560 558 if (!acquire(aux_engine, ddc_pin)) { 561 - *operation_result = AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE; 559 + *operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE; 562 560 return -1; 563 561 } 564 562 ··· 577 575 submit_channel_request(aux_engine, &aux_req); 578 576 *operation_result = get_channel_status(aux_engine, &returned_bytes); 579 577 580 - if (*operation_result == AUX_CHANNEL_OPERATION_SUCCEEDED) { 578 + if (*operation_result == AUX_RET_SUCCESS) { 581 579 int __maybe_unused bytes_replied = 0; 580 + 582 581 bytes_replied = read_channel_reply(aux_engine, payload->length, 583 582 payload->data, payload->reply, 584 583 &status); ··· 607 604 int i, ret = 0; 608 605 uint8_t reply; 609 606 bool payload_reply = true; 610 - enum aux_channel_operation_result operation_result; 607 + enum aux_return_code_type operation_result; 611 608 bool retry_on_defer = false; 612 609 613 610 int aux_ack_retries = 0, ··· 623 620 624 621 for (i = 0; i < AUX_MAX_RETRIES; i++) { 625 622 ret = dce_aux_transfer_raw(ddc, payload, &operation_result); 623 + 626 624 switch (operation_result) { 627 - case AUX_CHANNEL_OPERATION_SUCCEEDED: 625 + case AUX_RET_SUCCESS: 628 626 aux_timeout_retries = 0; 629 627 aux_invalid_reply_retries = 0; 630 628 ··· 671 667 } 672 668 break; 673 669 674 - case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY: 670 + case AUX_RET_ERROR_INVALID_REPLY: 675 671 if (++aux_invalid_reply_retries >= AUX_MAX_INVALID_REPLY_RETRIES) 676 672 goto fail; 677 673 else 678 674 udelay(400); 679 675 break; 680 676 681 - case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT: 677 + case AUX_RET_ERROR_TIMEOUT: 682 678 // Check whether a DEFER had occurred before the timeout. 683 679 // If so, treat timeout as a DEFER. 684 680 if (retry_on_defer) { ··· 700 696 } 701 697 break; 702 698 703 - case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: 704 - case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE: 705 - case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN: 699 + case AUX_RET_ERROR_HPD_DISCON: 700 + case AUX_RET_ERROR_ENGINE_ACQUIRE: 701 + case AUX_RET_ERROR_UNKNOWN: 706 702 default: 707 703 goto fail; 708 704 }
+2 -1
drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
··· 29 29 #include "i2caux_interface.h" 30 30 #include "inc/hw/aux_engine.h" 31 31 32 + enum aux_return_code_type; 32 33 33 34 #define AUX_COMMON_REG_LIST0(id)\ 34 35 SRI(AUX_CONTROL, DP_AUX, id), \ ··· 303 302 304 303 int dce_aux_transfer_raw(struct ddc_service *ddc, 305 304 struct aux_payload *cmd, 306 - enum aux_channel_operation_result *operation_result); 305 + enum aux_return_code_type *operation_result); 307 306 308 307 bool dce_aux_transfer_with_retries(struct ddc_service *ddc, 309 308 struct aux_payload *cmd);
+60
drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c
··· 1 + /* 2 + * Copyright 2020 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 + #include "dmub_outbox.h" 26 + #include "dc_dmub_srv.h" 27 + #include "dmub/inc/dmub_cmd.h" 28 + 29 + /** 30 + ***************************************************************************** 31 + * Function: dmub_enable_outbox_notification 32 + * 33 + * @brief 34 + * Sends inbox cmd to dmub to enable outbox1 messages with interrupt. 35 + * Dmub sends outbox1 message and triggers outbox1 interrupt. 36 + * 37 + * @param 38 + * [in] dc: dc structure 39 + * 40 + * @return 41 + * None 42 + ***************************************************************************** 43 + */ 44 + void dmub_enable_outbox_notification(struct dc *dc) 45 + { 46 + union dmub_rb_cmd cmd; 47 + struct dc_context *dc_ctx = dc->ctx; 48 + 49 + memset(&cmd, 0x0, sizeof(cmd)); 50 + cmd.outbox1_enable.header.type = DMUB_CMD__OUTBOX1_ENABLE; 51 + cmd.outbox1_enable.header.sub_type = 0; 52 + cmd.outbox1_enable.header.payload_bytes = 53 + sizeof(cmd.outbox1_enable) - 54 + sizeof(cmd.outbox1_enable.header); 55 + cmd.outbox1_enable.enable = true; 56 + 57 + dc_dmub_srv_cmd_queue(dc_ctx->dmub_srv, &cmd); 58 + dc_dmub_srv_cmd_execute(dc_ctx->dmub_srv); 59 + dc_dmub_srv_wait_idle(dc_ctx->dmub_srv); 60 + }
+33
drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.h
··· 1 + /* 2 + * Copyright 2020 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 _DMUB_OUTBOX_H_ 27 + #define _DMUB_OUTBOX_H_ 28 + 29 + #include "dc.h" 30 + 31 + void dmub_enable_outbox_notification(struct dc *dc); 32 + 33 + #endif /* _DMUB_OUTBOX_H_ */
+5
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
··· 53 53 #include "dsc.h" 54 54 #include "dce/dmub_hw_lock_mgr.h" 55 55 #include "dc_trace.h" 56 + #include "dce/dmub_outbox.h" 56 57 57 58 #define DC_LOGGER_INIT(logger) 58 59 ··· 1355 1354 if (hws->funcs.dsc_pg_control != NULL) 1356 1355 hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false); 1357 1356 } 1357 + 1358 + /* Enable outbox notification feature of dmub */ 1359 + if (dc->debug.enable_dmub_aux_for_legacy_ddc) 1360 + dmub_enable_outbox_notification(dc); 1358 1361 1359 1362 /* we want to turn off all dp displays before doing detection */ 1360 1363 if (dc->config.power_down_display_on_boot) {
+3 -1
drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h
··· 29 29 #include "dc_ddc_types.h" 30 30 #include "include/i2caux_interface.h" 31 31 32 + enum aux_return_code_type; 33 + 32 34 enum i2caux_transaction_operation { 33 35 I2CAUX_TRANSACTION_READ, 34 36 I2CAUX_TRANSACTION_WRITE ··· 164 162 uint8_t *buffer, 165 163 uint8_t *reply_result, 166 164 uint32_t *sw_status); 167 - enum aux_channel_operation_result (*get_channel_status)( 165 + enum aux_return_code_type (*get_channel_status)( 168 166 struct aux_engine *engine, 169 167 uint8_t *returned_bytes); 170 168 bool (*is_engine_available)(struct aux_engine *engine);
+1 -1
drivers/gpu/drm/amd/display/dc/irq_types.h
··· 150 150 DC_IRQ_SOURCE_DC4_VLINE1, 151 151 DC_IRQ_SOURCE_DC5_VLINE1, 152 152 DC_IRQ_SOURCE_DC6_VLINE1, 153 - 153 + DC_IRQ_DMCUB_OUTBOX1, 154 154 155 155 DAL_IRQ_SOURCES_NUMBER 156 156 };
+41
drivers/gpu/drm/amd/display/dmub/dmub_srv.h
··· 107 107 DMUB_WINDOW_TOTAL, 108 108 }; 109 109 110 + /* enum dmub_notification_type - dmub outbox notification identifier */ 111 + enum dmub_notification_type { 112 + DMUB_NOTIFICATION_NO_DATA = 0, 113 + DMUB_NOTIFICATION_AUX_REPLY, 114 + DMUB_NOTIFICATION_HPD, 115 + DMUB_NOTIFICATION_HPD_IRQ, 116 + DMUB_NOTIFICATION_MAX 117 + }; 118 + 110 119 /** 111 120 * struct dmub_region - dmub hw memory region 112 121 * @base: base address for region, must be 256 byte aligned ··· 265 256 266 257 void (*set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset); 267 258 259 + void (*setup_out_mailbox)(struct dmub_srv *dmub, 260 + const struct dmub_region *outbox1); 261 + 262 + uint32_t (*get_outbox1_wptr)(struct dmub_srv *dmub); 263 + 264 + void (*set_outbox1_rptr)(struct dmub_srv *dmub, uint32_t rptr_offset); 265 + 268 266 uint32_t (*emul_get_inbox1_rptr)(struct dmub_srv *dmub); 269 267 270 268 void (*emul_set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset); ··· 354 338 struct dmub_srv_base_funcs funcs; 355 339 struct dmub_srv_hw_funcs hw_funcs; 356 340 struct dmub_rb inbox1_rb; 341 + /** 342 + * outbox1_rb is accessed without locks (dal & dc) 343 + * and to be used only in dmub_srv_stat_get_notification() 344 + */ 345 + struct dmub_rb outbox1_rb; 357 346 358 347 bool sw_init; 359 348 bool hw_init; ··· 369 348 370 349 /* Feature capabilities reported by fw */ 371 350 struct dmub_feature_caps feature_caps; 351 + }; 352 + 353 + /** 354 + * struct dmub_notification - dmub notification data 355 + * @type: dmub notification type 356 + * @link_index: link index to identify aux connection 357 + * @result: USB4 status returned from dmub 358 + * @pending_notification: Indicates there are other pending notifications 359 + * @aux_reply: aux reply 360 + * @hpd_status: hpd status 361 + */ 362 + struct dmub_notification { 363 + enum dmub_notification_type type; 364 + uint8_t link_index; 365 + uint8_t result; 366 + bool pending_notification; 367 + union { 368 + struct aux_reply_data aux_reply; 369 + enum dp_hpd_status hpd_status; 370 + }; 372 371 }; 373 372 374 373 /**
+41
drivers/gpu/drm/amd/display/dmub/dmub_srv_stat.h
··· 1 + /* 2 + * Copyright 2020 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 _DMUB_SRV_STAT_H_ 27 + #define _DMUB_SRV_STAT_H_ 28 + 29 + /** 30 + * DOC: DMUB_SRV STAT Interface 31 + * 32 + * These interfaces are called without acquiring DAL and DC locks. 33 + * Hence, there is limitations on whese interfaces can access. Only 34 + * variables exclusively defined for these interfaces can be modified. 35 + */ 36 + #include "dmub_srv.h" 37 + 38 + enum dmub_status dmub_srv_stat_get_notification(struct dmub_srv *dmub, 39 + struct dmub_notification *notify); 40 + 41 + #endif /* _DMUB_SRV_STAT_H_ */
+1 -1
drivers/gpu/drm/amd/display/dmub/src/Makefile
··· 20 20 # OTHER DEALINGS IN THE SOFTWARE. 21 21 # 22 22 23 - DMUB = dmub_srv.o dmub_reg.o dmub_dcn20.o dmub_dcn21.o 23 + DMUB = dmub_srv.o dmub_srv_stat.o dmub_reg.o dmub_dcn20.o dmub_dcn21.o 24 24 DMUB += dmub_dcn30.o dmub_dcn301.o 25 25 DMUB += dmub_dcn302.o 26 26
+32
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c
··· 135 135 REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); 136 136 REG_WRITE(DMCUB_INBOX1_RPTR, 0); 137 137 REG_WRITE(DMCUB_INBOX1_WPTR, 0); 138 + REG_WRITE(DMCUB_OUTBOX1_RPTR, 0); 139 + REG_WRITE(DMCUB_OUTBOX1_WPTR, 0); 138 140 REG_WRITE(DMCUB_SCRATCH0, 0); 139 141 } 140 142 ··· 287 285 void dmub_dcn20_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset) 288 286 { 289 287 REG_WRITE(DMCUB_INBOX1_WPTR, wptr_offset); 288 + } 289 + 290 + void dmub_dcn20_setup_out_mailbox(struct dmub_srv *dmub, 291 + const struct dmub_region *outbox1) 292 + { 293 + /* New firmware can support CW4 for the outbox. */ 294 + if (dmub_dcn20_use_cached_inbox(dmub)) 295 + REG_WRITE(DMCUB_OUTBOX1_BASE_ADDRESS, outbox1->base); 296 + else 297 + REG_WRITE(DMCUB_OUTBOX1_BASE_ADDRESS, 0x80002000); 298 + 299 + REG_WRITE(DMCUB_OUTBOX1_SIZE, outbox1->top - outbox1->base); 300 + } 301 + 302 + uint32_t dmub_dcn20_get_outbox1_wptr(struct dmub_srv *dmub) 303 + { 304 + /** 305 + * outbox1 wptr register is accessed without locks (dal & dc) 306 + * and to be called only by dmub_srv_stat_get_notification() 307 + */ 308 + return REG_READ(DMCUB_OUTBOX1_WPTR); 309 + } 310 + 311 + void dmub_dcn20_set_outbox1_rptr(struct dmub_srv *dmub, uint32_t rptr_offset) 312 + { 313 + /** 314 + * outbox1 rptr register is accessed without locks (dal & dc) 315 + * and to be called only by dmub_srv_stat_get_notification() 316 + */ 317 + REG_WRITE(DMCUB_OUTBOX1_RPTR, rptr_offset); 290 318 } 291 319 292 320 bool dmub_dcn20_is_hw_init(struct dmub_srv *dmub)
+11
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h
··· 40 40 DMUB_SR(DMCUB_INBOX1_SIZE) \ 41 41 DMUB_SR(DMCUB_INBOX1_RPTR) \ 42 42 DMUB_SR(DMCUB_INBOX1_WPTR) \ 43 + DMUB_SR(DMCUB_OUTBOX1_BASE_ADDRESS) \ 44 + DMUB_SR(DMCUB_OUTBOX1_SIZE) \ 45 + DMUB_SR(DMCUB_OUTBOX1_RPTR) \ 46 + DMUB_SR(DMCUB_OUTBOX1_WPTR) \ 43 47 DMUB_SR(DMCUB_REGION3_CW0_OFFSET) \ 44 48 DMUB_SR(DMCUB_REGION3_CW1_OFFSET) \ 45 49 DMUB_SR(DMCUB_REGION3_CW2_OFFSET) \ ··· 188 184 uint32_t dmub_dcn20_get_inbox1_rptr(struct dmub_srv *dmub); 189 185 190 186 void dmub_dcn20_set_inbox1_wptr(struct dmub_srv *dmub, uint32_t wptr_offset); 187 + 188 + void dmub_dcn20_setup_out_mailbox(struct dmub_srv *dmub, 189 + const struct dmub_region *outbox1); 190 + 191 + uint32_t dmub_dcn20_get_outbox1_wptr(struct dmub_srv *dmub); 192 + 193 + void dmub_dcn20_set_outbox1_rptr(struct dmub_srv *dmub, uint32_t rptr_offset); 191 194 192 195 bool dmub_dcn20_is_hw_init(struct dmub_srv *dmub); 193 196
+27 -4
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
··· 46 46 /* Context size. */ 47 47 #define DMUB_CONTEXT_SIZE (512 * 1024) 48 48 49 - /* Mailbox size */ 50 - #define DMUB_MAILBOX_SIZE (DMUB_RB_SIZE) 49 + /* Mailbox size : Ring buffers are required for both inbox and outbox */ 50 + #define DMUB_MAILBOX_SIZE ((2 * DMUB_RB_SIZE)) 51 51 52 52 /* Default state size if meta is absent. */ 53 53 #define DMUB_FW_STATE_SIZE (64 * 1024) ··· 156 156 funcs->get_fw_status = dmub_dcn20_get_fw_boot_status; 157 157 funcs->enable_dmub_boot_options = dmub_dcn20_enable_dmub_boot_options; 158 158 funcs->skip_dmub_panel_power_sequence = dmub_dcn20_skip_dmub_panel_power_sequence; 159 + 160 + // Out mailbox register access functions for RN and above 161 + funcs->setup_out_mailbox = dmub_dcn20_setup_out_mailbox; 162 + funcs->get_outbox1_wptr = dmub_dcn20_get_outbox1_wptr; 163 + funcs->set_outbox1_rptr = dmub_dcn20_set_outbox1_rptr; 159 164 160 165 if (asic == DMUB_ASIC_DCN21) { 161 166 dmub->regs = &dmub_srv_dcn21_regs; ··· 402 397 403 398 struct dmub_rb_init_params rb_params; 404 399 struct dmub_window cw0, cw1, cw2, cw3, cw4, cw5, cw6; 405 - struct dmub_region inbox1; 400 + struct dmub_region inbox1, outbox1; 406 401 407 402 if (!dmub->sw_init) 408 403 return DMUB_STATUS_INVALID; ··· 449 444 cw4.region.base = DMUB_CW4_BASE; 450 445 cw4.region.top = cw4.region.base + mail_fb->size; 451 446 447 + /** 448 + * Doubled the mailbox region to accomodate inbox and outbox. 449 + * Note: Currently, currently total mailbox size is 16KB. It is split 450 + * equally into 8KB between inbox and outbox. If this config is 451 + * changed, then uncached base address configuration of outbox1 452 + * has to be updated in funcs->setup_out_mailbox. 453 + */ 452 454 inbox1.base = cw4.region.base; 453 - inbox1.top = cw4.region.top; 455 + inbox1.top = cw4.region.base + DMUB_RB_SIZE; 456 + outbox1.base = inbox1.top; 457 + outbox1.top = cw4.region.top; 454 458 455 459 cw5.offset.quad_part = tracebuff_fb->gpu_addr; 456 460 cw5.region.base = DMUB_CW5_BASE; ··· 479 465 480 466 if (dmub->hw_funcs.setup_mailbox) 481 467 dmub->hw_funcs.setup_mailbox(dmub, &inbox1); 468 + if (dmub->hw_funcs.setup_out_mailbox) 469 + dmub->hw_funcs.setup_out_mailbox(dmub, &outbox1); 482 470 } 483 471 484 472 if (mail_fb) { ··· 490 474 rb_params.capacity = DMUB_RB_SIZE; 491 475 492 476 dmub_rb_init(&dmub->inbox1_rb, &rb_params); 477 + 478 + // Initialize outbox1 ring buffer 479 + rb_params.ctx = dmub; 480 + rb_params.base_address = (void *) ((uint64_t) (mail_fb->cpu_addr) + DMUB_RB_SIZE); 481 + rb_params.capacity = DMUB_RB_SIZE; 482 + dmub_rb_init(&dmub->outbox1_rb, &rb_params); 483 + 493 484 } 494 485 495 486 if (dmub->hw_funcs.reset_release)
+105
drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c
··· 1 + /* 2 + * Copyright 2019 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 + #include "dmub/dmub_srv_stat.h" 27 + #include "dmub/inc/dmub_cmd.h" 28 + 29 + /** 30 + * DOC: DMUB_SRV STAT Interface 31 + * 32 + * These interfaces are called without acquiring DAL and DC locks. 33 + * Hence, there is limitations on whese interfaces can access. Only 34 + * variables exclusively defined for these interfaces can be modified. 35 + */ 36 + 37 + /** 38 + ***************************************************************************** 39 + * Function: dmub_srv_stat_get_notification 40 + * 41 + * @brief 42 + * Retrieves a dmub outbox notification, set up dmub notification 43 + * structure with message information. Also a pending bit if queue 44 + * is having more notifications 45 + * 46 + * @param [in] dmub: dmub srv structure 47 + * @param [out] pnotify: dmub notification structure to be filled up 48 + * 49 + * @return 50 + * dmub_status 51 + ***************************************************************************** 52 + */ 53 + enum dmub_status dmub_srv_stat_get_notification(struct dmub_srv *dmub, 54 + struct dmub_notification *notify) 55 + { 56 + /** 57 + * This function is called without dal and dc locks, so 58 + * we shall not modify any dmub variables, only dmub->outbox1_rb 59 + * is exempted as it is exclusively accessed by this function 60 + */ 61 + union dmub_rb_out_cmd cmd = {0}; 62 + 63 + if (!dmub->hw_init) { 64 + notify->type = DMUB_NOTIFICATION_NO_DATA; 65 + notify->pending_notification = false; 66 + return DMUB_STATUS_INVALID; 67 + } 68 + 69 + /* Get write pointer which is updated by dmub */ 70 + dmub->outbox1_rb.wrpt = dmub->hw_funcs.get_outbox1_wptr(dmub); 71 + 72 + if (!dmub_rb_out_front(&dmub->outbox1_rb, &cmd)) { 73 + notify->type = DMUB_NOTIFICATION_NO_DATA; 74 + notify->pending_notification = false; 75 + return DMUB_STATUS_OK; 76 + } 77 + 78 + switch (cmd.cmd_common.header.type) { 79 + case DMUB_OUT_CMD__DP_AUX_REPLY: 80 + notify->type = DMUB_NOTIFICATION_AUX_REPLY; 81 + notify->link_index = cmd.dp_aux_reply.control.instance; 82 + notify->result = cmd.dp_aux_reply.control.result; 83 + dmub_memcpy((void *)&notify->aux_reply, 84 + (void *)&cmd.dp_aux_reply.reply_data, sizeof(struct aux_reply_data)); 85 + break; 86 + default: 87 + notify->type = DMUB_NOTIFICATION_NO_DATA; 88 + break; 89 + } 90 + 91 + /* Pop outbox1 ringbuffer and update read pointer */ 92 + dmub_rb_pop_front(&dmub->outbox1_rb); 93 + dmub->hw_funcs.set_outbox1_rptr(dmub, dmub->outbox1_rb.rptr); 94 + 95 + /** 96 + * Notify dc whether dmub has a pending outbox message, 97 + * this is to avoid one more call to dmub_srv_stat_get_notification 98 + */ 99 + if (dmub_rb_empty(&dmub->outbox1_rb)) 100 + notify->pending_notification = false; 101 + else 102 + notify->pending_notification = true; 103 + 104 + return DMUB_STATUS_OK; 105 + }