linux/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
<<
>>
Prefs
   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#include "hdcp_psp.h"
  32
  33/*
  34 * If the SRM version being loaded is less than or equal to the
  35 * currently loaded SRM, psp will return 0xFFFF as the version
  36 */
  37#define PSP_SRM_VERSION_MAX 0xFFFF
  38
  39static bool
  40lp_write_i2c(void *handle, uint32_t address, const uint8_t *data, uint32_t size)
  41{
  42
  43        struct dc_link *link = handle;
  44        struct i2c_payload i2c_payloads[] = {{true, address, size, (void *)data} };
  45        struct i2c_command cmd = {i2c_payloads, 1, I2C_COMMAND_ENGINE_HW, link->dc->caps.i2c_speed_in_khz};
  46
  47        return dm_helpers_submit_i2c(link->ctx, link, &cmd);
  48}
  49
  50static bool
  51lp_read_i2c(void *handle, uint32_t address, uint8_t offset, uint8_t *data, uint32_t size)
  52{
  53        struct dc_link *link = handle;
  54
  55        struct i2c_payload i2c_payloads[] = {{true, address, 1, &offset}, {false, address, size, data} };
  56        struct i2c_command cmd = {i2c_payloads, 2, I2C_COMMAND_ENGINE_HW, link->dc->caps.i2c_speed_in_khz};
  57
  58        return dm_helpers_submit_i2c(link->ctx, link, &cmd);
  59}
  60
  61static bool
  62lp_write_dpcd(void *handle, uint32_t address, const uint8_t *data, uint32_t size)
  63{
  64        struct dc_link *link = handle;
  65
  66        return dm_helpers_dp_write_dpcd(link->ctx, link, address, data, size);
  67}
  68
  69static bool
  70lp_read_dpcd(void *handle, uint32_t address, uint8_t *data, uint32_t size)
  71{
  72        struct dc_link *link = handle;
  73
  74        return dm_helpers_dp_read_dpcd(link->ctx, link, address, data, size);
  75}
  76
  77static uint8_t *psp_get_srm(struct psp_context *psp, uint32_t *srm_version, uint32_t *srm_size)
  78{
  79
  80        struct ta_hdcp_shared_memory *hdcp_cmd;
  81
  82        if (!psp->hdcp_context.context.initialized) {
  83                DRM_WARN("Failed to get hdcp srm. HDCP TA is not initialized.");
  84                return NULL;
  85        }
  86
  87        hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
  88        memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
  89
  90        hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP_GET_SRM;
  91        psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
  92
  93        if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
  94                return NULL;
  95
  96        *srm_version = hdcp_cmd->out_msg.hdcp_get_srm.srm_version;
  97        *srm_size = hdcp_cmd->out_msg.hdcp_get_srm.srm_buf_size;
  98
  99
 100        return hdcp_cmd->out_msg.hdcp_get_srm.srm_buf;
 101}
 102
 103static int psp_set_srm(struct psp_context *psp, uint8_t *srm, uint32_t srm_size, uint32_t *srm_version)
 104{
 105
 106        struct ta_hdcp_shared_memory *hdcp_cmd;
 107
 108        if (!psp->hdcp_context.context.initialized) {
 109                DRM_WARN("Failed to get hdcp srm. HDCP TA is not initialized.");
 110                return -EINVAL;
 111        }
 112
 113        hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
 114        memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 115
 116        memcpy(hdcp_cmd->in_msg.hdcp_set_srm.srm_buf, srm, srm_size);
 117        hdcp_cmd->in_msg.hdcp_set_srm.srm_buf_size = srm_size;
 118        hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP_SET_SRM;
 119
 120        psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
 121
 122        if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS || hdcp_cmd->out_msg.hdcp_set_srm.valid_signature != 1 ||
 123            hdcp_cmd->out_msg.hdcp_set_srm.srm_version == PSP_SRM_VERSION_MAX)
 124                return -EINVAL;
 125
 126        *srm_version = hdcp_cmd->out_msg.hdcp_set_srm.srm_version;
 127        return 0;
 128}
 129
 130static void process_output(struct hdcp_workqueue *hdcp_work)
 131{
 132        struct mod_hdcp_output output = hdcp_work->output;
 133
 134        if (output.callback_stop)
 135                cancel_delayed_work(&hdcp_work->callback_dwork);
 136
 137        if (output.callback_needed)
 138                schedule_delayed_work(&hdcp_work->callback_dwork,
 139                                      msecs_to_jiffies(output.callback_delay));
 140
 141        if (output.watchdog_timer_stop)
 142                cancel_delayed_work(&hdcp_work->watchdog_timer_dwork);
 143
 144        if (output.watchdog_timer_needed)
 145                schedule_delayed_work(&hdcp_work->watchdog_timer_dwork,
 146                                      msecs_to_jiffies(output.watchdog_timer_delay));
 147
 148        schedule_delayed_work(&hdcp_work->property_validate_dwork, msecs_to_jiffies(0));
 149}
 150
 151static void link_lock(struct hdcp_workqueue *work, bool lock)
 152{
 153
 154        int i = 0;
 155
 156        for (i = 0; i < work->max_link; i++) {
 157                if (lock)
 158                        mutex_lock(&work[i].mutex);
 159                else
 160                        mutex_unlock(&work[i].mutex);
 161        }
 162}
 163void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
 164                         unsigned int link_index,
 165                         struct amdgpu_dm_connector *aconnector,
 166                         uint8_t content_type,
 167                         bool enable_encryption)
 168{
 169        struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
 170        struct mod_hdcp_display *display = &hdcp_work[link_index].display;
 171        struct mod_hdcp_link *link = &hdcp_work[link_index].link;
 172        struct mod_hdcp_display_query query;
 173
 174        mutex_lock(&hdcp_w->mutex);
 175        hdcp_w->aconnector = aconnector;
 176
 177        query.display = NULL;
 178        mod_hdcp_query_display(&hdcp_w->hdcp, aconnector->base.index, &query);
 179
 180        if (query.display != NULL) {
 181                memcpy(display, query.display, sizeof(struct mod_hdcp_display));
 182                mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
 183
 184                hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0;
 185
 186                if (enable_encryption) {
 187                        /* Explicitly set the saved SRM as sysfs call will be after we already enabled hdcp
 188                         * (s3 resume case)
 189                         */
 190                        if (hdcp_work->srm_size > 0)
 191                                psp_set_srm(hdcp_work->hdcp.config.psp.handle, hdcp_work->srm, hdcp_work->srm_size,
 192                                            &hdcp_work->srm_version);
 193
 194                        display->adjust.disable = MOD_HDCP_DISPLAY_NOT_DISABLE;
 195                        if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0) {
 196                                hdcp_w->link.adjust.hdcp1.disable = 0;
 197                                hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0;
 198                        } else if (content_type == DRM_MODE_HDCP_CONTENT_TYPE1) {
 199                                hdcp_w->link.adjust.hdcp1.disable = 1;
 200                                hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_1;
 201                        }
 202
 203                        schedule_delayed_work(&hdcp_w->property_validate_dwork,
 204                                              msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS));
 205                } else {
 206                        display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION;
 207                        hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
 208                        cancel_delayed_work(&hdcp_w->property_validate_dwork);
 209                }
 210
 211                display->state = MOD_HDCP_DISPLAY_ACTIVE;
 212        }
 213
 214        mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
 215
 216        process_output(hdcp_w);
 217        mutex_unlock(&hdcp_w->mutex);
 218}
 219
 220static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
 221                         unsigned int link_index,
 222                         struct amdgpu_dm_connector *aconnector)
 223{
 224        struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
 225        struct drm_connector_state *conn_state = aconnector->base.state;
 226
 227        mutex_lock(&hdcp_w->mutex);
 228        hdcp_w->aconnector = aconnector;
 229
 230        /* the removal of display will invoke auth reset -> hdcp destroy and
 231         * we'd expect the Content Protection (CP) property changed back to
 232         * DESIRED if at the time ENABLED. CP property change should occur
 233         * before the element removed from linked list.
 234         */
 235        if (conn_state && conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
 236                conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
 237
 238                DRM_DEBUG_DRIVER("[HDCP_DM] display %d, CP 2 -> 1, type %u, DPMS %u\n",
 239                         aconnector->base.index, conn_state->hdcp_content_type, aconnector->base.dpms);
 240        }
 241
 242        mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
 243
 244        process_output(hdcp_w);
 245        mutex_unlock(&hdcp_w->mutex);
 246}
 247void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
 248{
 249        struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
 250
 251        mutex_lock(&hdcp_w->mutex);
 252
 253        mod_hdcp_reset_connection(&hdcp_w->hdcp,  &hdcp_w->output);
 254
 255        cancel_delayed_work(&hdcp_w->property_validate_dwork);
 256        hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
 257
 258        process_output(hdcp_w);
 259
 260        mutex_unlock(&hdcp_w->mutex);
 261}
 262
 263void hdcp_handle_cpirq(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
 264{
 265        struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
 266
 267        schedule_work(&hdcp_w->cpirq_work);
 268}
 269
 270
 271
 272
 273static void event_callback(struct work_struct *work)
 274{
 275        struct hdcp_workqueue *hdcp_work;
 276
 277        hdcp_work = container_of(to_delayed_work(work), struct hdcp_workqueue,
 278                                      callback_dwork);
 279
 280        mutex_lock(&hdcp_work->mutex);
 281
 282        cancel_delayed_work(&hdcp_work->callback_dwork);
 283
 284        mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CALLBACK,
 285                               &hdcp_work->output);
 286
 287        process_output(hdcp_work);
 288
 289        mutex_unlock(&hdcp_work->mutex);
 290
 291
 292}
 293static void event_property_update(struct work_struct *work)
 294{
 295
 296        struct hdcp_workqueue *hdcp_work = container_of(work, struct hdcp_workqueue, property_update_work);
 297        struct amdgpu_dm_connector *aconnector = hdcp_work->aconnector;
 298        struct drm_device *dev = hdcp_work->aconnector->base.dev;
 299        long ret;
 300
 301        drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
 302        mutex_lock(&hdcp_work->mutex);
 303
 304
 305        if (aconnector->base.state->commit) {
 306                ret = wait_for_completion_interruptible_timeout(&aconnector->base.state->commit->hw_done, 10 * HZ);
 307
 308                if (ret == 0) {
 309                        DRM_ERROR("HDCP state unknown! Setting it to DESIRED");
 310                        hdcp_work->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
 311                }
 312        }
 313
 314        if (hdcp_work->encryption_status != MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF) {
 315                if (aconnector->base.state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE0 &&
 316                    hdcp_work->encryption_status <= MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE0_ON)
 317                        drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED);
 318                else if (aconnector->base.state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE1 &&
 319                         hdcp_work->encryption_status == MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE1_ON)
 320                        drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED);
 321        } else {
 322                drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_DESIRED);
 323        }
 324
 325
 326        mutex_unlock(&hdcp_work->mutex);
 327        drm_modeset_unlock(&dev->mode_config.connection_mutex);
 328}
 329
 330static void event_property_validate(struct work_struct *work)
 331{
 332        struct hdcp_workqueue *hdcp_work =
 333                container_of(to_delayed_work(work), struct hdcp_workqueue, property_validate_dwork);
 334        struct mod_hdcp_display_query query;
 335        struct amdgpu_dm_connector *aconnector = hdcp_work->aconnector;
 336
 337        if (!aconnector)
 338                return;
 339
 340        mutex_lock(&hdcp_work->mutex);
 341
 342        query.encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
 343        mod_hdcp_query_display(&hdcp_work->hdcp, aconnector->base.index, &query);
 344
 345        if (query.encryption_status != hdcp_work->encryption_status) {
 346                hdcp_work->encryption_status = query.encryption_status;
 347                schedule_work(&hdcp_work->property_update_work);
 348        }
 349
 350        mutex_unlock(&hdcp_work->mutex);
 351}
 352
 353static void event_watchdog_timer(struct work_struct *work)
 354{
 355        struct hdcp_workqueue *hdcp_work;
 356
 357        hdcp_work = container_of(to_delayed_work(work),
 358                                      struct hdcp_workqueue,
 359                                      watchdog_timer_dwork);
 360
 361        mutex_lock(&hdcp_work->mutex);
 362
 363        cancel_delayed_work(&hdcp_work->watchdog_timer_dwork);
 364
 365        mod_hdcp_process_event(&hdcp_work->hdcp,
 366                               MOD_HDCP_EVENT_WATCHDOG_TIMEOUT,
 367                               &hdcp_work->output);
 368
 369        process_output(hdcp_work);
 370
 371        mutex_unlock(&hdcp_work->mutex);
 372
 373}
 374
 375static void event_cpirq(struct work_struct *work)
 376{
 377        struct hdcp_workqueue *hdcp_work;
 378
 379        hdcp_work = container_of(work, struct hdcp_workqueue, cpirq_work);
 380
 381        mutex_lock(&hdcp_work->mutex);
 382
 383        mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CPIRQ, &hdcp_work->output);
 384
 385        process_output(hdcp_work);
 386
 387        mutex_unlock(&hdcp_work->mutex);
 388
 389}
 390
 391
 392void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work)
 393{
 394        int i = 0;
 395
 396        for (i = 0; i < hdcp_work->max_link; i++) {
 397                cancel_delayed_work_sync(&hdcp_work[i].callback_dwork);
 398                cancel_delayed_work_sync(&hdcp_work[i].watchdog_timer_dwork);
 399        }
 400
 401        sysfs_remove_bin_file(kobj, &hdcp_work[0].attr);
 402        kfree(hdcp_work->srm);
 403        kfree(hdcp_work->srm_temp);
 404        kfree(hdcp_work);
 405}
 406
 407
 408static bool enable_assr(void *handle, struct dc_link *link)
 409{
 410
 411        struct hdcp_workqueue *hdcp_work = handle;
 412        struct mod_hdcp hdcp = hdcp_work->hdcp;
 413        struct psp_context *psp = hdcp.config.psp.handle;
 414        struct ta_dtm_shared_memory *dtm_cmd;
 415        bool res = true;
 416
 417        if (!psp->dtm_context.context.initialized) {
 418                DRM_INFO("Failed to enable ASSR, DTM TA is not initialized.");
 419                return false;
 420        }
 421
 422        dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;
 423
 424        mutex_lock(&psp->dtm_context.mutex);
 425        memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
 426
 427        dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_ASSR_ENABLE;
 428        dtm_cmd->dtm_in_message.topology_assr_enable.display_topology_dig_be_index = link->link_enc_hw_inst;
 429        dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
 430
 431        psp_dtm_invoke(psp, dtm_cmd->cmd_id);
 432
 433        if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
 434                DRM_INFO("Failed to enable ASSR");
 435                res = false;
 436        }
 437
 438        mutex_unlock(&psp->dtm_context.mutex);
 439
 440        return res;
 441}
 442
 443static void update_config(void *handle, struct cp_psp_stream_config *config)
 444{
 445        struct hdcp_workqueue *hdcp_work = handle;
 446        struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx;
 447        int link_index = aconnector->dc_link->link_index;
 448        struct mod_hdcp_display *display = &hdcp_work[link_index].display;
 449        struct mod_hdcp_link *link = &hdcp_work[link_index].link;
 450        struct drm_connector_state *conn_state;
 451
 452        if (config->dpms_off) {
 453                hdcp_remove_display(hdcp_work, link_index, aconnector);
 454                return;
 455        }
 456
 457        memset(display, 0, sizeof(*display));
 458        memset(link, 0, sizeof(*link));
 459
 460        display->index = aconnector->base.index;
 461        display->state = MOD_HDCP_DISPLAY_ACTIVE;
 462
 463        if (aconnector->dc_sink != NULL)
 464                link->mode = mod_hdcp_signal_type_to_operation_mode(aconnector->dc_sink->sink_signal);
 465
 466        display->controller = CONTROLLER_ID_D0 + config->otg_inst;
 467        display->dig_fe = config->dig_fe;
 468        link->dig_be = config->dig_be;
 469        link->ddc_line = aconnector->dc_link->ddc_hw_inst + 1;
 470        display->stream_enc_idx = config->stream_enc_idx;
 471        link->link_enc_idx = config->link_enc_idx;
 472        link->phy_idx = config->phy_idx;
 473        link->hdcp_supported_informational = dc_link_is_hdcp14(aconnector->dc_link,
 474                        aconnector->dc_sink->sink_signal) ? 1 : 0;
 475        link->dp.rev = aconnector->dc_link->dpcd_caps.dpcd_rev.raw;
 476        link->dp.assr_enabled = config->assr_enabled;
 477        link->dp.mst_enabled = config->mst_enabled;
 478        display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION;
 479        link->adjust.auth_delay = 3;
 480        link->adjust.hdcp1.disable = 0;
 481        conn_state = aconnector->base.state;
 482
 483        DRM_DEBUG_DRIVER("[HDCP_DM] display %d, CP %d, type %d\n", aconnector->base.index,
 484                        (!!aconnector->base.state) ? aconnector->base.state->content_protection : -1,
 485                        (!!aconnector->base.state) ? aconnector->base.state->hdcp_content_type : -1);
 486
 487        hdcp_update_display(hdcp_work, link_index, aconnector, conn_state->hdcp_content_type, false);
 488}
 489
 490
 491/* NOTE: From the usermodes prospective you only need to call write *ONCE*, the kernel
 492 *      will automatically call once or twice depending on the size
 493 *
 494 * call: "cat file > /sys/class/drm/card0/device/hdcp_srm" from usermode no matter what the size is
 495 *
 496 * The kernel can only send PAGE_SIZE at once and since MAX_SRM_FILE(5120) > PAGE_SIZE(4096),
 497 * srm_data_write can be called multiple times.
 498 *
 499 * sysfs interface doesn't tell us the size we will get so we are sending partial SRMs to psp and on
 500 * the last call we will send the full SRM. PSP will fail on every call before the last.
 501 *
 502 * This means we don't know if the SRM is good until the last call. And because of this limitation we
 503 * cannot throw errors early as it will stop the kernel from writing to sysfs
 504 *
 505 * Example 1:
 506 *      Good SRM size = 5096
 507 *      first call to write 4096 -> PSP fails
 508 *      Second call to write 1000 -> PSP Pass -> SRM is set
 509 *
 510 * Example 2:
 511 *      Bad SRM size = 4096
 512 *      first call to write 4096 -> PSP fails (This is the same as above, but we don't know if this
 513 *      is the last call)
 514 *
 515 * Solution?:
 516 *      1: Parse the SRM? -> It is signed so we don't know the EOF
 517 *      2: We can have another sysfs that passes the size before calling set. -> simpler solution
 518 *      below
 519 *
 520 * Easy Solution:
 521 * Always call get after Set to verify if set was successful.
 522 * +----------------------+
 523 * |   Why it works:      |
 524 * +----------------------+
 525 * PSP will only update its srm if its older than the one we are trying to load.
 526 * Always do set first than get.
 527 *      -if we try to "1. SET" a older version PSP will reject it and we can "2. GET" the newer
 528 *      version and save it
 529 *
 530 *      -if we try to "1. SET" a newer version PSP will accept it and we can "2. GET" the
 531 *      same(newer) version back and save it
 532 *
 533 *      -if we try to "1. SET" a newer version and PSP rejects it. That means the format is
 534 *      incorrect/corrupted and we should correct our SRM by getting it from PSP
 535 */
 536static ssize_t srm_data_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer,
 537                              loff_t pos, size_t count)
 538{
 539        struct hdcp_workqueue *work;
 540        uint32_t srm_version = 0;
 541
 542        work = container_of(bin_attr, struct hdcp_workqueue, attr);
 543        link_lock(work, true);
 544
 545        memcpy(work->srm_temp + pos, buffer, count);
 546
 547        if (!psp_set_srm(work->hdcp.config.psp.handle, work->srm_temp, pos + count, &srm_version)) {
 548                DRM_DEBUG_DRIVER("HDCP SRM SET version 0x%X", srm_version);
 549                memcpy(work->srm, work->srm_temp, pos + count);
 550                work->srm_size = pos + count;
 551                work->srm_version = srm_version;
 552        }
 553
 554
 555        link_lock(work, false);
 556
 557        return count;
 558}
 559
 560static ssize_t srm_data_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer,
 561                             loff_t pos, size_t count)
 562{
 563        struct hdcp_workqueue *work;
 564        uint8_t *srm = NULL;
 565        uint32_t srm_version;
 566        uint32_t srm_size;
 567        size_t ret = count;
 568
 569        work = container_of(bin_attr, struct hdcp_workqueue, attr);
 570
 571        link_lock(work, true);
 572
 573        srm = psp_get_srm(work->hdcp.config.psp.handle, &srm_version, &srm_size);
 574
 575        if (!srm) {
 576                ret = -EINVAL;
 577                goto ret;
 578        }
 579
 580        if (pos >= srm_size)
 581                ret = 0;
 582
 583        if (srm_size - pos < count) {
 584                memcpy(buffer, srm + pos, srm_size - pos);
 585                ret = srm_size - pos;
 586                goto ret;
 587        }
 588
 589        memcpy(buffer, srm + pos, count);
 590
 591ret:
 592        link_lock(work, false);
 593        return ret;
 594}
 595
 596/* From the hdcp spec (5.Renewability) SRM needs to be stored in a non-volatile memory.
 597 *
 598 * For example,
 599 *      if Application "A" sets the SRM (ver 2) and we reboot/suspend and later when Application "B"
 600 *      needs to use HDCP, the version in PSP should be SRM(ver 2). So SRM should be persistent
 601 *      across boot/reboots/suspend/resume/shutdown
 602 *
 603 * Currently when the system goes down (suspend/shutdown) the SRM is cleared from PSP. For HDCP we need
 604 * to make the SRM persistent.
 605 *
 606 * -PSP owns the checking of SRM but doesn't have the ability to store it in a non-volatile memory.
 607 * -The kernel cannot write to the file systems.
 608 * -So we need usermode to do this for us, which is why an interface for usermode is needed
 609 *
 610 *
 611 *
 612 * Usermode can read/write to/from PSP using the sysfs interface
 613 * For example:
 614 *      to save SRM from PSP to storage : cat /sys/class/drm/card0/device/hdcp_srm > srmfile
 615 *      to load from storage to PSP: cat srmfile > /sys/class/drm/card0/device/hdcp_srm
 616 */
 617static const struct bin_attribute data_attr = {
 618        .attr = {.name = "hdcp_srm", .mode = 0664},
 619        .size = PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE, /* Limit SRM size */
 620        .write = srm_data_write,
 621        .read = srm_data_read,
 622};
 623
 624
 625struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, struct cp_psp *cp_psp, struct dc *dc)
 626{
 627
 628        int max_caps = dc->caps.max_links;
 629        struct hdcp_workqueue *hdcp_work;
 630        int i = 0;
 631
 632        hdcp_work = kcalloc(max_caps, sizeof(*hdcp_work), GFP_KERNEL);
 633        if (ZERO_OR_NULL_PTR(hdcp_work))
 634                return NULL;
 635
 636        hdcp_work->srm = kcalloc(PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE, sizeof(*hdcp_work->srm), GFP_KERNEL);
 637
 638        if (hdcp_work->srm == NULL)
 639                goto fail_alloc_context;
 640
 641        hdcp_work->srm_temp = kcalloc(PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE, sizeof(*hdcp_work->srm_temp), GFP_KERNEL);
 642
 643        if (hdcp_work->srm_temp == NULL)
 644                goto fail_alloc_context;
 645
 646        hdcp_work->max_link = max_caps;
 647
 648        for (i = 0; i < max_caps; i++) {
 649                mutex_init(&hdcp_work[i].mutex);
 650
 651                INIT_WORK(&hdcp_work[i].cpirq_work, event_cpirq);
 652                INIT_WORK(&hdcp_work[i].property_update_work, event_property_update);
 653                INIT_DELAYED_WORK(&hdcp_work[i].callback_dwork, event_callback);
 654                INIT_DELAYED_WORK(&hdcp_work[i].watchdog_timer_dwork, event_watchdog_timer);
 655                INIT_DELAYED_WORK(&hdcp_work[i].property_validate_dwork, event_property_validate);
 656
 657                hdcp_work[i].hdcp.config.psp.handle = &adev->psp;
 658                if (dc->ctx->dce_version == DCN_VERSION_3_1)
 659                        hdcp_work[i].hdcp.config.psp.caps.dtm_v3_supported = 1;
 660                hdcp_work[i].hdcp.config.ddc.handle = dc_get_link_at_index(dc, i);
 661                hdcp_work[i].hdcp.config.ddc.funcs.write_i2c = lp_write_i2c;
 662                hdcp_work[i].hdcp.config.ddc.funcs.read_i2c = lp_read_i2c;
 663                hdcp_work[i].hdcp.config.ddc.funcs.write_dpcd = lp_write_dpcd;
 664                hdcp_work[i].hdcp.config.ddc.funcs.read_dpcd = lp_read_dpcd;
 665        }
 666
 667        cp_psp->funcs.update_stream_config = update_config;
 668        cp_psp->funcs.enable_assr = enable_assr;
 669        cp_psp->handle = hdcp_work;
 670
 671        /* File created at /sys/class/drm/card0/device/hdcp_srm*/
 672        hdcp_work[0].attr = data_attr;
 673        sysfs_bin_attr_init(&hdcp_work[0].attr);
 674
 675        if (sysfs_create_bin_file(&adev->dev->kobj, &hdcp_work[0].attr))
 676                DRM_WARN("Failed to create device file hdcp_srm");
 677
 678        return hdcp_work;
 679
 680fail_alloc_context:
 681        kfree(hdcp_work->srm);
 682        kfree(hdcp_work->srm_temp);
 683        kfree(hdcp_work);
 684
 685        return NULL;
 686
 687
 688
 689}
 690
 691
 692
 693