LCOV - code coverage report
Current view: top level - dev/pci/drm/i915 - intel_csr.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 60 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #ifdef __linux__
      25             : #include <linux/firmware.h>
      26             : #endif
      27             : #include "i915_drv.h"
      28             : #include "i915_reg.h"
      29             : 
      30             : /**
      31             :  * DOC: csr support for dmc
      32             :  *
      33             :  * Display Context Save and Restore (CSR) firmware support added from gen9
      34             :  * onwards to drive newly added DMC (Display microcontroller) in display
      35             :  * engine to save and restore the state of display engine when it enter into
      36             :  * low-power state and comes back to normal.
      37             :  *
      38             :  * Firmware loading status will be one of the below states: FW_UNINITIALIZED,
      39             :  * FW_LOADED, FW_FAILED.
      40             :  *
      41             :  * Once the firmware is written into the registers status will be moved from
      42             :  * FW_UNINITIALIZED to FW_LOADED and for any erroneous condition status will
      43             :  * be moved to FW_FAILED.
      44             :  */
      45             : 
      46             : #define I915_CSR_KBL "i915/kbl_dmc_ver1.bin"
      47             : #define I915_CSR_SKL "i915/skl_dmc_ver1.bin"
      48             : #define I915_CSR_BXT "i915/bxt_dmc_ver1.bin"
      49             : 
      50             : MODULE_FIRMWARE(I915_CSR_KBL);
      51             : MODULE_FIRMWARE(I915_CSR_SKL);
      52             : MODULE_FIRMWARE(I915_CSR_BXT);
      53             : 
      54             : /*
      55             : * SKL CSR registers for DC5 and DC6
      56             : */
      57             : #define CSR_PROGRAM(i)                  (0x80000 + (i) * 4)
      58             : #define CSR_SSP_BASE_ADDR_GEN9          0x00002FC0
      59             : #define CSR_HTP_ADDR_SKL                0x00500034
      60             : #define CSR_SSP_BASE                    0x8F074
      61             : #define CSR_HTP_SKL                     0x8F004
      62             : #define CSR_LAST_WRITE                  0x8F034
      63             : #define CSR_LAST_WRITE_VALUE            0xc003b400
      64             : /* MMIO address range for CSR program (0x80000 - 0x82FFF) */
      65             : #define CSR_MAX_FW_SIZE                 0x2FFF
      66             : #define CSR_DEFAULT_FW_OFFSET           0xFFFFFFFF
      67             : #define CSR_MMIO_START_RANGE    0x80000
      68             : #define CSR_MMIO_END_RANGE              0x8FFFF
      69             : 
      70             : struct intel_css_header {
      71             :         /* 0x09 for DMC */
      72             :         uint32_t module_type;
      73             : 
      74             :         /* Includes the DMC specific header in dwords */
      75             :         uint32_t header_len;
      76             : 
      77             :         /* always value would be 0x10000 */
      78             :         uint32_t header_ver;
      79             : 
      80             :         /* Not used */
      81             :         uint32_t module_id;
      82             : 
      83             :         /* Not used */
      84             :         uint32_t module_vendor;
      85             : 
      86             :         /* in YYYYMMDD format */
      87             :         uint32_t date;
      88             : 
      89             :         /* Size in dwords (CSS_Headerlen + PackageHeaderLen + dmc FWsLen)/4 */
      90             :         uint32_t size;
      91             : 
      92             :         /* Not used */
      93             :         uint32_t key_size;
      94             : 
      95             :         /* Not used */
      96             :         uint32_t modulus_size;
      97             : 
      98             :         /* Not used */
      99             :         uint32_t exponent_size;
     100             : 
     101             :         /* Not used */
     102             :         uint32_t reserved1[12];
     103             : 
     104             :         /* Major Minor */
     105             :         uint32_t version;
     106             : 
     107             :         /* Not used */
     108             :         uint32_t reserved2[8];
     109             : 
     110             :         /* Not used */
     111             :         uint32_t kernel_header_info;
     112             : } __packed;
     113             : 
     114             : struct intel_fw_info {
     115             :         uint16_t reserved1;
     116             : 
     117             :         /* Stepping (A, B, C, ..., *). * is a wildcard */
     118             :         char stepping;
     119             : 
     120             :         /* Sub-stepping (0, 1, ..., *). * is a wildcard */
     121             :         char substepping;
     122             : 
     123             :         uint32_t offset;
     124             :         uint32_t reserved2;
     125             : } __packed;
     126             : 
     127             : struct intel_package_header {
     128             :         /* DMC container header length in dwords */
     129             :         unsigned char header_len;
     130             : 
     131             :         /* always value would be 0x01 */
     132             :         unsigned char header_ver;
     133             : 
     134             :         unsigned char reserved[10];
     135             : 
     136             :         /* Number of valid entries in the FWInfo array below */
     137             :         uint32_t num_entries;
     138             : 
     139             :         struct intel_fw_info fw_info[20];
     140             : } __packed;
     141             : 
     142             : struct intel_dmc_header {
     143             :         /* always value would be 0x40403E3E */
     144             :         uint32_t signature;
     145             : 
     146             :         /* DMC binary header length */
     147             :         unsigned char header_len;
     148             : 
     149             :         /* 0x01 */
     150             :         unsigned char header_ver;
     151             : 
     152             :         /* Reserved */
     153             :         uint16_t dmcc_ver;
     154             : 
     155             :         /* Major, Minor */
     156             :         uint32_t        project;
     157             : 
     158             :         /* Firmware program size (excluding header) in dwords */
     159             :         uint32_t        fw_size;
     160             : 
     161             :         /* Major Minor version */
     162             :         uint32_t fw_version;
     163             : 
     164             :         /* Number of valid MMIO cycles present. */
     165             :         uint32_t mmio_count;
     166             : 
     167             :         /* MMIO address */
     168             :         uint32_t mmioaddr[8];
     169             : 
     170             :         /* MMIO data */
     171             :         uint32_t mmiodata[8];
     172             : 
     173             :         /* FW filename  */
     174             :         unsigned char dfile[32];
     175             : 
     176             :         uint32_t reserved1[2];
     177             : } __packed;
     178             : 
     179             : #ifdef __linux__
     180             : struct stepping_info {
     181             :         char stepping;
     182             :         char substepping;
     183             : };
     184             : 
     185             : /*
     186             :  * Kabylake derivated from Skylake H0, so SKL H0
     187             :  * is the right firmware for KBL A0 (revid 0).
     188             :  */
     189             : static const struct stepping_info kbl_stepping_info[] = {
     190             :         {'H', '0'}, {'I', '0'}
     191             : };
     192             : 
     193             : static const struct stepping_info skl_stepping_info[] = {
     194             :                 {'A', '0'}, {'B', '0'}, {'C', '0'},
     195             :                 {'D', '0'}, {'E', '0'}, {'F', '0'},
     196             :                 {'G', '0'}, {'H', '0'}, {'I', '0'},
     197             :                 {'J', '0'}, {'K', '0'}
     198             : };
     199             : 
     200             : static struct stepping_info bxt_stepping_info[] = {
     201             :         {'A', '0'}, {'A', '1'}, {'A', '2'},
     202             :         {'B', '0'}, {'B', '1'}, {'B', '2'}
     203             : };
     204             : 
     205             : static char intel_get_stepping(struct drm_device *dev)
     206             : {
     207             :         if (IS_KABYLAKE(dev) && (dev->pdev->revision <
     208             :                         ARRAY_SIZE(kbl_stepping_info)))
     209             :                 return kbl_stepping_info[dev->pdev->revision].stepping;
     210             :         else if (IS_SKYLAKE(dev) && (dev->pdev->revision <
     211             :                         ARRAY_SIZE(skl_stepping_info)))
     212             :                 return skl_stepping_info[dev->pdev->revision].stepping;
     213             :         else if (IS_BROXTON(dev) && (dev->pdev->revision <
     214             :                                 ARRAY_SIZE(bxt_stepping_info)))
     215             :                 return bxt_stepping_info[dev->pdev->revision].stepping;
     216             :         else
     217             :                 return -ENODATA;
     218             : }
     219             : 
     220             : static char intel_get_substepping(struct drm_device *dev)
     221             : {
     222             :         if (IS_KABYLAKE(dev) && (dev->pdev->revision <
     223             :                         ARRAY_SIZE(kbl_stepping_info)))
     224             :                 return kbl_stepping_info[dev->pdev->revision].substepping;
     225             :         else if (IS_SKYLAKE(dev) && (dev->pdev->revision <
     226             :                         ARRAY_SIZE(skl_stepping_info)))
     227             :                 return skl_stepping_info[dev->pdev->revision].substepping;
     228             :         else if (IS_BROXTON(dev) && (dev->pdev->revision <
     229             :                         ARRAY_SIZE(bxt_stepping_info)))
     230             :                 return bxt_stepping_info[dev->pdev->revision].substepping;
     231             :         else
     232             :                 return -ENODATA;
     233             : }
     234             : #endif
     235             : 
     236             : /**
     237             :  * intel_csr_load_status_get() - to get firmware loading status.
     238             :  * @dev_priv: i915 device.
     239             :  *
     240             :  * This function helps to get the firmware loading status.
     241             :  *
     242             :  * Return: Firmware loading status.
     243             :  */
     244           0 : enum csr_state intel_csr_load_status_get(struct drm_i915_private *dev_priv)
     245             : {
     246             :         enum csr_state state;
     247             : 
     248           0 :         mutex_lock(&dev_priv->csr_lock);
     249           0 :         state = dev_priv->csr.state;
     250           0 :         mutex_unlock(&dev_priv->csr_lock);
     251             : 
     252           0 :         return state;
     253             : }
     254             : 
     255             : /**
     256             :  * intel_csr_load_status_set() - help to set firmware loading status.
     257             :  * @dev_priv: i915 device.
     258             :  * @state: enumeration of firmware loading status.
     259             :  *
     260             :  * Set the firmware loading status.
     261             :  */
     262           0 : void intel_csr_load_status_set(struct drm_i915_private *dev_priv,
     263             :                         enum csr_state state)
     264             : {
     265           0 :         mutex_lock(&dev_priv->csr_lock);
     266           0 :         dev_priv->csr.state = state;
     267           0 :         mutex_unlock(&dev_priv->csr_lock);
     268           0 : }
     269             : 
     270             : /**
     271             :  * intel_csr_load_program() - write the firmware from memory to register.
     272             :  * @dev: drm device.
     273             :  *
     274             :  * CSR firmware is read from a .bin file and kept in internal memory one time.
     275             :  * Everytime display comes back from low power state this function is called to
     276             :  * copy the firmware from internal memory to registers.
     277             :  */
     278           0 : void intel_csr_load_program(struct drm_device *dev)
     279             : {
     280           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
     281           0 :         u32 *payload = dev_priv->csr.dmc_payload;
     282             :         uint32_t i, fw_size;
     283             : 
     284           0 :         if (!IS_GEN9(dev)) {
     285           0 :                 DRM_ERROR("No CSR support available for this platform\n");
     286           0 :                 return;
     287             :         }
     288             : 
     289             :         /*
     290             :          * FIXME: Firmware gets lost on S3/S4, but not when entering system
     291             :          * standby or suspend-to-idle (which is just like forced runtime pm).
     292             :          * Unfortunately the ACPI subsystem doesn't yet give us a way to
     293             :          * differentiate this, hence figure it out with this hack.
     294             :          */
     295           0 :         if (I915_READ(CSR_PROGRAM(0)))
     296           0 :                 return;
     297             : 
     298           0 :         mutex_lock(&dev_priv->csr_lock);
     299           0 :         fw_size = dev_priv->csr.dmc_fw_size;
     300           0 :         for (i = 0; i < fw_size; i++)
     301           0 :                 I915_WRITE(CSR_PROGRAM(i), payload[i]);
     302             : 
     303           0 :         for (i = 0; i < dev_priv->csr.mmio_count; i++) {
     304           0 :                 I915_WRITE(dev_priv->csr.mmioaddr[i],
     305             :                         dev_priv->csr.mmiodata[i]);
     306             :         }
     307             : 
     308           0 :         dev_priv->csr.state = FW_LOADED;
     309           0 :         mutex_unlock(&dev_priv->csr_lock);
     310           0 : }
     311             : 
     312             : #ifdef __linux__
     313             : static void finish_csr_load(const struct firmware *fw, void *context)
     314             : {
     315             :         struct drm_i915_private *dev_priv = context;
     316             :         struct drm_device *dev = dev_priv->dev;
     317             :         struct intel_css_header *css_header;
     318             :         struct intel_package_header *package_header;
     319             :         struct intel_dmc_header *dmc_header;
     320             :         struct intel_csr *csr = &dev_priv->csr;
     321             :         char stepping = intel_get_stepping(dev);
     322             :         char substepping = intel_get_substepping(dev);
     323             :         uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes;
     324             :         uint32_t i;
     325             :         uint32_t *dmc_payload;
     326             :         bool fw_loaded = false;
     327             : 
     328             :         if (!fw) {
     329             :                 i915_firmware_load_error_print(csr->fw_path, 0);
     330             :                 goto out;
     331             :         }
     332             : 
     333             :         if ((stepping == -ENODATA) || (substepping == -ENODATA)) {
     334             :                 DRM_ERROR("Unknown stepping info, firmware loading failed\n");
     335             :                 goto out;
     336             :         }
     337             : 
     338             :         /* Extract CSS Header information*/
     339             :         css_header = (struct intel_css_header *)fw->data;
     340             :         if (sizeof(struct intel_css_header) !=
     341             :                 (css_header->header_len * 4)) {
     342             :                 DRM_ERROR("Firmware has wrong CSS header length %u bytes\n",
     343             :                         (css_header->header_len * 4));
     344             :                 goto out;
     345             :         }
     346             :         readcount += sizeof(struct intel_css_header);
     347             : 
     348             :         /* Extract Package Header information*/
     349             :         package_header = (struct intel_package_header *)
     350             :                                         &fw->data[readcount];
     351             :         if (sizeof(struct intel_package_header) !=
     352             :                 (package_header->header_len * 4)) {
     353             :                 DRM_ERROR("Firmware has wrong package header length %u bytes\n",
     354             :                         (package_header->header_len * 4));
     355             :                 goto out;
     356             :         }
     357             :         readcount += sizeof(struct intel_package_header);
     358             : 
     359             :         /* Search for dmc_offset to find firware binary. */
     360             :         for (i = 0; i < package_header->num_entries; i++) {
     361             :                 if (package_header->fw_info[i].substepping == '*' &&
     362             :                         stepping == package_header->fw_info[i].stepping) {
     363             :                         dmc_offset = package_header->fw_info[i].offset;
     364             :                         break;
     365             :                 } else if (stepping == package_header->fw_info[i].stepping &&
     366             :                         substepping == package_header->fw_info[i].substepping) {
     367             :                         dmc_offset = package_header->fw_info[i].offset;
     368             :                         break;
     369             :                 } else if (package_header->fw_info[i].stepping == '*' &&
     370             :                         package_header->fw_info[i].substepping == '*')
     371             :                         dmc_offset = package_header->fw_info[i].offset;
     372             :         }
     373             :         if (dmc_offset == CSR_DEFAULT_FW_OFFSET) {
     374             :                 DRM_ERROR("Firmware not supported for %c stepping\n", stepping);
     375             :                 goto out;
     376             :         }
     377             :         readcount += dmc_offset;
     378             : 
     379             :         /* Extract dmc_header information. */
     380             :         dmc_header = (struct intel_dmc_header *)&fw->data[readcount];
     381             :         if (sizeof(struct intel_dmc_header) != (dmc_header->header_len)) {
     382             :                 DRM_ERROR("Firmware has wrong dmc header length %u bytes\n",
     383             :                                 (dmc_header->header_len));
     384             :                 goto out;
     385             :         }
     386             :         readcount += sizeof(struct intel_dmc_header);
     387             : 
     388             :         /* Cache the dmc header info. */
     389             :         if (dmc_header->mmio_count > ARRAY_SIZE(csr->mmioaddr)) {
     390             :                 DRM_ERROR("Firmware has wrong mmio count %u\n",
     391             :                                                 dmc_header->mmio_count);
     392             :                 goto out;
     393             :         }
     394             :         csr->mmio_count = dmc_header->mmio_count;
     395             :         for (i = 0; i < dmc_header->mmio_count; i++) {
     396             :                 if (dmc_header->mmioaddr[i] < CSR_MMIO_START_RANGE ||
     397             :                         dmc_header->mmioaddr[i] > CSR_MMIO_END_RANGE) {
     398             :                         DRM_ERROR(" Firmware has wrong mmio address 0x%x\n",
     399             :                                                 dmc_header->mmioaddr[i]);
     400             :                         goto out;
     401             :                 }
     402             :                 csr->mmioaddr[i] = dmc_header->mmioaddr[i];
     403             :                 csr->mmiodata[i] = dmc_header->mmiodata[i];
     404             :         }
     405             : 
     406             :         /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */
     407             :         nbytes = dmc_header->fw_size * 4;
     408             :         if (nbytes > CSR_MAX_FW_SIZE) {
     409             :                 DRM_ERROR("CSR firmware too big (%u) bytes\n", nbytes);
     410             :                 goto out;
     411             :         }
     412             :         csr->dmc_fw_size = dmc_header->fw_size;
     413             : 
     414             :         csr->dmc_payload = kmalloc(nbytes, GFP_KERNEL);
     415             :         if (!csr->dmc_payload) {
     416             :                 DRM_ERROR("Memory allocation failed for dmc payload\n");
     417             :                 goto out;
     418             :         }
     419             : 
     420             :         dmc_payload = csr->dmc_payload;
     421             :         memcpy(dmc_payload, &fw->data[readcount], nbytes);
     422             : 
     423             :         /* load csr program during system boot, as needed for DC states */
     424             :         intel_csr_load_program(dev);
     425             :         fw_loaded = true;
     426             : 
     427             :         DRM_DEBUG_KMS("Finished loading %s\n", dev_priv->csr.fw_path);
     428             : out:
     429             :         if (fw_loaded)
     430             :                 intel_runtime_pm_put(dev_priv);
     431             :         else
     432             :                 intel_csr_load_status_set(dev_priv, FW_FAILED);
     433             : 
     434             :         release_firmware(fw);
     435             : }
     436             : #endif
     437             : 
     438             : /**
     439             :  * intel_csr_ucode_init() - initialize the firmware loading.
     440             :  * @dev: drm device.
     441             :  *
     442             :  * This function is called at the time of loading the display driver to read
     443             :  * firmware from a .bin file and copied into a internal memory.
     444             :  */
     445           0 : void intel_csr_ucode_init(struct drm_device *dev)
     446             : {
     447           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
     448           0 :         struct intel_csr *csr = &dev_priv->csr;
     449             :         int ret;
     450             : 
     451           0 :         if (!HAS_CSR(dev))
     452           0 :                 return;
     453             : 
     454           0 :         if (IS_KABYLAKE(dev))
     455           0 :                 csr->fw_path = I915_CSR_KBL;
     456           0 :         else if (IS_SKYLAKE(dev))
     457           0 :                 csr->fw_path = I915_CSR_SKL;
     458           0 :         else if (IS_BROXTON(dev_priv))
     459           0 :                 csr->fw_path = I915_CSR_BXT;
     460             :         else {
     461           0 :                 DRM_ERROR("Unexpected: no known CSR firmware for platform\n");
     462           0 :                 intel_csr_load_status_set(dev_priv, FW_FAILED);
     463           0 :                 return;
     464             :         }
     465             : 
     466             :         DRM_DEBUG_KMS("Loading %s\n", csr->fw_path);
     467             : 
     468             :         /*
     469             :          * Obtain a runtime pm reference, until CSR is loaded,
     470             :          * to avoid entering runtime-suspend.
     471             :          */
     472           0 :         intel_runtime_pm_get(dev_priv);
     473             : 
     474             :         /* CSR supported for platform, load firmware */
     475             :         ret = request_firmware_nowait(THIS_MODULE, true, csr->fw_path,
     476             :                                 &dev_priv->dev->pdev->dev,
     477             :                                 GFP_KERNEL, dev_priv,
     478             :                                 finish_csr_load);
     479           0 :         if (ret) {
     480           0 :                 i915_firmware_load_error_print(csr->fw_path, ret);
     481           0 :                 intel_csr_load_status_set(dev_priv, FW_FAILED);
     482           0 :         }
     483           0 : }
     484             : 
     485             : /**
     486             :  * intel_csr_ucode_fini() - unload the CSR firmware.
     487             :  * @dev: drm device.
     488             :  *
     489             :  * Firmmware unloading includes freeing the internal momory and reset the
     490             :  * firmware loading status.
     491             :  */
     492           0 : void intel_csr_ucode_fini(struct drm_device *dev)
     493             : {
     494           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
     495             : 
     496           0 :         if (!HAS_CSR(dev))
     497           0 :                 return;
     498             : 
     499           0 :         intel_csr_load_status_set(dev_priv, FW_FAILED);
     500           0 :         kfree(dev_priv->csr.dmc_payload);
     501           0 : }
     502             : 
     503           0 : void assert_csr_loaded(struct drm_i915_private *dev_priv)
     504             : {
     505           0 :         WARN_ONCE(intel_csr_load_status_get(dev_priv) != FW_LOADED,
     506             :                   "CSR is not loaded.\n");
     507           0 :         WARN_ONCE(!I915_READ(CSR_PROGRAM(0)),
     508             :                   "CSR program storage start is NULL\n");
     509           0 :         WARN_ONCE(!I915_READ(CSR_SSP_BASE), "CSR SSP Base Not fine\n");
     510           0 :         WARN_ONCE(!I915_READ(CSR_HTP_SKL), "CSR HTP Not fine\n");
     511           0 : }

Generated by: LCOV version 1.13