Line data Source code
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 : * dmub_srv_stat_get_notification - Retrieves a dmub outbox notification, set up dmub notification 39 : * structure with message information. Also a pending bit if queue 40 : * is having more notifications 41 : * @dmub: dmub srv structure 42 : * @notify: dmub notification structure to be filled up 43 : * 44 : * Returns: dmub_status 45 : */ 46 0 : enum dmub_status dmub_srv_stat_get_notification(struct dmub_srv *dmub, 47 : struct dmub_notification *notify) 48 : { 49 : /** 50 : * This function is called without dal and dc locks, so 51 : * we shall not modify any dmub variables, only dmub->outbox1_rb 52 : * is exempted as it is exclusively accessed by this function 53 : */ 54 0 : union dmub_rb_out_cmd cmd = {0}; 55 : 56 0 : if (!dmub->hw_init) { 57 0 : notify->type = DMUB_NOTIFICATION_NO_DATA; 58 0 : notify->pending_notification = false; 59 0 : return DMUB_STATUS_INVALID; 60 : } 61 : 62 : /* Get write pointer which is updated by dmub */ 63 0 : dmub->outbox1_rb.wrpt = dmub->hw_funcs.get_outbox1_wptr(dmub); 64 : 65 0 : if (!dmub_rb_out_front(&dmub->outbox1_rb, &cmd)) { 66 0 : notify->type = DMUB_NOTIFICATION_NO_DATA; 67 0 : notify->pending_notification = false; 68 0 : return DMUB_STATUS_OK; 69 : } 70 : 71 0 : switch (cmd.cmd_common.header.type) { 72 : case DMUB_OUT_CMD__DP_AUX_REPLY: 73 0 : notify->type = DMUB_NOTIFICATION_AUX_REPLY; 74 0 : notify->link_index = cmd.dp_aux_reply.control.instance; 75 0 : notify->result = cmd.dp_aux_reply.control.result; 76 0 : dmub_memcpy((void *)¬ify->aux_reply, 77 : (void *)&cmd.dp_aux_reply.reply_data, sizeof(struct aux_reply_data)); 78 0 : break; 79 : case DMUB_OUT_CMD__DP_HPD_NOTIFY: 80 0 : if (cmd.dp_hpd_notify.hpd_data.hpd_type == DP_HPD) { 81 0 : notify->type = DMUB_NOTIFICATION_HPD; 82 0 : notify->hpd_status = cmd.dp_hpd_notify.hpd_data.hpd_status; 83 : } else { 84 0 : notify->type = DMUB_NOTIFICATION_HPD_IRQ; 85 : } 86 : 87 0 : notify->link_index = cmd.dp_hpd_notify.hpd_data.instance; 88 0 : notify->result = AUX_RET_SUCCESS; 89 0 : break; 90 : case DMUB_OUT_CMD__SET_CONFIG_REPLY: 91 0 : notify->type = DMUB_NOTIFICATION_SET_CONFIG_REPLY; 92 0 : notify->link_index = cmd.set_config_reply.set_config_reply_control.instance; 93 0 : notify->sc_status = cmd.set_config_reply.set_config_reply_control.status; 94 0 : break; 95 : default: 96 0 : notify->type = DMUB_NOTIFICATION_NO_DATA; 97 0 : break; 98 : } 99 : 100 : /* Pop outbox1 ringbuffer and update read pointer */ 101 0 : dmub_rb_pop_front(&dmub->outbox1_rb); 102 0 : dmub->hw_funcs.set_outbox1_rptr(dmub, dmub->outbox1_rb.rptr); 103 : 104 : /** 105 : * Notify dc whether dmub has a pending outbox message, 106 : * this is to avoid one more call to dmub_srv_stat_get_notification 107 : */ 108 0 : if (dmub_rb_empty(&dmub->outbox1_rb)) 109 0 : notify->pending_notification = false; 110 : else 111 0 : notify->pending_notification = true; 112 : 113 : return DMUB_STATUS_OK; 114 : }