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 "amdgpu_dm_hdcp.h" 27 #include "amdgpu.h" 28 #include "amdgpu_dm.h" 29 #include "dm_helpers.h" 30 #include <drm/drm_hdcp.h> 31 32 static bool 33 lp_write_i2c(void *handle, uint32_t address, const uint8_t *data, uint32_t size) 34 { 35 36 struct dc_link *link = handle; 37 struct i2c_payload i2c_payloads[] = {{true, address, size, (void *)data} }; 38 struct i2c_command cmd = {i2c_payloads, 1, I2C_COMMAND_ENGINE_HW, link->dc->caps.i2c_speed_in_khz}; 39 40 return dm_helpers_submit_i2c(link->ctx, link, &cmd); 41 } 42 43 static bool 44 lp_read_i2c(void *handle, uint32_t address, uint8_t offset, uint8_t *data, uint32_t size) 45 { 46 struct dc_link *link = handle; 47 48 struct i2c_payload i2c_payloads[] = {{true, address, 1, &offset}, {false, address, size, data} }; 49 struct i2c_command cmd = {i2c_payloads, 2, I2C_COMMAND_ENGINE_HW, link->dc->caps.i2c_speed_in_khz}; 50 51 return dm_helpers_submit_i2c(link->ctx, link, &cmd); 52 } 53 54 static bool 55 lp_write_dpcd(void *handle, uint32_t address, const uint8_t *data, uint32_t size) 56 { 57 struct dc_link *link = handle; 58 59 return dm_helpers_dp_write_dpcd(link->ctx, link, address, data, size); 60 } 61 62 static bool 63 lp_read_dpcd(void *handle, uint32_t address, uint8_t *data, uint32_t size) 64 { 65 struct dc_link *link = handle; 66 67 return dm_helpers_dp_read_dpcd(link->ctx, link, address, data, size); 68 } 69 70 static void process_output(struct hdcp_workqueue *hdcp_work) 71 { 72 struct mod_hdcp_output output = hdcp_work->output; 73 74 if (output.callback_stop) 75 cancel_delayed_work(&hdcp_work->callback_dwork); 76 77 if (output.callback_needed) 78 schedule_delayed_work(&hdcp_work->callback_dwork, 79 msecs_to_jiffies(output.callback_delay)); 80 81 if (output.watchdog_timer_stop) 82 cancel_delayed_work(&hdcp_work->watchdog_timer_dwork); 83 84 if (output.watchdog_timer_needed) 85 schedule_delayed_work(&hdcp_work->watchdog_timer_dwork, 86 msecs_to_jiffies(output.watchdog_timer_delay)); 87 88 } 89 90 void hdcp_add_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index, struct amdgpu_dm_connector *aconnector) 91 { 92 struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index]; 93 struct mod_hdcp_display *display = &hdcp_work[link_index].display; 94 struct mod_hdcp_link *link = &hdcp_work[link_index].link; 95 96 mutex_lock(&hdcp_w->mutex); 97 hdcp_w->aconnector = aconnector; 98 99 mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output); 100 101 schedule_delayed_work(&hdcp_w->property_validate_dwork, msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS)); 102 103 process_output(hdcp_w); 104 105 mutex_unlock(&hdcp_w->mutex); 106 107 } 108 109 void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index, unsigned int display_index) 110 { 111 struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index]; 112 113 mutex_lock(&hdcp_w->mutex); 114 115 mod_hdcp_remove_display(&hdcp_w->hdcp, display_index, &hdcp_w->output); 116 117 cancel_delayed_work(&hdcp_w->property_validate_dwork); 118 hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF; 119 120 process_output(hdcp_w); 121 122 mutex_unlock(&hdcp_w->mutex); 123 124 } 125 126 void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index) 127 { 128 struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index]; 129 130 mutex_lock(&hdcp_w->mutex); 131 132 mod_hdcp_reset_connection(&hdcp_w->hdcp, &hdcp_w->output); 133 134 cancel_delayed_work(&hdcp_w->property_validate_dwork); 135 hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF; 136 137 process_output(hdcp_w); 138 139 mutex_unlock(&hdcp_w->mutex); 140 } 141 142 void hdcp_handle_cpirq(struct hdcp_workqueue *hdcp_work, unsigned int link_index) 143 { 144 struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index]; 145 146 schedule_work(&hdcp_w->cpirq_work); 147 } 148 149 150 151 152 static void event_callback(struct work_struct *work) 153 { 154 struct hdcp_workqueue *hdcp_work; 155 156 hdcp_work = container_of(to_delayed_work(work), struct hdcp_workqueue, 157 callback_dwork); 158 159 mutex_lock(&hdcp_work->mutex); 160 161 cancel_delayed_work(&hdcp_work->watchdog_timer_dwork); 162 163 mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CALLBACK, 164 &hdcp_work->output); 165 166 process_output(hdcp_work); 167 168 mutex_unlock(&hdcp_work->mutex); 169 170 171 } 172 static void event_property_update(struct work_struct *work) 173 { 174 175 struct hdcp_workqueue *hdcp_work = container_of(work, struct hdcp_workqueue, property_update_work); 176 struct amdgpu_dm_connector *aconnector = hdcp_work->aconnector; 177 struct drm_device *dev = hdcp_work->aconnector->base.dev; 178 long ret; 179 180 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 181 mutex_lock(&hdcp_work->mutex); 182 183 184 if (aconnector->base.state->commit) { 185 ret = wait_for_completion_interruptible_timeout(&aconnector->base.state->commit->hw_done, 10 * HZ); 186 187 if (ret == 0) { 188 DRM_ERROR("HDCP state unknown! Setting it to DESIRED"); 189 hdcp_work->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF; 190 } 191 } 192 193 if (hdcp_work->encryption_status == MOD_HDCP_ENCRYPTION_STATUS_HDCP1_ON) 194 drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED); 195 else 196 drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_DESIRED); 197 198 199 mutex_unlock(&hdcp_work->mutex); 200 drm_modeset_unlock(&dev->mode_config.connection_mutex); 201 } 202 203 static void event_property_validate(struct work_struct *work) 204 { 205 struct hdcp_workqueue *hdcp_work = 206 container_of(to_delayed_work(work), struct hdcp_workqueue, property_validate_dwork); 207 struct mod_hdcp_display_query query; 208 struct amdgpu_dm_connector *aconnector = hdcp_work->aconnector; 209 210 mutex_lock(&hdcp_work->mutex); 211 212 query.encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF; 213 mod_hdcp_query_display(&hdcp_work->hdcp, aconnector->base.index, &query); 214 215 if (query.encryption_status != hdcp_work->encryption_status) { 216 hdcp_work->encryption_status = query.encryption_status; 217 schedule_work(&hdcp_work->property_update_work); 218 } 219 220 schedule_delayed_work(&hdcp_work->property_validate_dwork, msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS)); 221 222 mutex_unlock(&hdcp_work->mutex); 223 } 224 225 static void event_watchdog_timer(struct work_struct *work) 226 { 227 struct hdcp_workqueue *hdcp_work; 228 229 hdcp_work = container_of(to_delayed_work(work), 230 struct hdcp_workqueue, 231 watchdog_timer_dwork); 232 233 mutex_lock(&hdcp_work->mutex); 234 235 mod_hdcp_process_event(&hdcp_work->hdcp, 236 MOD_HDCP_EVENT_WATCHDOG_TIMEOUT, 237 &hdcp_work->output); 238 239 process_output(hdcp_work); 240 241 mutex_unlock(&hdcp_work->mutex); 242 243 } 244 245 static void event_cpirq(struct work_struct *work) 246 { 247 struct hdcp_workqueue *hdcp_work; 248 249 hdcp_work = container_of(work, struct hdcp_workqueue, cpirq_work); 250 251 mutex_lock(&hdcp_work->mutex); 252 253 mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CPIRQ, &hdcp_work->output); 254 255 process_output(hdcp_work); 256 257 mutex_unlock(&hdcp_work->mutex); 258 259 } 260 261 262 void hdcp_destroy(struct hdcp_workqueue *hdcp_work) 263 { 264 int i = 0; 265 266 for (i = 0; i < hdcp_work->max_link; i++) { 267 cancel_delayed_work_sync(&hdcp_work[i].callback_dwork); 268 cancel_delayed_work_sync(&hdcp_work[i].watchdog_timer_dwork); 269 } 270 271 kfree(hdcp_work); 272 273 } 274 275 static void update_config(void *handle, struct cp_psp_stream_config *config) 276 { 277 struct hdcp_workqueue *hdcp_work = handle; 278 struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx; 279 int link_index = aconnector->dc_link->link_index; 280 struct mod_hdcp_display *display = &hdcp_work[link_index].display; 281 struct mod_hdcp_link *link = &hdcp_work[link_index].link; 282 283 memset(display, 0, sizeof(*display)); 284 memset(link, 0, sizeof(*link)); 285 286 display->index = aconnector->base.index; 287 display->state = MOD_HDCP_DISPLAY_ACTIVE; 288 289 if (aconnector->dc_sink != NULL) 290 link->mode = mod_hdcp_signal_type_to_operation_mode(aconnector->dc_sink->sink_signal); 291 292 display->controller = CONTROLLER_ID_D0 + config->otg_inst; 293 display->dig_fe = config->stream_enc_inst; 294 link->dig_be = config->link_enc_inst; 295 link->ddc_line = aconnector->dc_link->ddc_hw_inst + 1; 296 link->dp.rev = aconnector->dc_link->dpcd_caps.dpcd_rev.raw; 297 link->adjust.hdcp2.disable = 1; 298 299 } 300 301 struct hdcp_workqueue *hdcp_create_workqueue(void *psp_context, struct cp_psp *cp_psp, struct dc *dc) 302 { 303 304 int max_caps = dc->caps.max_links; 305 struct hdcp_workqueue *hdcp_work = kzalloc(max_caps*sizeof(*hdcp_work), GFP_KERNEL); 306 int i = 0; 307 308 if (hdcp_work == NULL) 309 goto fail_alloc_context; 310 311 hdcp_work->max_link = max_caps; 312 313 for (i = 0; i < max_caps; i++) { 314 315 mutex_init(&hdcp_work[i].mutex); 316 317 INIT_WORK(&hdcp_work[i].cpirq_work, event_cpirq); 318 INIT_WORK(&hdcp_work[i].property_update_work, event_property_update); 319 INIT_DELAYED_WORK(&hdcp_work[i].callback_dwork, event_callback); 320 INIT_DELAYED_WORK(&hdcp_work[i].watchdog_timer_dwork, event_watchdog_timer); 321 INIT_DELAYED_WORK(&hdcp_work[i].property_validate_dwork, event_property_validate); 322 323 hdcp_work[i].hdcp.config.psp.handle = psp_context; 324 hdcp_work[i].hdcp.config.ddc.handle = dc_get_link_at_index(dc, i); 325 hdcp_work[i].hdcp.config.ddc.funcs.write_i2c = lp_write_i2c; 326 hdcp_work[i].hdcp.config.ddc.funcs.read_i2c = lp_read_i2c; 327 hdcp_work[i].hdcp.config.ddc.funcs.write_dpcd = lp_write_dpcd; 328 hdcp_work[i].hdcp.config.ddc.funcs.read_dpcd = lp_read_dpcd; 329 } 330 331 cp_psp->funcs.update_stream_config = update_config; 332 cp_psp->handle = hdcp_work; 333 334 return hdcp_work; 335 336 fail_alloc_context: 337 kfree(hdcp_work); 338 339 return NULL; 340 341 342 343 } 344 345 346 347