drm/i915: Hook up pfit for DSI
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_csr.c
index 647d85e77c2f4700e84bc275efb711f9b2dc2363..d57b00ed5e5e9dfb724290142088d3ead8b7967b 100644 (file)
 #define I915_CSR_SKL "i915/skl_dmc_ver1.bin"
 #define I915_CSR_BXT "i915/bxt_dmc_ver1.bin"
 
+#define FIRMWARE_URL  "https://01.org/linuxgraphics/intel-linux-graphics-firmwares"
+
 MODULE_FIRMWARE(I915_CSR_SKL);
 MODULE_FIRMWARE(I915_CSR_BXT);
 
 #define SKL_CSR_VERSION_REQUIRED       CSR_VERSION(1, 23)
+#define BXT_CSR_VERSION_REQUIRED       CSR_VERSION(1, 7)
 
 #define CSR_MAX_FW_SIZE                        0x2FFF
 #define CSR_DEFAULT_FW_OFFSET          0xFFFFFFFF
@@ -177,7 +180,8 @@ static const struct stepping_info kbl_stepping_info[] = {
 static const struct stepping_info skl_stepping_info[] = {
        {'A', '0'}, {'B', '0'}, {'C', '0'},
        {'D', '0'}, {'E', '0'}, {'F', '0'},
-       {'G', '0'}, {'H', '0'}, {'I', '0'}
+       {'G', '0'}, {'H', '0'}, {'I', '0'},
+       {'J', '0'}, {'K', '0'}
 };
 
 static const struct stepping_info bxt_stepping_info[] = {
@@ -185,28 +189,49 @@ static const struct stepping_info bxt_stepping_info[] = {
        {'B', '0'}, {'B', '1'}, {'B', '2'}
 };
 
-static const struct stepping_info *intel_get_stepping_info(struct drm_device *dev)
+static const struct stepping_info no_stepping_info = { '*', '*' };
+
+static const struct stepping_info *
+intel_get_stepping_info(struct drm_i915_private *dev_priv)
 {
        const struct stepping_info *si;
        unsigned int size;
 
-       if (IS_KABYLAKE(dev)) {
+       if (IS_KABYLAKE(dev_priv)) {
                size = ARRAY_SIZE(kbl_stepping_info);
                si = kbl_stepping_info;
-       } else if (IS_SKYLAKE(dev)) {
+       } else if (IS_SKYLAKE(dev_priv)) {
                size = ARRAY_SIZE(skl_stepping_info);
                si = skl_stepping_info;
-       } else if (IS_BROXTON(dev)) {
+       } else if (IS_BROXTON(dev_priv)) {
                size = ARRAY_SIZE(bxt_stepping_info);
                si = bxt_stepping_info;
        } else {
-               return NULL;
+               size = 0;
        }
 
-       if (INTEL_REVID(dev) < size)
-               return si + INTEL_REVID(dev);
+       if (INTEL_REVID(dev_priv) < size)
+               return si + INTEL_REVID(dev_priv);
+
+       return &no_stepping_info;
+}
+
+static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv)
+{
+       uint32_t val, mask;
+
+       mask = DC_STATE_DEBUG_MASK_MEMORY_UP;
+
+       if (IS_BROXTON(dev_priv))
+               mask |= DC_STATE_DEBUG_MASK_CORES;
 
-       return NULL;
+       /* The below bit doesn't need to be cleared ever afterwards */
+       val = I915_READ(DC_STATE_DEBUG);
+       if ((val & mask) != mask) {
+               val |= mask;
+               I915_WRITE(DC_STATE_DEBUG, val);
+               POSTING_READ(DC_STATE_DEBUG);
+       }
 }
 
 /**
@@ -242,33 +267,26 @@ void intel_csr_load_program(struct drm_i915_private *dev_priv)
        }
 
        dev_priv->csr.dc_state = 0;
+
+       gen9_set_dc_state_debugmask(dev_priv);
 }
 
 static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
                              const struct firmware *fw)
 {
-       struct drm_device *dev = dev_priv->dev;
        struct intel_css_header *css_header;
        struct intel_package_header *package_header;
        struct intel_dmc_header *dmc_header;
        struct intel_csr *csr = &dev_priv->csr;
-       const struct stepping_info *stepping_info = intel_get_stepping_info(dev);
-       char stepping, substepping;
+       const struct stepping_info *si = intel_get_stepping_info(dev_priv);
        uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes;
        uint32_t i;
        uint32_t *dmc_payload;
+       uint32_t required_min_version;
 
        if (!fw)
                return NULL;
 
-       if (!stepping_info) {
-               DRM_ERROR("Unknown stepping info, firmware loading failed\n");
-               return NULL;
-       }
-
-       stepping = stepping_info->stepping;
-       substepping = stepping_info->substepping;
-
        /* Extract CSS Header information*/
        css_header = (struct intel_css_header *)fw->data;
        if (sizeof(struct intel_css_header) !=
@@ -280,14 +298,23 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
 
        csr->version = css_header->version;
 
-       if (IS_SKYLAKE(dev) && csr->version < SKL_CSR_VERSION_REQUIRED) {
-               DRM_INFO("Refusing to load old Skylake DMC firmware v%u.%u,"
+       if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+               required_min_version = SKL_CSR_VERSION_REQUIRED;
+       } else if (IS_BROXTON(dev_priv)) {
+               required_min_version = BXT_CSR_VERSION_REQUIRED;
+       } else {
+               MISSING_CASE(INTEL_REVID(dev_priv));
+               required_min_version = 0;
+       }
+
+       if (csr->version < required_min_version) {
+               DRM_INFO("Refusing to load old DMC firmware v%u.%u,"
                         " please upgrade to v%u.%u or later"
-                        " [https://01.org/linuxgraphics/intel-linux-graphics-firmwares].\n",
+                          " [" FIRMWARE_URL "].\n",
                         CSR_VERSION_MAJOR(csr->version),
                         CSR_VERSION_MINOR(csr->version),
-                        CSR_VERSION_MAJOR(SKL_CSR_VERSION_REQUIRED),
-                        CSR_VERSION_MINOR(SKL_CSR_VERSION_REQUIRED));
+                        CSR_VERSION_MAJOR(required_min_version),
+                        CSR_VERSION_MINOR(required_min_version));
                return NULL;
        }
 
@@ -307,11 +334,11 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
        /* Search for dmc_offset to find firware binary. */
        for (i = 0; i < package_header->num_entries; i++) {
                if (package_header->fw_info[i].substepping == '*' &&
-                   stepping == package_header->fw_info[i].stepping) {
+                   si->stepping == package_header->fw_info[i].stepping) {
                        dmc_offset = package_header->fw_info[i].offset;
                        break;
-               } else if (stepping == package_header->fw_info[i].stepping &&
-                       substepping == package_header->fw_info[i].substepping) {
+               } else if (si->stepping == package_header->fw_info[i].stepping &&
+                          si->substepping == package_header->fw_info[i].substepping) {
                        dmc_offset = package_header->fw_info[i].offset;
                        break;
                } else if (package_header->fw_info[i].stepping == '*' &&
@@ -319,7 +346,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
                        dmc_offset = package_header->fw_info[i].offset;
        }
        if (dmc_offset == CSR_DEFAULT_FW_OFFSET) {
-               DRM_ERROR("Firmware not supported for %c stepping\n", stepping);
+               DRM_ERROR("Firmware not supported for %c stepping\n",
+                         si->stepping);
                return NULL;
        }
        readcount += dmc_offset;
@@ -365,9 +393,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
                return NULL;
        }
 
-       memcpy(dmc_payload, &fw->data[readcount], nbytes);
-
-       return dmc_payload;
+       return memcpy(dmc_payload, &fw->data[readcount], nbytes);
 }
 
 static void csr_load_work_fn(struct work_struct *work)
@@ -382,18 +408,12 @@ static void csr_load_work_fn(struct work_struct *work)
 
        ret = request_firmware(&fw, dev_priv->csr.fw_path,
                               &dev_priv->dev->pdev->dev);
-       if (!fw)
-               goto out;
-
-       dev_priv->csr.dmc_payload = parse_csr_fw(dev_priv, fw);
-       if (!dev_priv->csr.dmc_payload)
-               goto out;
+       if (fw)
+               dev_priv->csr.dmc_payload = parse_csr_fw(dev_priv, fw);
 
-       /* load csr program during system boot, as needed for DC states */
-       intel_csr_load_program(dev_priv);
-
-out:
        if (dev_priv->csr.dmc_payload) {
+               intel_csr_load_program(dev_priv);
+
                intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
 
                DRM_INFO("Finished loading %s (v%u.%u)\n",
@@ -401,7 +421,10 @@ out:
                         CSR_VERSION_MAJOR(csr->version),
                         CSR_VERSION_MINOR(csr->version));
        } else {
-               DRM_ERROR("Failed to load DMC firmware, disabling rpm\n");
+               dev_notice(dev_priv->dev->dev,
+                          "Failed to load DMC firmware"
+                          " [" FIRMWARE_URL "],"
+                          " disabling runtime power management.\n");
        }
 
        release_firmware(fw);
@@ -423,7 +446,7 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
        if (!HAS_CSR(dev_priv))
                return;
 
-       if (IS_SKYLAKE(dev_priv))
+       if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
                csr->fw_path = I915_CSR_SKL;
        else if (IS_BROXTON(dev_priv))
                csr->fw_path = I915_CSR_BXT;
This page took 0.036699 seconds and 5 git commands to generate.