linux/drivers/gpu/drm/i915/display/intel_dmc.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2014 Intel Corporation
   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 (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21 * IN THE SOFTWARE.
  22 *
  23 */
  24
  25#include <linux/firmware.h>
  26
  27#include "i915_drv.h"
  28#include "i915_reg.h"
  29#include "intel_de.h"
  30#include "intel_dmc.h"
  31
  32/**
  33 * DOC: DMC Firmware Support
  34 *
  35 * From gen9 onwards we have newly added DMC (Display microcontroller) in display
  36 * engine to save and restore the state of display engine when it enter into
  37 * low-power state and comes back to normal.
  38 */
  39
  40#define DMC_PATH(platform, major, minor) \
  41        "i915/"                          \
  42        __stringify(platform) "_dmc_ver" \
  43        __stringify(major) "_"           \
  44        __stringify(minor) ".bin"
  45
  46#define GEN12_DMC_MAX_FW_SIZE           ICL_DMC_MAX_FW_SIZE
  47
  48#define ADLS_DMC_PATH                   DMC_PATH(adls, 2, 01)
  49#define ADLS_DMC_VERSION_REQUIRED       DMC_VERSION(2, 1)
  50MODULE_FIRMWARE(ADLS_DMC_PATH);
  51
  52#define DG1_DMC_PATH                    DMC_PATH(dg1, 2, 02)
  53#define DG1_DMC_VERSION_REQUIRED        DMC_VERSION(2, 2)
  54MODULE_FIRMWARE(DG1_DMC_PATH);
  55
  56#define RKL_DMC_PATH                    DMC_PATH(rkl, 2, 02)
  57#define RKL_DMC_VERSION_REQUIRED        DMC_VERSION(2, 2)
  58MODULE_FIRMWARE(RKL_DMC_PATH);
  59
  60#define TGL_DMC_PATH                    DMC_PATH(tgl, 2, 08)
  61#define TGL_DMC_VERSION_REQUIRED        DMC_VERSION(2, 8)
  62MODULE_FIRMWARE(TGL_DMC_PATH);
  63
  64#define ICL_DMC_PATH                    DMC_PATH(icl, 1, 09)
  65#define ICL_DMC_VERSION_REQUIRED        DMC_VERSION(1, 9)
  66#define ICL_DMC_MAX_FW_SIZE             0x6000
  67MODULE_FIRMWARE(ICL_DMC_PATH);
  68
  69#define CNL_DMC_PATH                    DMC_PATH(cnl, 1, 07)
  70#define CNL_DMC_VERSION_REQUIRED        DMC_VERSION(1, 7)
  71#define CNL_DMC_MAX_FW_SIZE             GLK_DMC_MAX_FW_SIZE
  72MODULE_FIRMWARE(CNL_DMC_PATH);
  73
  74#define GLK_DMC_PATH                    DMC_PATH(glk, 1, 04)
  75#define GLK_DMC_VERSION_REQUIRED        DMC_VERSION(1, 4)
  76#define GLK_DMC_MAX_FW_SIZE             0x4000
  77MODULE_FIRMWARE(GLK_DMC_PATH);
  78
  79#define KBL_DMC_PATH                    DMC_PATH(kbl, 1, 04)
  80#define KBL_DMC_VERSION_REQUIRED        DMC_VERSION(1, 4)
  81#define KBL_DMC_MAX_FW_SIZE             BXT_DMC_MAX_FW_SIZE
  82MODULE_FIRMWARE(KBL_DMC_PATH);
  83
  84#define SKL_DMC_PATH                    DMC_PATH(skl, 1, 27)
  85#define SKL_DMC_VERSION_REQUIRED        DMC_VERSION(1, 27)
  86#define SKL_DMC_MAX_FW_SIZE             BXT_DMC_MAX_FW_SIZE
  87MODULE_FIRMWARE(SKL_DMC_PATH);
  88
  89#define BXT_DMC_PATH                    DMC_PATH(bxt, 1, 07)
  90#define BXT_DMC_VERSION_REQUIRED        DMC_VERSION(1, 7)
  91#define BXT_DMC_MAX_FW_SIZE             0x3000
  92MODULE_FIRMWARE(BXT_DMC_PATH);
  93
  94#define DMC_DEFAULT_FW_OFFSET           0xFFFFFFFF
  95#define PACKAGE_MAX_FW_INFO_ENTRIES     20
  96#define PACKAGE_V2_MAX_FW_INFO_ENTRIES  32
  97#define DMC_V1_MAX_MMIO_COUNT           8
  98#define DMC_V3_MAX_MMIO_COUNT           20
  99
 100struct intel_css_header {
 101        /* 0x09 for DMC */
 102        u32 module_type;
 103
 104        /* Includes the DMC specific header in dwords */
 105        u32 header_len;
 106
 107        /* always value would be 0x10000 */
 108        u32 header_ver;
 109
 110        /* Not used */
 111        u32 module_id;
 112
 113        /* Not used */
 114        u32 module_vendor;
 115
 116        /* in YYYYMMDD format */
 117        u32 date;
 118
 119        /* Size in dwords (CSS_Headerlen + PackageHeaderLen + dmc FWsLen)/4 */
 120        u32 size;
 121
 122        /* Not used */
 123        u32 key_size;
 124
 125        /* Not used */
 126        u32 modulus_size;
 127
 128        /* Not used */
 129        u32 exponent_size;
 130
 131        /* Not used */
 132        u32 reserved1[12];
 133
 134        /* Major Minor */
 135        u32 version;
 136
 137        /* Not used */
 138        u32 reserved2[8];
 139
 140        /* Not used */
 141        u32 kernel_header_info;
 142} __packed;
 143
 144struct intel_fw_info {
 145        u8 reserved1;
 146
 147        /* reserved on package_header version 1, must be 0 on version 2 */
 148        u8 dmc_id;
 149
 150        /* Stepping (A, B, C, ..., *). * is a wildcard */
 151        char stepping;
 152
 153        /* Sub-stepping (0, 1, ..., *). * is a wildcard */
 154        char substepping;
 155
 156        u32 offset;
 157        u32 reserved2;
 158} __packed;
 159
 160struct intel_package_header {
 161        /* DMC container header length in dwords */
 162        u8 header_len;
 163
 164        /* 0x01, 0x02 */
 165        u8 header_ver;
 166
 167        u8 reserved[10];
 168
 169        /* Number of valid entries in the FWInfo array below */
 170        u32 num_entries;
 171} __packed;
 172
 173struct intel_dmc_header_base {
 174        /* always value would be 0x40403E3E */
 175        u32 signature;
 176
 177        /* DMC binary header length */
 178        u8 header_len;
 179
 180        /* 0x01 */
 181        u8 header_ver;
 182
 183        /* Reserved */
 184        u16 dmcc_ver;
 185
 186        /* Major, Minor */
 187        u32 project;
 188
 189        /* Firmware program size (excluding header) in dwords */
 190        u32 fw_size;
 191
 192        /* Major Minor version */
 193        u32 fw_version;
 194} __packed;
 195
 196struct intel_dmc_header_v1 {
 197        struct intel_dmc_header_base base;
 198
 199        /* Number of valid MMIO cycles present. */
 200        u32 mmio_count;
 201
 202        /* MMIO address */
 203        u32 mmioaddr[DMC_V1_MAX_MMIO_COUNT];
 204
 205        /* MMIO data */
 206        u32 mmiodata[DMC_V1_MAX_MMIO_COUNT];
 207
 208        /* FW filename  */
 209        char dfile[32];
 210
 211        u32 reserved1[2];
 212} __packed;
 213
 214struct intel_dmc_header_v3 {
 215        struct intel_dmc_header_base base;
 216
 217        /* DMC RAM start MMIO address */
 218        u32 start_mmioaddr;
 219
 220        u32 reserved[9];
 221
 222        /* FW filename */
 223        char dfile[32];
 224
 225        /* Number of valid MMIO cycles present. */
 226        u32 mmio_count;
 227
 228        /* MMIO address */
 229        u32 mmioaddr[DMC_V3_MAX_MMIO_COUNT];
 230
 231        /* MMIO data */
 232        u32 mmiodata[DMC_V3_MAX_MMIO_COUNT];
 233} __packed;
 234
 235struct stepping_info {
 236        char stepping;
 237        char substepping;
 238};
 239
 240bool intel_dmc_has_payload(struct drm_i915_private *i915)
 241{
 242        return i915->dmc.dmc_payload;
 243}
 244
 245static const struct stepping_info skl_stepping_info[] = {
 246        {'A', '0'}, {'B', '0'}, {'C', '0'},
 247        {'D', '0'}, {'E', '0'}, {'F', '0'},
 248        {'G', '0'}, {'H', '0'}, {'I', '0'},
 249        {'J', '0'}, {'K', '0'}
 250};
 251
 252static const struct stepping_info bxt_stepping_info[] = {
 253        {'A', '0'}, {'A', '1'}, {'A', '2'},
 254        {'B', '0'}, {'B', '1'}, {'B', '2'}
 255};
 256
 257static const struct stepping_info icl_stepping_info[] = {
 258        {'A', '0'}, {'A', '1'}, {'A', '2'},
 259        {'B', '0'}, {'B', '2'},
 260        {'C', '0'}
 261};
 262
 263static const struct stepping_info no_stepping_info = { '*', '*' };
 264
 265static const struct stepping_info *
 266intel_get_stepping_info(struct drm_i915_private *dev_priv)
 267{
 268        const struct stepping_info *si;
 269        unsigned int size;
 270
 271        if (IS_ICELAKE(dev_priv)) {
 272                size = ARRAY_SIZE(icl_stepping_info);
 273                si = icl_stepping_info;
 274        } else if (IS_SKYLAKE(dev_priv)) {
 275                size = ARRAY_SIZE(skl_stepping_info);
 276                si = skl_stepping_info;
 277        } else if (IS_BROXTON(dev_priv)) {
 278                size = ARRAY_SIZE(bxt_stepping_info);
 279                si = bxt_stepping_info;
 280        } else {
 281                size = 0;
 282                si = NULL;
 283        }
 284
 285        if (INTEL_REVID(dev_priv) < size)
 286                return si + INTEL_REVID(dev_priv);
 287
 288        return &no_stepping_info;
 289}
 290
 291static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv)
 292{
 293        u32 val, mask;
 294
 295        mask = DC_STATE_DEBUG_MASK_MEMORY_UP;
 296
 297        if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
 298                mask |= DC_STATE_DEBUG_MASK_CORES;
 299
 300        /* The below bit doesn't need to be cleared ever afterwards */
 301        val = intel_de_read(dev_priv, DC_STATE_DEBUG);
 302        if ((val & mask) != mask) {
 303                val |= mask;
 304                intel_de_write(dev_priv, DC_STATE_DEBUG, val);
 305                intel_de_posting_read(dev_priv, DC_STATE_DEBUG);
 306        }
 307}
 308
 309/**
 310 * intel_dmc_load_program() - write the firmware from memory to register.
 311 * @dev_priv: i915 drm device.
 312 *
 313 * DMC firmware is read from a .bin file and kept in internal memory one time.
 314 * Everytime display comes back from low power state this function is called to
 315 * copy the firmware from internal memory to registers.
 316 */
 317void intel_dmc_load_program(struct drm_i915_private *dev_priv)
 318{
 319        u32 *payload = dev_priv->dmc.dmc_payload;
 320        u32 i, fw_size;
 321
 322        if (!HAS_DMC(dev_priv)) {
 323                drm_err(&dev_priv->drm,
 324                        "No DMC support available for this platform\n");
 325                return;
 326        }
 327
 328        if (!intel_dmc_has_payload(dev_priv)) {
 329                drm_err(&dev_priv->drm,
 330                        "Tried to program CSR with empty payload\n");
 331                return;
 332        }
 333
 334        fw_size = dev_priv->dmc.dmc_fw_size;
 335        assert_rpm_wakelock_held(&dev_priv->runtime_pm);
 336
 337        preempt_disable();
 338
 339        for (i = 0; i < fw_size; i++)
 340                intel_uncore_write_fw(&dev_priv->uncore, DMC_PROGRAM(i),
 341                                      payload[i]);
 342
 343        preempt_enable();
 344
 345        for (i = 0; i < dev_priv->dmc.mmio_count; i++) {
 346                intel_de_write(dev_priv, dev_priv->dmc.mmioaddr[i],
 347                               dev_priv->dmc.mmiodata[i]);
 348        }
 349
 350        dev_priv->dmc.dc_state = 0;
 351
 352        gen9_set_dc_state_debugmask(dev_priv);
 353}
 354
 355/*
 356 * Search fw_info table for dmc_offset to find firmware binary: num_entries is
 357 * already sanitized.
 358 */
 359static u32 find_dmc_fw_offset(const struct intel_fw_info *fw_info,
 360                              unsigned int num_entries,
 361                              const struct stepping_info *si,
 362                              u8 package_ver)
 363{
 364        u32 dmc_offset = DMC_DEFAULT_FW_OFFSET;
 365        unsigned int i;
 366
 367        for (i = 0; i < num_entries; i++) {
 368                if (package_ver > 1 && fw_info[i].dmc_id != 0)
 369                        continue;
 370
 371                if (fw_info[i].substepping == '*' &&
 372                    si->stepping == fw_info[i].stepping) {
 373                        dmc_offset = fw_info[i].offset;
 374                        break;
 375                }
 376
 377                if (si->stepping == fw_info[i].stepping &&
 378                    si->substepping == fw_info[i].substepping) {
 379                        dmc_offset = fw_info[i].offset;
 380                        break;
 381                }
 382
 383                if (fw_info[i].stepping == '*' &&
 384                    fw_info[i].substepping == '*') {
 385                        /*
 386                         * In theory we should stop the search as generic
 387                         * entries should always come after the more specific
 388                         * ones, but let's continue to make sure to work even
 389                         * with "broken" firmwares. If we don't find a more
 390                         * specific one, then we use this entry
 391                         */
 392                        dmc_offset = fw_info[i].offset;
 393                }
 394        }
 395
 396        return dmc_offset;
 397}
 398
 399static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
 400                               const struct intel_dmc_header_base *dmc_header,
 401                               size_t rem_size)
 402{
 403        struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc);
 404        unsigned int header_len_bytes, dmc_header_size, payload_size, i;
 405        const u32 *mmioaddr, *mmiodata;
 406        u32 mmio_count, mmio_count_max;
 407        u8 *payload;
 408
 409        BUILD_BUG_ON(ARRAY_SIZE(dmc->mmioaddr) < DMC_V3_MAX_MMIO_COUNT ||
 410                     ARRAY_SIZE(dmc->mmioaddr) < DMC_V1_MAX_MMIO_COUNT);
 411
 412        /*
 413         * Check if we can access common fields, we will checkc again below
 414         * after we have read the version
 415         */
 416        if (rem_size < sizeof(struct intel_dmc_header_base))
 417                goto error_truncated;
 418
 419        /* Cope with small differences between v1 and v3 */
 420        if (dmc_header->header_ver == 3) {
 421                const struct intel_dmc_header_v3 *v3 =
 422                        (const struct intel_dmc_header_v3 *)dmc_header;
 423
 424                if (rem_size < sizeof(struct intel_dmc_header_v3))
 425                        goto error_truncated;
 426
 427                mmioaddr = v3->mmioaddr;
 428                mmiodata = v3->mmiodata;
 429                mmio_count = v3->mmio_count;
 430                mmio_count_max = DMC_V3_MAX_MMIO_COUNT;
 431                /* header_len is in dwords */
 432                header_len_bytes = dmc_header->header_len * 4;
 433                dmc_header_size = sizeof(*v3);
 434        } else if (dmc_header->header_ver == 1) {
 435                const struct intel_dmc_header_v1 *v1 =
 436                        (const struct intel_dmc_header_v1 *)dmc_header;
 437
 438                if (rem_size < sizeof(struct intel_dmc_header_v1))
 439                        goto error_truncated;
 440
 441                mmioaddr = v1->mmioaddr;
 442                mmiodata = v1->mmiodata;
 443                mmio_count = v1->mmio_count;
 444                mmio_count_max = DMC_V1_MAX_MMIO_COUNT;
 445                header_len_bytes = dmc_header->header_len;
 446                dmc_header_size = sizeof(*v1);
 447        } else {
 448                drm_err(&i915->drm, "Unknown DMC fw header version: %u\n",
 449                        dmc_header->header_ver);
 450                return 0;
 451        }
 452
 453        if (header_len_bytes != dmc_header_size) {
 454                drm_err(&i915->drm, "DMC firmware has wrong dmc header length "
 455                        "(%u bytes)\n", header_len_bytes);
 456                return 0;
 457        }
 458
 459        /* Cache the dmc header info. */
 460        if (mmio_count > mmio_count_max) {
 461                drm_err(&i915->drm, "DMC firmware has wrong mmio count %u\n", mmio_count);
 462                return 0;
 463        }
 464
 465        for (i = 0; i < mmio_count; i++) {
 466                if (mmioaddr[i] < DMC_MMIO_START_RANGE ||
 467                    mmioaddr[i] > DMC_MMIO_END_RANGE) {
 468                        drm_err(&i915->drm, "DMC firmware has wrong mmio address 0x%x\n",
 469                                mmioaddr[i]);
 470                        return 0;
 471                }
 472                dmc->mmioaddr[i] = _MMIO(mmioaddr[i]);
 473                dmc->mmiodata[i] = mmiodata[i];
 474        }
 475        dmc->mmio_count = mmio_count;
 476
 477        rem_size -= header_len_bytes;
 478
 479        /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */
 480        payload_size = dmc_header->fw_size * 4;
 481        if (rem_size < payload_size)
 482                goto error_truncated;
 483
 484        if (payload_size > dmc->max_fw_size) {
 485                drm_err(&i915->drm, "DMC FW too big (%u bytes)\n", payload_size);
 486                return 0;
 487        }
 488        dmc->dmc_fw_size = dmc_header->fw_size;
 489
 490        dmc->dmc_payload = kmalloc(payload_size, GFP_KERNEL);
 491        if (!dmc->dmc_payload)
 492                return 0;
 493
 494        payload = (u8 *)(dmc_header) + header_len_bytes;
 495        memcpy(dmc->dmc_payload, payload, payload_size);
 496
 497        return header_len_bytes + payload_size;
 498
 499error_truncated:
 500        drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n");
 501        return 0;
 502}
 503
 504static u32
 505parse_dmc_fw_package(struct intel_dmc *dmc,
 506                     const struct intel_package_header *package_header,
 507                     const struct stepping_info *si,
 508                     size_t rem_size)
 509{
 510        struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc);
 511        u32 package_size = sizeof(struct intel_package_header);
 512        u32 num_entries, max_entries, dmc_offset;
 513        const struct intel_fw_info *fw_info;
 514
 515        if (rem_size < package_size)
 516                goto error_truncated;
 517
 518        if (package_header->header_ver == 1) {
 519                max_entries = PACKAGE_MAX_FW_INFO_ENTRIES;
 520        } else if (package_header->header_ver == 2) {
 521                max_entries = PACKAGE_V2_MAX_FW_INFO_ENTRIES;
 522        } else {
 523                drm_err(&i915->drm, "DMC firmware has unknown header version %u\n",
 524                        package_header->header_ver);
 525                return 0;
 526        }
 527
 528        /*
 529         * We should always have space for max_entries,
 530         * even if not all are used
 531         */
 532        package_size += max_entries * sizeof(struct intel_fw_info);
 533        if (rem_size < package_size)
 534                goto error_truncated;
 535
 536        if (package_header->header_len * 4 != package_size) {
 537                drm_err(&i915->drm, "DMC firmware has wrong package header length "
 538                        "(%u bytes)\n", package_size);
 539                return 0;
 540        }
 541
 542        num_entries = package_header->num_entries;
 543        if (WARN_ON(package_header->num_entries > max_entries))
 544                num_entries = max_entries;
 545
 546        fw_info = (const struct intel_fw_info *)
 547                ((u8 *)package_header + sizeof(*package_header));
 548        dmc_offset = find_dmc_fw_offset(fw_info, num_entries, si,
 549                                        package_header->header_ver);
 550        if (dmc_offset == DMC_DEFAULT_FW_OFFSET) {
 551                drm_err(&i915->drm, "DMC firmware not supported for %c stepping\n",
 552                        si->stepping);
 553                return 0;
 554        }
 555
 556        /* dmc_offset is in dwords */
 557        return package_size + dmc_offset * 4;
 558
 559error_truncated:
 560        drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n");
 561        return 0;
 562}
 563
 564/* Return number of bytes parsed or 0 on error */
 565static u32 parse_dmc_fw_css(struct intel_dmc *dmc,
 566                            struct intel_css_header *css_header,
 567                            size_t rem_size)
 568{
 569        struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc);
 570
 571        if (rem_size < sizeof(struct intel_css_header)) {
 572                drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n");
 573                return 0;
 574        }
 575
 576        if (sizeof(struct intel_css_header) !=
 577            (css_header->header_len * 4)) {
 578                drm_err(&i915->drm, "DMC firmware has wrong CSS header length "
 579                        "(%u bytes)\n",
 580                        (css_header->header_len * 4));
 581                return 0;
 582        }
 583
 584        if (dmc->required_version &&
 585            css_header->version != dmc->required_version) {
 586                drm_info(&i915->drm, "Refusing to load DMC firmware v%u.%u,"
 587                         " please use v%u.%u\n",
 588                         DMC_VERSION_MAJOR(css_header->version),
 589                         DMC_VERSION_MINOR(css_header->version),
 590                         DMC_VERSION_MAJOR(dmc->required_version),
 591                         DMC_VERSION_MINOR(dmc->required_version));
 592                return 0;
 593        }
 594
 595        dmc->version = css_header->version;
 596
 597        return sizeof(struct intel_css_header);
 598}
 599
 600static void parse_dmc_fw(struct drm_i915_private *dev_priv,
 601                         const struct firmware *fw)
 602{
 603        struct intel_css_header *css_header;
 604        struct intel_package_header *package_header;
 605        struct intel_dmc_header_base *dmc_header;
 606        struct intel_dmc *dmc = &dev_priv->dmc;
 607        const struct stepping_info *si = intel_get_stepping_info(dev_priv);
 608        u32 readcount = 0;
 609        u32 r;
 610
 611        if (!fw)
 612                return;
 613
 614        /* Extract CSS Header information */
 615        css_header = (struct intel_css_header *)fw->data;
 616        r = parse_dmc_fw_css(dmc, css_header, fw->size);
 617        if (!r)
 618                return;
 619
 620        readcount += r;
 621
 622        /* Extract Package Header information */
 623        package_header = (struct intel_package_header *)&fw->data[readcount];
 624        r = parse_dmc_fw_package(dmc, package_header, si, fw->size - readcount);
 625        if (!r)
 626                return;
 627
 628        readcount += r;
 629
 630        /* Extract dmc_header information */
 631        dmc_header = (struct intel_dmc_header_base *)&fw->data[readcount];
 632        parse_dmc_fw_header(dmc, dmc_header, fw->size - readcount);
 633}
 634
 635static void intel_dmc_runtime_pm_get(struct drm_i915_private *dev_priv)
 636{
 637        drm_WARN_ON(&dev_priv->drm, dev_priv->dmc.wakeref);
 638        dev_priv->dmc.wakeref =
 639                intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
 640}
 641
 642static void intel_dmc_runtime_pm_put(struct drm_i915_private *dev_priv)
 643{
 644        intel_wakeref_t wakeref __maybe_unused =
 645                fetch_and_zero(&dev_priv->dmc.wakeref);
 646
 647        intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
 648}
 649
 650static void dmc_load_work_fn(struct work_struct *work)
 651{
 652        struct drm_i915_private *dev_priv;
 653        struct intel_dmc *dmc;
 654        const struct firmware *fw = NULL;
 655
 656        dev_priv = container_of(work, typeof(*dev_priv), dmc.work);
 657        dmc = &dev_priv->dmc;
 658
 659        request_firmware(&fw, dev_priv->dmc.fw_path, dev_priv->drm.dev);
 660        parse_dmc_fw(dev_priv, fw);
 661
 662        if (intel_dmc_has_payload(dev_priv)) {
 663                intel_dmc_load_program(dev_priv);
 664                intel_dmc_runtime_pm_put(dev_priv);
 665
 666                drm_info(&dev_priv->drm,
 667                         "Finished loading DMC firmware %s (v%u.%u)\n",
 668                         dev_priv->dmc.fw_path, DMC_VERSION_MAJOR(dmc->version),
 669                         DMC_VERSION_MINOR(dmc->version));
 670        } else {
 671                drm_notice(&dev_priv->drm,
 672                           "Failed to load DMC firmware %s."
 673                           " Disabling runtime power management.\n",
 674                           dmc->fw_path);
 675                drm_notice(&dev_priv->drm, "DMC firmware homepage: %s",
 676                           INTEL_UC_FIRMWARE_URL);
 677        }
 678
 679        release_firmware(fw);
 680}
 681
 682/**
 683 * intel_dmc_ucode_init() - initialize the firmware loading.
 684 * @dev_priv: i915 drm device.
 685 *
 686 * This function is called at the time of loading the display driver to read
 687 * firmware from a .bin file and copied into a internal memory.
 688 */
 689void intel_dmc_ucode_init(struct drm_i915_private *dev_priv)
 690{
 691        struct intel_dmc *dmc = &dev_priv->dmc;
 692
 693        INIT_WORK(&dev_priv->dmc.work, dmc_load_work_fn);
 694
 695        if (!HAS_DMC(dev_priv))
 696                return;
 697
 698        /*
 699         * Obtain a runtime pm reference, until DMC is loaded, to avoid entering
 700         * runtime-suspend.
 701         *
 702         * On error, we return with the rpm wakeref held to prevent runtime
 703         * suspend as runtime suspend *requires* a working DMC for whatever
 704         * reason.
 705         */
 706        intel_dmc_runtime_pm_get(dev_priv);
 707
 708        if (IS_ALDERLAKE_S(dev_priv)) {
 709                dmc->fw_path = ADLS_DMC_PATH;
 710                dmc->required_version = ADLS_DMC_VERSION_REQUIRED;
 711                dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
 712        } else if (IS_DG1(dev_priv)) {
 713                dmc->fw_path = DG1_DMC_PATH;
 714                dmc->required_version = DG1_DMC_VERSION_REQUIRED;
 715                dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
 716        } else if (IS_ROCKETLAKE(dev_priv)) {
 717                dmc->fw_path = RKL_DMC_PATH;
 718                dmc->required_version = RKL_DMC_VERSION_REQUIRED;
 719                dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
 720        } else if (DISPLAY_VER(dev_priv) >= 12) {
 721                dmc->fw_path = TGL_DMC_PATH;
 722                dmc->required_version = TGL_DMC_VERSION_REQUIRED;
 723                dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
 724        } else if (DISPLAY_VER(dev_priv) == 11) {
 725                dmc->fw_path = ICL_DMC_PATH;
 726                dmc->required_version = ICL_DMC_VERSION_REQUIRED;
 727                dmc->max_fw_size = ICL_DMC_MAX_FW_SIZE;
 728        } else if (IS_CANNONLAKE(dev_priv)) {
 729                dmc->fw_path = CNL_DMC_PATH;
 730                dmc->required_version = CNL_DMC_VERSION_REQUIRED;
 731                dmc->max_fw_size = CNL_DMC_MAX_FW_SIZE;
 732        } else if (IS_GEMINILAKE(dev_priv)) {
 733                dmc->fw_path = GLK_DMC_PATH;
 734                dmc->required_version = GLK_DMC_VERSION_REQUIRED;
 735                dmc->max_fw_size = GLK_DMC_MAX_FW_SIZE;
 736        } else if (IS_KABYLAKE(dev_priv) ||
 737                   IS_COFFEELAKE(dev_priv) ||
 738                   IS_COMETLAKE(dev_priv)) {
 739                dmc->fw_path = KBL_DMC_PATH;
 740                dmc->required_version = KBL_DMC_VERSION_REQUIRED;
 741                dmc->max_fw_size = KBL_DMC_MAX_FW_SIZE;
 742        } else if (IS_SKYLAKE(dev_priv)) {
 743                dmc->fw_path = SKL_DMC_PATH;
 744                dmc->required_version = SKL_DMC_VERSION_REQUIRED;
 745                dmc->max_fw_size = SKL_DMC_MAX_FW_SIZE;
 746        } else if (IS_BROXTON(dev_priv)) {
 747                dmc->fw_path = BXT_DMC_PATH;
 748                dmc->required_version = BXT_DMC_VERSION_REQUIRED;
 749                dmc->max_fw_size = BXT_DMC_MAX_FW_SIZE;
 750        }
 751
 752        if (dev_priv->params.dmc_firmware_path) {
 753                if (strlen(dev_priv->params.dmc_firmware_path) == 0) {
 754                        dmc->fw_path = NULL;
 755                        drm_info(&dev_priv->drm,
 756                                 "Disabling DMC firmware and runtime PM\n");
 757                        return;
 758                }
 759
 760                dmc->fw_path = dev_priv->params.dmc_firmware_path;
 761                /* Bypass version check for firmware override. */
 762                dmc->required_version = 0;
 763        }
 764
 765        if (!dmc->fw_path) {
 766                drm_dbg_kms(&dev_priv->drm,
 767                            "No known DMC firmware for platform, disabling runtime PM\n");
 768                return;
 769        }
 770
 771        drm_dbg_kms(&dev_priv->drm, "Loading %s\n", dmc->fw_path);
 772        schedule_work(&dev_priv->dmc.work);
 773}
 774
 775/**
 776 * intel_dmc_ucode_suspend() - prepare DMC firmware before system suspend
 777 * @dev_priv: i915 drm device
 778 *
 779 * Prepare the DMC firmware before entering system suspend. This includes
 780 * flushing pending work items and releasing any resources acquired during
 781 * init.
 782 */
 783void intel_dmc_ucode_suspend(struct drm_i915_private *dev_priv)
 784{
 785        if (!HAS_DMC(dev_priv))
 786                return;
 787
 788        flush_work(&dev_priv->dmc.work);
 789
 790        /* Drop the reference held in case DMC isn't loaded. */
 791        if (!intel_dmc_has_payload(dev_priv))
 792                intel_dmc_runtime_pm_put(dev_priv);
 793}
 794
 795/**
 796 * intel_dmc_ucode_resume() - init DMC firmware during system resume
 797 * @dev_priv: i915 drm device
 798 *
 799 * Reinitialize the DMC firmware during system resume, reacquiring any
 800 * resources released in intel_dmc_ucode_suspend().
 801 */
 802void intel_dmc_ucode_resume(struct drm_i915_private *dev_priv)
 803{
 804        if (!HAS_DMC(dev_priv))
 805                return;
 806
 807        /*
 808         * Reacquire the reference to keep RPM disabled in case DMC isn't
 809         * loaded.
 810         */
 811        if (!intel_dmc_has_payload(dev_priv))
 812                intel_dmc_runtime_pm_get(dev_priv);
 813}
 814
 815/**
 816 * intel_dmc_ucode_fini() - unload the DMC firmware.
 817 * @dev_priv: i915 drm device.
 818 *
 819 * Firmmware unloading includes freeing the internal memory and reset the
 820 * firmware loading status.
 821 */
 822void intel_dmc_ucode_fini(struct drm_i915_private *dev_priv)
 823{
 824        if (!HAS_DMC(dev_priv))
 825                return;
 826
 827        intel_dmc_ucode_suspend(dev_priv);
 828        drm_WARN_ON(&dev_priv->drm, dev_priv->dmc.wakeref);
 829
 830        kfree(dev_priv->dmc.dmc_payload);
 831}
 832