15ca38a18SWenjing Liu /* 25ca38a18SWenjing Liu * Copyright 2023 Advanced Micro Devices, Inc. 35ca38a18SWenjing Liu * 45ca38a18SWenjing Liu * Permission is hereby granted, free of charge, to any person obtaining a 55ca38a18SWenjing Liu * copy of this software and associated documentation files (the "Software"), 65ca38a18SWenjing Liu * to deal in the Software without restriction, including without limitation 75ca38a18SWenjing Liu * the rights to use, copy, modify, merge, publish, distribute, sublicense, 85ca38a18SWenjing Liu * and/or sell copies of the Software, and to permit persons to whom the 95ca38a18SWenjing Liu * Software is furnished to do so, subject to the following conditions: 105ca38a18SWenjing Liu * 115ca38a18SWenjing Liu * The above copyright notice and this permission notice shall be included in 125ca38a18SWenjing Liu * all copies or substantial portions of the Software. 135ca38a18SWenjing Liu * 145ca38a18SWenjing Liu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 155ca38a18SWenjing Liu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165ca38a18SWenjing Liu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 175ca38a18SWenjing Liu * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 185ca38a18SWenjing Liu * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 195ca38a18SWenjing Liu * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 205ca38a18SWenjing Liu * OTHER DEALINGS IN THE SOFTWARE. 215ca38a18SWenjing Liu * 225ca38a18SWenjing Liu * Authors: AMD 235ca38a18SWenjing Liu * 245ca38a18SWenjing Liu */ 255ca38a18SWenjing Liu 265ca38a18SWenjing Liu /* FILE POLICY AND INTENDED USAGE: 275ca38a18SWenjing Liu * This file provides single entrance to link functionality declared in dc 285ca38a18SWenjing Liu * public headers. The file is intended to be used as a thin translation layer 295ca38a18SWenjing Liu * that directly calls link internal functions without adding new functional 305ca38a18SWenjing Liu * behavior. 315ca38a18SWenjing Liu * 325ca38a18SWenjing Liu * When exporting a new link related dc function, add function declaration in 335ca38a18SWenjing Liu * dc.h with detail interface documentation, then add function implementation 345ca38a18SWenjing Liu * in this file which calls link functions. 355ca38a18SWenjing Liu */ 365ca38a18SWenjing Liu #include "link.h" 37*7ae1dbe6SWenjing Liu #include "dce/dce_i2c.h" 38*7ae1dbe6SWenjing Liu struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index) 39*7ae1dbe6SWenjing Liu { 40*7ae1dbe6SWenjing Liu return dc->links[link_index]; 41*7ae1dbe6SWenjing Liu } 42*7ae1dbe6SWenjing Liu 43*7ae1dbe6SWenjing Liu void dc_get_edp_links(const struct dc *dc, 44*7ae1dbe6SWenjing Liu struct dc_link **edp_links, 45*7ae1dbe6SWenjing Liu int *edp_num) 46*7ae1dbe6SWenjing Liu { 47*7ae1dbe6SWenjing Liu int i; 48*7ae1dbe6SWenjing Liu 49*7ae1dbe6SWenjing Liu *edp_num = 0; 50*7ae1dbe6SWenjing Liu for (i = 0; i < dc->link_count; i++) { 51*7ae1dbe6SWenjing Liu // report any eDP links, even unconnected DDI's 52*7ae1dbe6SWenjing Liu if (!dc->links[i]) 53*7ae1dbe6SWenjing Liu continue; 54*7ae1dbe6SWenjing Liu if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) { 55*7ae1dbe6SWenjing Liu edp_links[*edp_num] = dc->links[i]; 56*7ae1dbe6SWenjing Liu if (++(*edp_num) == MAX_NUM_EDP) 57*7ae1dbe6SWenjing Liu return; 58*7ae1dbe6SWenjing Liu } 59*7ae1dbe6SWenjing Liu } 60*7ae1dbe6SWenjing Liu } 61*7ae1dbe6SWenjing Liu 62*7ae1dbe6SWenjing Liu bool dc_get_edp_link_panel_inst(const struct dc *dc, 63*7ae1dbe6SWenjing Liu const struct dc_link *link, 64*7ae1dbe6SWenjing Liu unsigned int *inst_out) 65*7ae1dbe6SWenjing Liu { 66*7ae1dbe6SWenjing Liu struct dc_link *edp_links[MAX_NUM_EDP]; 67*7ae1dbe6SWenjing Liu int edp_num, i; 68*7ae1dbe6SWenjing Liu 69*7ae1dbe6SWenjing Liu *inst_out = 0; 70*7ae1dbe6SWenjing Liu if (link->connector_signal != SIGNAL_TYPE_EDP) 71*7ae1dbe6SWenjing Liu return false; 72*7ae1dbe6SWenjing Liu dc_get_edp_links(dc, edp_links, &edp_num); 73*7ae1dbe6SWenjing Liu for (i = 0; i < edp_num; i++) { 74*7ae1dbe6SWenjing Liu if (link == edp_links[i]) 75*7ae1dbe6SWenjing Liu break; 76*7ae1dbe6SWenjing Liu (*inst_out)++; 77*7ae1dbe6SWenjing Liu } 78*7ae1dbe6SWenjing Liu return true; 79*7ae1dbe6SWenjing Liu } 805ca38a18SWenjing Liu 815ca38a18SWenjing Liu bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) 825ca38a18SWenjing Liu { 835ca38a18SWenjing Liu return link_detect(link, reason); 845ca38a18SWenjing Liu } 855ca38a18SWenjing Liu 865ca38a18SWenjing Liu bool dc_link_detect_connection_type(struct dc_link *link, 875ca38a18SWenjing Liu enum dc_connection_type *type) 885ca38a18SWenjing Liu { 895ca38a18SWenjing Liu return link_detect_connection_type(link, type); 905ca38a18SWenjing Liu } 915ca38a18SWenjing Liu 925ca38a18SWenjing Liu const struct dc_link_status *dc_link_get_status(const struct dc_link *link) 935ca38a18SWenjing Liu { 945ca38a18SWenjing Liu return link_get_status(link); 955ca38a18SWenjing Liu } 965ca38a18SWenjing Liu #ifdef CONFIG_DRM_AMD_DC_HDCP 975ca38a18SWenjing Liu 985ca38a18SWenjing Liu /* return true if the connected receiver supports the hdcp version */ 995ca38a18SWenjing Liu bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal) 1005ca38a18SWenjing Liu { 1015ca38a18SWenjing Liu return link_is_hdcp14(link, signal); 1025ca38a18SWenjing Liu } 1035ca38a18SWenjing Liu 1045ca38a18SWenjing Liu bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal) 1055ca38a18SWenjing Liu { 1065ca38a18SWenjing Liu return link_is_hdcp22(link, signal); 1075ca38a18SWenjing Liu } 1085ca38a18SWenjing Liu #endif 1095ca38a18SWenjing Liu 1105ca38a18SWenjing Liu void dc_link_clear_dprx_states(struct dc_link *link) 1115ca38a18SWenjing Liu { 1125ca38a18SWenjing Liu link_clear_dprx_states(link); 1135ca38a18SWenjing Liu } 1145ca38a18SWenjing Liu 1155ca38a18SWenjing Liu bool dc_link_reset_cur_dp_mst_topology(struct dc_link *link) 1165ca38a18SWenjing Liu { 1175ca38a18SWenjing Liu return link_reset_cur_dp_mst_topology(link); 1185ca38a18SWenjing Liu } 1195ca38a18SWenjing Liu 1205ca38a18SWenjing Liu uint32_t dc_link_bandwidth_kbps( 1215ca38a18SWenjing Liu const struct dc_link *link, 1225ca38a18SWenjing Liu const struct dc_link_settings *link_settings) 1235ca38a18SWenjing Liu { 1245ca38a18SWenjing Liu return dp_link_bandwidth_kbps(link, link_settings); 1255ca38a18SWenjing Liu } 1265ca38a18SWenjing Liu 1275ca38a18SWenjing Liu uint32_t dc_bandwidth_in_kbps_from_timing( 1285ca38a18SWenjing Liu const struct dc_crtc_timing *timing) 1295ca38a18SWenjing Liu { 1305ca38a18SWenjing Liu return link_timing_bandwidth_kbps(timing); 1315ca38a18SWenjing Liu } 1325ca38a18SWenjing Liu 1335ca38a18SWenjing Liu void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map) 1345ca38a18SWenjing Liu { 1355ca38a18SWenjing Liu link_get_cur_res_map(dc, map); 1365ca38a18SWenjing Liu } 1375ca38a18SWenjing Liu 1385ca38a18SWenjing Liu void dc_restore_link_res_map(const struct dc *dc, uint32_t *map) 1395ca38a18SWenjing Liu { 1405ca38a18SWenjing Liu link_restore_res_map(dc, map); 1415ca38a18SWenjing Liu } 1425ca38a18SWenjing Liu 1435ca38a18SWenjing Liu bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx) 1445ca38a18SWenjing Liu { 1455ca38a18SWenjing Liu return link_update_dsc_config(pipe_ctx); 1465ca38a18SWenjing Liu } 147*7ae1dbe6SWenjing Liu 148*7ae1dbe6SWenjing Liu bool dc_is_oem_i2c_device_present( 149*7ae1dbe6SWenjing Liu struct dc *dc, 150*7ae1dbe6SWenjing Liu size_t slave_address) 151*7ae1dbe6SWenjing Liu { 152*7ae1dbe6SWenjing Liu if (dc->res_pool->oem_device) 153*7ae1dbe6SWenjing Liu return dce_i2c_oem_device_present( 154*7ae1dbe6SWenjing Liu dc->res_pool, 155*7ae1dbe6SWenjing Liu dc->res_pool->oem_device, 156*7ae1dbe6SWenjing Liu slave_address); 157*7ae1dbe6SWenjing Liu 158*7ae1dbe6SWenjing Liu return false; 159*7ae1dbe6SWenjing Liu } 160*7ae1dbe6SWenjing Liu 161*7ae1dbe6SWenjing Liu bool dc_submit_i2c( 162*7ae1dbe6SWenjing Liu struct dc *dc, 163*7ae1dbe6SWenjing Liu uint32_t link_index, 164*7ae1dbe6SWenjing Liu struct i2c_command *cmd) 165*7ae1dbe6SWenjing Liu { 166*7ae1dbe6SWenjing Liu 167*7ae1dbe6SWenjing Liu struct dc_link *link = dc->links[link_index]; 168*7ae1dbe6SWenjing Liu struct ddc_service *ddc = link->ddc; 169*7ae1dbe6SWenjing Liu 170*7ae1dbe6SWenjing Liu return dce_i2c_submit_command( 171*7ae1dbe6SWenjing Liu dc->res_pool, 172*7ae1dbe6SWenjing Liu ddc->ddc_pin, 173*7ae1dbe6SWenjing Liu cmd); 174*7ae1dbe6SWenjing Liu } 175*7ae1dbe6SWenjing Liu 176*7ae1dbe6SWenjing Liu bool dc_submit_i2c_oem( 177*7ae1dbe6SWenjing Liu struct dc *dc, 178*7ae1dbe6SWenjing Liu struct i2c_command *cmd) 179*7ae1dbe6SWenjing Liu { 180*7ae1dbe6SWenjing Liu struct ddc_service *ddc = dc->res_pool->oem_device; 181*7ae1dbe6SWenjing Liu 182*7ae1dbe6SWenjing Liu if (ddc) 183*7ae1dbe6SWenjing Liu return dce_i2c_submit_command( 184*7ae1dbe6SWenjing Liu dc->res_pool, 185*7ae1dbe6SWenjing Liu ddc->ddc_pin, 186*7ae1dbe6SWenjing Liu cmd); 187*7ae1dbe6SWenjing Liu 188*7ae1dbe6SWenjing Liu return false; 189*7ae1dbe6SWenjing Liu } 190*7ae1dbe6SWenjing Liu 191