From 0b4a2a36d078b3a8de871025a958da547a6143f7 Mon Sep 17 00:00:00 2001 From: Satheeshakrishna M Date: Fri, 11 Jul 2014 14:51:13 +0530 Subject: drm/i915/bxt: Define BXT power domains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add BXT power domains v2: Use DOMAIN_PLLS instead of a new CDCLK one, whitespace fixes (Damien) v3: add VGA, TRANSCODER_A power domains (imre) Signed-off-by: Satheeshakrishna M (v1) Signed-off-by: Damien Lespiau Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index ce00e6994eeb..ff5cce32c7d6 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -319,6 +319,38 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, SKL_DISPLAY_MISC_IO_POWER_DOMAINS)) | \ BIT(POWER_DOMAIN_INIT)) +#define BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \ + BIT(POWER_DOMAIN_TRANSCODER_A) | \ + BIT(POWER_DOMAIN_PIPE_B) | \ + BIT(POWER_DOMAIN_TRANSCODER_B) | \ + BIT(POWER_DOMAIN_PIPE_C) | \ + BIT(POWER_DOMAIN_TRANSCODER_C) | \ + BIT(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \ + BIT(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \ + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ + BIT(POWER_DOMAIN_AUX_B) | \ + BIT(POWER_DOMAIN_AUX_C) | \ + BIT(POWER_DOMAIN_AUDIO) | \ + BIT(POWER_DOMAIN_VGA) | \ + BIT(POWER_DOMAIN_INIT)) +#define BXT_DISPLAY_POWERWELL_1_POWER_DOMAINS ( \ + BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \ + BIT(POWER_DOMAIN_PIPE_A) | \ + BIT(POWER_DOMAIN_TRANSCODER_EDP) | \ + BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \ + BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) | \ + BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) | \ + BIT(POWER_DOMAIN_AUX_A) | \ + BIT(POWER_DOMAIN_PLLS) | \ + BIT(POWER_DOMAIN_INIT)) +#define BXT_DISPLAY_ALWAYS_ON_POWER_DOMAINS ( \ + (POWER_DOMAIN_MASK & ~(BXT_DISPLAY_POWERWELL_1_POWER_DOMAINS | \ + BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS)) | \ + BIT(POWER_DOMAIN_INIT)) + static void skl_set_power_well(struct drm_i915_private *dev_priv, struct i915_power_well *power_well, bool enable) { @@ -1313,6 +1345,27 @@ static struct i915_power_well skl_power_wells[] = { }, }; +static struct i915_power_well bxt_power_wells[] = { + { + .name = "always-on", + .always_on = 1, + .domains = BXT_DISPLAY_ALWAYS_ON_POWER_DOMAINS, + .ops = &i9xx_always_on_power_well_ops, + }, + { + .name = "power well 1", + .domains = BXT_DISPLAY_POWERWELL_1_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .data = SKL_DISP_PW_1, + }, + { + .name = "power well 2", + .domains = BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS, + .ops = &skl_power_well_ops, + .data = SKL_DISP_PW_2, + } +}; + #define set_power_wells(power_domains, __power_wells) ({ \ (power_domains)->power_wells = (__power_wells); \ (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \ @@ -1341,6 +1394,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) set_power_wells(power_domains, bdw_power_wells); } else if (IS_SKYLAKE(dev_priv->dev)) { set_power_wells(power_domains, skl_power_wells); + } else if (IS_BROXTON(dev_priv->dev)) { + set_power_wells(power_domains, bxt_power_wells); } else if (IS_CHERRYVIEW(dev_priv->dev)) { set_power_wells(power_domains, chv_power_wells); } else if (IS_VALLEYVIEW(dev_priv->dev)) { -- cgit v1.2.3-59-g8ed1b From 664326f8a5b7e4ab7ed469acaadc63d2a05d8720 Mon Sep 17 00:00:00 2001 From: "A.Sunil Kamath" Date: Mon, 24 Nov 2014 13:37:44 +0530 Subject: drm/i915/bxt: Implement enable/disable for Display C9 state v2: Modified as per review comments from Imre - Mention enabling instead of allowing in the debug trace and remove unnecessary comments. v3: - Rebase to latest. - Move DC9-related functions from intel_display.c to intel_runtime_pm.c. v4: (imre) - remove DC5 disabling, it's a nop at this point - squashed in Suketu's "Assert the requirements to enter or exit DC9" patch - remove check for RUNTIME_PM from assert_can_enable_dc9, it's not a dependency Signed-off-by: A.Sunil Kamath (v3) Signed-off-by: Imre Deak Reviewed-by: Sagar Kamble Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 5 +++ drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_runtime_pm.c | 66 +++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 11b9a0898111..29c41f1bba34 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7059,6 +7059,11 @@ enum skl_disp_power_wells { #define BXT_DE_PLL_PLL_ENABLE (1 << 31) #define BXT_DE_PLL_LOCK (1 << 30) +/* GEN9 DC */ +#define DC_STATE_EN 0x45504 +#define DC_STATE_EN_UPTO_DC5 (1<<0) +#define DC_STATE_EN_DC9 (1<<3) + /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register, * since on HSW we can't write to it using I915_WRITE. */ #define D_COMP_HSW (MCHBAR_MIRROR_BASE_SNB + 0x5F0C) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1ae0c3a1ad0b..1cad3ddaf3c7 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1117,6 +1117,8 @@ void broxton_uninit_cdclk(struct drm_device *dev); void broxton_set_cdclk(struct drm_device *dev, int frequency); void broxton_ddi_phy_init(struct drm_device *dev); void broxton_ddi_phy_uninit(struct drm_device *dev); +void bxt_enable_dc9(struct drm_i915_private *dev_priv); +void bxt_disable_dc9(struct drm_i915_private *dev_priv); void intel_dp_get_m_n(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index ff5cce32c7d6..8fe2fdeab652 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -351,6 +351,72 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS)) | \ BIT(POWER_DOMAIN_INIT)) +static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + WARN(!IS_BROXTON(dev), "Platform doesn't support DC9.\n"); + WARN((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9), + "DC9 already programmed to be enabled.\n"); + WARN(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5, + "DC5 still not disabled to enable DC9.\n"); + WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on.\n"); + WARN(intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n"); + + /* + * TODO: check for the following to verify the conditions to enter DC9 + * state are satisfied: + * 1] Check relevant display engine registers to verify if mode set + * disable sequence was followed. + * 2] Check if display uninitialize sequence is initialized. + */ +} + +static void assert_can_disable_dc9(struct drm_i915_private *dev_priv) +{ + WARN(intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n"); + WARN(!(I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9), + "DC9 already programmed to be disabled.\n"); + WARN(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5, + "DC5 still not disabled.\n"); + + /* + * TODO: check for the following to verify DC9 state was indeed + * entered before programming to disable it: + * 1] Check relevant display engine registers to verify if mode + * set disable sequence was followed. + * 2] Check if display uninitialize sequence is initialized. + */ +} + +void bxt_enable_dc9(struct drm_i915_private *dev_priv) +{ + uint32_t val; + + assert_can_enable_dc9(dev_priv); + + DRM_DEBUG_KMS("Enabling DC9\n"); + + val = I915_READ(DC_STATE_EN); + val |= DC_STATE_EN_DC9; + I915_WRITE(DC_STATE_EN, val); + POSTING_READ(DC_STATE_EN); +} + +void bxt_disable_dc9(struct drm_i915_private *dev_priv) +{ + uint32_t val; + + assert_can_disable_dc9(dev_priv); + + DRM_DEBUG_KMS("Disabling DC9\n"); + + val = I915_READ(DC_STATE_EN); + val &= ~DC_STATE_EN_DC9; + I915_WRITE(DC_STATE_EN, val); + POSTING_READ(DC_STATE_EN); +} + static void skl_set_power_well(struct drm_i915_private *dev_priv, struct i915_power_well *power_well, bool enable) { -- cgit v1.2.3-59-g8ed1b From dc17430054056049e8b279ffe3f18d0ff13ae3e2 Mon Sep 17 00:00:00 2001 From: Suketu Shah Date: Fri, 17 Apr 2015 19:46:16 +0530 Subject: drm/i915/skl: Add DC5 Trigger Sequence Add triggers as per expectations mentioned in gen9_enable_dc5 and gen9_disable_dc5 patch. Also call POSTING_READ for every write to a register to ensure that its written immediately. v1: Remove POSTING_READ calls as they've already been added in previous patches. v2: Rebase to move all runtime pm specific changes to intel_runtime_pm.c file. Modified as per review comments from Imre: 1] Change variable name 'dc5_allowed' to 'dc5_enabled' to correspond to relevant functions. 2] Move the check dc5_enabled in skl_set_power_well() to disable DC5 into gen9_disable_DC5 which is a more appropriate place. 3] Convert checks for 'pm.dc5_enabled' and 'pm.suspended' in skl_set_power_well() to warnings. However, removing them for now as they'll be included in a future patch asserting DC-state entry/exit criteria. 4] Enable DC5, only when CSR firmware is verified to be loaded. Create new structure to track 'enabled' and 'deferred' status of DC5. 5] Ensure runtime PM reference is obtained, if CSR is not loaded, to avoid entering runtime-suspend and release it when it's loaded. 6] Protect necessary CSR-related code with locks. 7] Move CSR-loading call to runtime PM initialization, as power domains needed to be accessed during deferred DC5-enabling, are not initialized earlier. v3: Rebase to latest. Modified as per review comments from Imre: 1] Use blocking wait for CSR-loading to finish to enable DC5 for simplicity, instead of deferring enabling DC5 until CSR is loaded. 2] Obtain runtime PM reference during CSR-loading initialization itself as deferred DC5- enabling is removed and release it at the end of CSR-loading functionality. 3] Revert calling CSR-loading functionality to the beginning of i915 driver-load functionality to avoid any delay in loading. 4] Define another variable to track whether CSR-loading failed and use it to avoid enabling DC5 if it's true. 5] Define CSR-load-status accessor functions for use later. v4: 1] Disable DC5 before enabling PG2 instead of after it. 2] DC5 was being mistaken enabled even when CSR-loading timed-out. Fix that. 3] Enable DC5-related functionality using a macro. 4] Remove dc5_enabled tracking variable and its use as it's not needed now. v5: 1] Mark CSR failed to load where necessary in finish_csr_load function. 2] Use mutex-protected accessor function to check if CSR loaded instead of directly accessing the variable. 3] Prefix csr_load_status_get/set function names with intel_. v6: rebase to latest. v7: Rebase on top of nightly (Damien) v8: Squashed the patch from Imre - added csr helper pointers to simplify the code. (Imre) v9: After adding dmc ver 1.0 support rebased on top of nightly. (Animesh) v10: Added a enum for different csr states, suggested by Imre. (Animesh) v11: Based on review comments from Imre, Damien and Daniel following changes done - enum name chnaged to csr_state (singular form). - FW_UNINITIALIZED used as zeroth element in enum csr_state. - Prototype changed for helper function(set/get csr status), using enum csr_state instead of bool. v12: Based on review comment from Imre, introduced bool fw_loaded local to finish_csr_load() which helps calling once to set the csr status. The same flag used to fail RPM if find any issue during firmware loading. Issue: VIZ-2819 Signed-off-by: A.Sunil Kamath Signed-off-by: Suketu Shah Signed-off-by: Damien Lespiau Signed-off-by: Imre Deak Signed-off-by: Animesh Manna Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 7 ++++++ drivers/gpu/drm/i915/intel_csr.c | 42 +++++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_drv.h | 3 +++ drivers/gpu/drm/i915/intel_runtime_pm.c | 33 ++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index df46e2735991..a49986f8b7f0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -669,6 +669,12 @@ struct intel_uncore { #define for_each_fw_domain(domain__, dev_priv__, i__) \ for_each_fw_domain_mask(domain__, FORCEWAKE_ALL, dev_priv__, i__) +enum csr_state { + FW_UNINITIALIZED = 0, + FW_LOADED, + FW_FAILED +}; + struct intel_csr { const char *fw_path; __be32 *dmc_payload; @@ -676,6 +682,7 @@ struct intel_csr { uint32_t mmio_count; uint32_t mmioaddr[8]; uint32_t mmiodata[8]; + enum csr_state state; }; #define DEV_INFO_FOR_EACH_FLAG(func, sep) \ diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index b3d6fbefa5c6..0cae0cd90c21 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -183,6 +183,25 @@ static char intel_get_substepping(struct drm_device *dev) return -ENODATA; } +enum csr_state intel_csr_load_status_get(struct drm_i915_private *dev_priv) +{ + enum csr_state state; + + mutex_lock(&dev_priv->csr_lock); + state = dev_priv->csr.state; + mutex_unlock(&dev_priv->csr_lock); + + return state; +} + +void intel_csr_load_status_set(struct drm_i915_private *dev_priv, + enum csr_state state) +{ + mutex_lock(&dev_priv->csr_lock); + dev_priv->csr.state = state; + mutex_unlock(&dev_priv->csr_lock); +} + void intel_csr_load_program(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -204,6 +223,8 @@ void intel_csr_load_program(struct drm_device *dev) I915_WRITE(dev_priv->csr.mmioaddr[i], dev_priv->csr.mmiodata[i]); } + + dev_priv->csr.state = FW_LOADED; mutex_unlock(&dev_priv->csr_lock); } @@ -220,6 +241,7 @@ static void finish_csr_load(const struct firmware *fw, void *context) uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; uint32_t i; __be32 *dmc_payload; + bool fw_loaded = false; if (!fw) { i915_firmware_load_error_print(csr->fw_path, 0); @@ -326,7 +348,14 @@ static void finish_csr_load(const struct firmware *fw, void *context) /* load csr program during system boot, as needed for DC states */ intel_csr_load_program(dev); + fw_loaded = true; + out: + if (fw_loaded) + intel_runtime_pm_put(dev_priv); + else + intel_csr_load_status_set(dev_priv, FW_FAILED); + release_firmware(fw); } @@ -343,17 +372,25 @@ void intel_csr_ucode_init(struct drm_device *dev) csr->fw_path = I915_CSR_SKL; else { DRM_ERROR("Unexpected: no known CSR firmware for platform\n"); + intel_csr_load_status_set(dev_priv, FW_FAILED); return; } + /* + * Obtain a runtime pm reference, until CSR is loaded, + * to avoid entering runtime-suspend. + */ + intel_runtime_pm_get(dev_priv); + /* CSR supported for platform, load firmware */ ret = request_firmware_nowait(THIS_MODULE, true, csr->fw_path, &dev_priv->dev->pdev->dev, GFP_KERNEL, dev_priv, finish_csr_load); - if (ret) + if (ret) { i915_firmware_load_error_print(csr->fw_path, ret); - + intel_csr_load_status_set(dev_priv, FW_FAILED); + } } void intel_csr_ucode_fini(struct drm_device *dev) @@ -363,5 +400,6 @@ void intel_csr_ucode_fini(struct drm_device *dev) if (!HAS_CSR(dev)) return; + intel_csr_load_status_set(dev_priv, FW_FAILED); kfree(dev_priv->csr.dmc_payload); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8bdb29e3ecb2..980b3aff9bf4 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1155,6 +1155,9 @@ u32 skl_plane_ctl_rotation(unsigned int rotation); /* intel_csr.c */ void intel_csr_ucode_init(struct drm_device *dev); +enum csr_state intel_csr_load_status_get(struct drm_i915_private *dev_priv); +void intel_csr_load_status_set(struct drm_i915_private *dev_priv, + enum csr_state state); void intel_csr_load_program(struct drm_device *dev); void intel_csr_ucode_fini(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 8fe2fdeab652..ffbf9779c26d 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -49,6 +49,8 @@ * present for a given platform. */ +#define GEN9_ENABLE_DC5(dev) (IS_SKYLAKE(dev)) + #define for_each_power_well(i, power_well, domain_mask, power_domains) \ for (i = 0; \ i < (power_domains)->power_well_count && \ @@ -417,9 +419,20 @@ void bxt_disable_dc9(struct drm_i915_private *dev_priv) POSTING_READ(DC_STATE_EN); } +static void gen9_enable_dc5(struct drm_i915_private *dev_priv) +{ + /* TODO: Implementation to be done. */ +} + +static void gen9_disable_dc5(struct drm_i915_private *dev_priv) +{ + /* TODO: Implementation to be done. */ +} + static void skl_set_power_well(struct drm_i915_private *dev_priv, struct i915_power_well *power_well, bool enable) { + struct drm_device *dev = dev_priv->dev; uint32_t tmp, fuse_status; uint32_t req_mask, state_mask; bool is_enabled, enable_requested, check_fuse_status = false; @@ -459,6 +472,13 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, if (enable) { if (!enable_requested) { + WARN((tmp & state_mask) && + !I915_READ(HSW_PWR_WELL_BIOS), + "Invalid for power well status to be enabled, unless done by the BIOS, \ + when request is to disable!\n"); + if (GEN9_ENABLE_DC5(dev) && + power_well->data == SKL_DISP_PW_2) + gen9_disable_dc5(dev_priv); I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask); } @@ -475,6 +495,19 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, I915_WRITE(HSW_PWR_WELL_DRIVER, tmp & ~req_mask); POSTING_READ(HSW_PWR_WELL_DRIVER); DRM_DEBUG_KMS("Disabling %s\n", power_well->name); + + if (GEN9_ENABLE_DC5(dev) && + power_well->data == SKL_DISP_PW_2) { + enum csr_state state; + + wait_for((state = intel_csr_load_status_get(dev_priv)) != + FW_UNINITIALIZED, 1000); + if (state != FW_LOADED) + DRM_ERROR("CSR firmware not ready (%d)\n", + state); + else + gen9_enable_dc5(dev_priv); + } } } -- cgit v1.2.3-59-g8ed1b From 6b457d31ea0465fcadcf6d5044f5f71398954727 Mon Sep 17 00:00:00 2001 From: "A.Sunil Kamath" Date: Thu, 16 Apr 2015 14:22:09 +0530 Subject: drm/i915/skl: Implement enable/disable for Display C5 state. This patch just implements the basic enable and disable functions of DC5 state which is needed for both SKL and BXT. Its important to load respective CSR program before calling enable, which anyways will happen as CSR program is executed during boot. DC5 is a power saving state where hardware dynamically disables power well 1 and the CDCLK PLL and saves the associated registers. DC5 can be entered when software allows it, power well 2 is disabled, and hardware detects that all pipes are disabled or pipe A is enabled with PSR active. Its better to configure display engine to have power well 2 disabled before getting into DC5 enable function. Hence rpm framework will have to ensure to check status of power well 2 before calling gen9_enable_dc5. Rather dc5 entry criteria should be decided based on power well 2 status. If disabled, then call gen9_enable_dc5. v2: Replace HAS_ with IS_ check as per Daniel's review comments v3: Cleared the bits dc5/dc6 enable of DC_STATE_EN register before setting them as per Satheesh's review comments. v4: call POSTING_READ for every write to a register to ensure that its written immediately. v5: Modified as per review comments from Imre. - Squashed register definitions into this patch. - Finetuned comments and functions. v6: Avoid redundant writes in gen9_set_dc_state_debugmask_memory_up function. v7: - Rebase to latest. - Move all runtime PM functions defined in intel_display.c to intel_runtime_pm.c. v8: Rebased to drm-intel-nightly. (Animesh) Issue: VIZ-2819 Signed-off-by: A.Sunil Kamath Signed-off-by: Damien Lespiau Signed-off-by: Animesh Manna Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 11 +++++++++ drivers/gpu/drm/i915/intel_runtime_pm.c | 41 +++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e35d7f29d7c2..1b31238fa531 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7204,6 +7204,17 @@ enum skl_disp_power_wells { #define DC_STATE_EN_UPTO_DC5 (1<<0) #define DC_STATE_EN_DC9 (1<<3) +/* +* SKL DC +*/ +#define DC_STATE_EN 0x45504 +#define DC_STATE_EN_UPTO_DC5 (1<<0) +#define DC_STATE_EN_UPTO_DC6 (2<<0) +#define DC_STATE_EN_UPTO_DC5_DC6_MASK 0x3 + +#define DC_STATE_DEBUG 0x45520 +#define DC_STATE_DEBUG_MASK_MEMORY_UP (1<<1) + /* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register, * since on HSW we can't write to it using I915_WRITE. */ #define D_COMP_HSW (MCHBAR_MIRROR_BASE_SNB + 0x5F0C) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index ffbf9779c26d..839010a57a2b 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -419,14 +419,51 @@ void bxt_disable_dc9(struct drm_i915_private *dev_priv) POSTING_READ(DC_STATE_EN); } +static void gen9_set_dc_state_debugmask_memory_up( + struct drm_i915_private *dev_priv) +{ + uint32_t val; + + /* The below bit doesn't need to be cleared ever afterwards */ + val = I915_READ(DC_STATE_DEBUG); + if (!(val & DC_STATE_DEBUG_MASK_MEMORY_UP)) { + val |= DC_STATE_DEBUG_MASK_MEMORY_UP; + I915_WRITE(DC_STATE_DEBUG, val); + POSTING_READ(DC_STATE_DEBUG); + } +} + static void gen9_enable_dc5(struct drm_i915_private *dev_priv) { - /* TODO: Implementation to be done. */ + struct drm_device *dev = dev_priv->dev; + uint32_t val; + + WARN_ON(!IS_GEN9(dev)); + + DRM_DEBUG_KMS("Enabling DC5\n"); + + gen9_set_dc_state_debugmask_memory_up(dev_priv); + + val = I915_READ(DC_STATE_EN); + val &= ~DC_STATE_EN_UPTO_DC5_DC6_MASK; + val |= DC_STATE_EN_UPTO_DC5; + I915_WRITE(DC_STATE_EN, val); + POSTING_READ(DC_STATE_EN); } static void gen9_disable_dc5(struct drm_i915_private *dev_priv) { - /* TODO: Implementation to be done. */ + struct drm_device *dev = dev_priv->dev; + uint32_t val; + + WARN_ON(!IS_GEN9(dev)); + + DRM_DEBUG_KMS("Disabling DC5\n"); + + val = I915_READ(DC_STATE_EN); + val &= ~DC_STATE_EN_UPTO_DC5; + I915_WRITE(DC_STATE_EN, val); + POSTING_READ(DC_STATE_EN); } static void skl_set_power_well(struct drm_i915_private *dev_priv, -- cgit v1.2.3-59-g8ed1b From 5aefb2398afad6998d51f90294e02b37b3f19a40 Mon Sep 17 00:00:00 2001 From: Suketu Shah Date: Thu, 16 Apr 2015 14:22:10 +0530 Subject: drm/i915/skl: Assert the requirements to enter or exit DC5. Warn if the conditions to enter or exit DC5 are not satisfied such as support for runtime PM, state of power well, CSR loading etc. v2: Removed camelcase in functions and variables. v3: Do some minimal check to assert if CSR program is not loaded. v4: 1] Used an appropriate function lookup_power_well() to identify power well, instead of using a magic number which can change in future. 2] Split the conditions further in assert_can_enable_DC5() and added more checks. 3] Removed all WARNs from assert_can_disable_DC5 as they were unnecessary and added two new ones. 4] Changed variable names as updated in earlier patches. v5: 1] Change lookup_power_well function to take an int power well id. 2] Define a new intel_display_power_well_is_enabled helper function to check whether a particular power well is enabled. 3] Use CSR-related mutex in assert_csr_loaded function. v6: Remove use of dc5_enabled variable as it's no longer needed. v7: 1] Rebase to latest. 2] Move all DC5-related functions from intel_display.c to intel_runtime_pm.c. v8: After adding dmc ver 1.0 support rebased on top of nightly. (Animesh) v9: Modified below changes based on review comments from Imre. - Moved intel_display_power_well_is_enabled() to intel_runtime_pm.c. - Removed mutex lock from assert_csr_loaded(). (Animesh) Issue: VIZ-2819 Signed-off-by: A.Sunil Kamath Signed-off-by: Suketu Shah Signed-off-by: Damien Lespiau Signed-off-by: Animesh Manna Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_csr.c | 9 ++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_runtime_pm.c | 51 +++++++++++++++++++++++++++++---- 3 files changed, 56 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 0cae0cd90c21..9311cddb86e6 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -403,3 +403,12 @@ void intel_csr_ucode_fini(struct drm_device *dev) intel_csr_load_status_set(dev_priv, FW_FAILED); kfree(dev_priv->csr.dmc_payload); } + +void assert_csr_loaded(struct drm_i915_private *dev_priv) +{ + WARN((intel_csr_load_status_get(dev_priv) != FW_LOADED), "CSR is not loaded.\n"); + WARN(!I915_READ(CSR_PROGRAM_BASE), + "CSR program storage start is NULL\n"); + WARN(!I915_READ(CSR_SSP_BASE), "CSR SSP Base Not fine\n"); + WARN(!I915_READ(CSR_HTP_SKL), "CSR HTP Not fine\n"); +} diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 980b3aff9bf4..ddf3fefd96b2 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1160,6 +1160,7 @@ void intel_csr_load_status_set(struct drm_i915_private *dev_priv, enum csr_state state); void intel_csr_load_program(struct drm_device *dev); void intel_csr_ucode_fini(struct drm_device *dev); +void assert_csr_loaded(struct drm_i915_private *dev_priv); /* intel_dp.c */ void intel_dp_init(struct drm_device *dev, int output_reg, enum port port); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 839010a57a2b..2f7f0ab363fb 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -64,6 +64,9 @@ i--) \ if ((power_well)->domains & (domain_mask)) +bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, + int power_well_id); + /* * We should only use the power well if we explicitly asked the hardware to * enable it, so check if it's enabled and also check if we've requested it to @@ -433,12 +436,39 @@ static void gen9_set_dc_state_debugmask_memory_up( } } -static void gen9_enable_dc5(struct drm_i915_private *dev_priv) +static void assert_can_enable_dc5(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; + bool pg2_enabled = intel_display_power_well_is_enabled(dev_priv, + SKL_DISP_PW_2); + + WARN(!IS_SKYLAKE(dev), "Platform doesn't support DC5.\n"); + WARN(!HAS_RUNTIME_PM(dev), "Runtime PM not enabled.\n"); + WARN(pg2_enabled, "PG2 not disabled to enable DC5.\n"); + + WARN((I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5), + "DC5 already programmed to be enabled.\n"); + WARN(dev_priv->pm.suspended, + "DC5 cannot be enabled, if platform is runtime-suspended.\n"); + + assert_csr_loaded(dev_priv); +} + +static void assert_can_disable_dc5(struct drm_i915_private *dev_priv) +{ + bool pg2_enabled = intel_display_power_well_is_enabled(dev_priv, + SKL_DISP_PW_2); + + WARN(!pg2_enabled, "PG2 not enabled to disable DC5.\n"); + WARN(dev_priv->pm.suspended, + "Disabling of DC5 while platform is runtime-suspended should never happen.\n"); +} + +static void gen9_enable_dc5(struct drm_i915_private *dev_priv) +{ uint32_t val; - WARN_ON(!IS_GEN9(dev)); + assert_can_enable_dc5(dev_priv); DRM_DEBUG_KMS("Enabling DC5\n"); @@ -453,10 +483,9 @@ static void gen9_enable_dc5(struct drm_i915_private *dev_priv) static void gen9_disable_dc5(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; uint32_t val; - WARN_ON(!IS_GEN9(dev)); + assert_can_disable_dc5(dev_priv); DRM_DEBUG_KMS("Disabling DC5\n"); @@ -1416,7 +1445,7 @@ static struct i915_power_well chv_power_wells[] = { }; static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv, - enum punit_power_well power_well_id) + int power_well_id) { struct i915_power_domains *power_domains = &dev_priv->power_domains; struct i915_power_well *power_well; @@ -1430,6 +1459,18 @@ static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_pr return NULL; } +bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, + int power_well_id) +{ + struct i915_power_well *power_well; + bool ret; + + power_well = lookup_power_well(dev_priv, power_well_id); + ret = power_well->ops->is_enabled(dev_priv, power_well); + + return ret; +} + static struct i915_power_well skl_power_wells[] = { { .name = "always-on", -- cgit v1.2.3-59-g8ed1b From f75a1985137f272dff1a361b763a76fb8f68c3b9 Mon Sep 17 00:00:00 2001 From: Suketu Shah Date: Thu, 16 Apr 2015 14:22:11 +0530 Subject: drm/i915/skl: Add DC6 Trigger sequence. Add triggers for DC6 as per details provided in skl_enable_dc6 and skl_disable_dc6 implementations. Also Call POSTING_READ for every write to a register to ensure it is written to immediately v1: Remove POSTING_READ and intel_prepare_ddi calls as they've been added in previous patches. v2: 1] Remove check for backlight disabled as it should be the case by that time. 2] Mark DC5 as disabled when enabling DC6. 3] Return from DC5-disabling function early if DC5 is already be disabled which can happen due to DC6-enabling earlier. 3] Ensure CSR firmware is loaded after resume from DC6 as corresponding memory contents won't be retained after runtime-suspend. 4] Ensure that CSR isn't identified as loaded before CSR-loading program is called during runtime-resume. v3: Rebase to latest Modified as per review comments from Imre and after discussion with Art: 1] DC6 should be preferably enabled when PG2 is disabled by SW as the check for PG1 being disabled is taken of by HW to enter DC6, and disabled when PG2 is enabled respectively. This helps save more power, especially in the case when display is disabled but GT is enabled. Accordingly, replacing DC5 trigger sequence with DC6 for SKL. 2] DC6 could be enabled from intel_runtime_suspend() function, if DC5 is already enabled. 3] Move CSR-load-status setting code from intel_runtime_suspend function to a new function. v4: 1] Enable/disable DC6 only when toggling the power-well using a newly defined macro ENABLE_DC6. v5: 1] Load CSR on system resume too as firmware may be lost on system suspend preventing enabling DC5, DC6. 2] DDI buffers shouldn't be programmed during driver-load/resume as it's already done during modeset initialization then and also that the encoder list is still uninitialized by then. Therefore, call intel_prepare_ddi function right after disabling DC6 but outside skl_disable_dc6 function and not during driver-load/resume. v6: 1] Rebase to latest. 2] Move SKL_ENABLE_DC6 macro definition from intel_display.c to intel_runtime_pm.c. v7: 1) Refactored the code for removing the warning got from checkpatch. 2) After adding dmc ver 1.0 support rebased on top of nightly. (Animesh) v8: - Reverted the changes done in v7. - Removed the condition check in skl_prepare_resune(). (Animesh) Issue: VIZ-2819 Signed-off-by: A.Sunil Kamath Signed-off-by: Suketu Shah Signed-off-by: Damien Lespiau Signed-off-by: Animesh Manna Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 30 +++++++++++++++++++++++ drivers/gpu/drm/i915/intel_runtime_pm.c | 43 +++++++++++++++++++++++++++------ 2 files changed, 66 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b743bb17e288..334bcc1badaa 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -594,6 +594,8 @@ static void intel_suspend_encoders(struct drm_i915_private *dev_priv) static int intel_suspend_complete(struct drm_i915_private *dev_priv); static int vlv_resume_prepare(struct drm_i915_private *dev_priv, bool rpm_resume); +static int skl_resume_prepare(struct drm_i915_private *dev_priv); + static int i915_drm_suspend(struct drm_device *dev) { @@ -808,6 +810,8 @@ static int i915_drm_resume_early(struct drm_device *dev) if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) hsw_disable_pc8(dev_priv); + else if (IS_SKYLAKE(dev_priv)) + ret = skl_resume_prepare(dev_priv); intel_uncore_sanitize(dev); intel_power_domains_init_hw(dev_priv); @@ -1022,6 +1026,19 @@ static int i915_pm_resume(struct device *dev) return i915_drm_resume(drm_dev); } +static int skl_suspend_complete(struct drm_i915_private *dev_priv) +{ + /* Enabling DC6 is not a hard requirement to enter runtime D3 */ + + /* + * This is to ensure that CSR isn't identified as loaded before + * CSR-loading program is called during runtime-resume. + */ + intel_csr_load_status_set(dev_priv, FW_UNINITIALIZED); + + return 0; +} + static int hsw_suspend_complete(struct drm_i915_private *dev_priv) { hsw_enable_pc8(dev_priv); @@ -1061,6 +1078,15 @@ static int bxt_resume_prepare(struct drm_i915_private *dev_priv) return 0; } +static int skl_resume_prepare(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + intel_csr_load_program(dev); + + return 0; +} + /* * Save all Gunit registers that may be lost after a D3 and a subsequent * S0i[R123] transition. The list of registers needing a save/restore is @@ -1536,6 +1562,8 @@ static int intel_runtime_resume(struct device *device) if (IS_BROXTON(dev)) ret = bxt_resume_prepare(dev_priv); + else if (IS_SKYLAKE(dev)) + ret = skl_resume_prepare(dev_priv); else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) hsw_disable_pc8(dev_priv); else if (IS_VALLEYVIEW(dev_priv)) @@ -1570,6 +1598,8 @@ static int intel_suspend_complete(struct drm_i915_private *dev_priv) if (IS_BROXTON(dev)) ret = bxt_suspend_complete(dev_priv); + else if (IS_SKYLAKE(dev)) + ret = skl_suspend_complete(dev_priv); else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) ret = hsw_suspend_complete(dev_priv); else if (IS_VALLEYVIEW(dev)) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 2f7f0ab363fb..5bd7f083aa34 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -49,7 +49,8 @@ * present for a given platform. */ -#define GEN9_ENABLE_DC5(dev) (IS_SKYLAKE(dev)) +#define GEN9_ENABLE_DC5(dev) 0 +#define SKL_ENABLE_DC6(dev) IS_SKYLAKE(dev) #define for_each_power_well(i, power_well, domain_mask, power_domains) \ for (i = 0; \ @@ -495,6 +496,16 @@ static void gen9_disable_dc5(struct drm_i915_private *dev_priv) POSTING_READ(DC_STATE_EN); } +static void skl_enable_dc6(struct drm_i915_private *dev_priv) +{ + /* TODO: Implementation to be done. */ +} + +static void skl_disable_dc6(struct drm_i915_private *dev_priv) +{ + /* TODO: Implementation to be done. */ +} + static void skl_set_power_well(struct drm_i915_private *dev_priv, struct i915_power_well *power_well, bool enable) { @@ -542,9 +553,21 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, !I915_READ(HSW_PWR_WELL_BIOS), "Invalid for power well status to be enabled, unless done by the BIOS, \ when request is to disable!\n"); - if (GEN9_ENABLE_DC5(dev) && - power_well->data == SKL_DISP_PW_2) - gen9_disable_dc5(dev_priv); + if ((GEN9_ENABLE_DC5(dev) || SKL_ENABLE_DC6(dev)) && + power_well->data == SKL_DISP_PW_2) { + if (SKL_ENABLE_DC6(dev)) { + skl_disable_dc6(dev_priv); + /* + * DDI buffer programming unnecessary during driver-load/resume + * as it's already done during modeset initialization then. + * It's also invalid here as encoder list is still uninitialized. + */ + if (!dev_priv->power_domains.initializing) + intel_prepare_ddi(dev); + } else { + gen9_disable_dc5(dev_priv); + } + } I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask); } @@ -562,17 +585,23 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, POSTING_READ(HSW_PWR_WELL_DRIVER); DRM_DEBUG_KMS("Disabling %s\n", power_well->name); - if (GEN9_ENABLE_DC5(dev) && + if ((GEN9_ENABLE_DC5(dev) || SKL_ENABLE_DC6(dev)) && power_well->data == SKL_DISP_PW_2) { enum csr_state state; - + /* TODO: wait for a completion event or + * similar here instead of busy + * waiting using wait_for function. + */ wait_for((state = intel_csr_load_status_get(dev_priv)) != FW_UNINITIALIZED, 1000); if (state != FW_LOADED) DRM_ERROR("CSR firmware not ready (%d)\n", state); else - gen9_enable_dc5(dev_priv); + if (SKL_ENABLE_DC6(dev)) + skl_enable_dc6(dev_priv); + else + gen9_enable_dc5(dev_priv); } } } -- cgit v1.2.3-59-g8ed1b From 74b4f371f56fc7ca4058041080b30d5b0a7271af Mon Sep 17 00:00:00 2001 From: "A.Sunil Kamath" Date: Thu, 16 Apr 2015 14:22:12 +0530 Subject: Implement enable/disable for Display C6 state This patch just implements the basic enable and disable functions of DC6 state which is needed for SKL platform. Its important to load SKL CSR program before calling enable. DC6 is a deeper power saving state where hardware dynamically disables power well 0 and saves the associated registers. DC6 can be entered when software allows it, the conditions for DC5 are met, and the PCU allows DC6. DC6 cannot be used if the backlight is being driven from the display utility pin. Its better to configure display engine to have power well 2 disabled before getting into DC6 enable function. Hence rpm framework will ensure to check status of power well 2 and DC5 before calling skl_enable_dc6. v2: Replace HAS_ with IS_ check as per Daniel's review comments v3: Cleared the bits dc5/dc6 enable of DC_STATE_EN register before setting them as per Satheesh's review comments. v4: No need to call gen9_disable_dc5 inside enable sequence of DC6, as its already take care above. v5: call POSTING_READ for every write to a register to ensure that its written immediately. Call intel_prepare_ddi during DC6 exit as it's required on low-power exit. v6: Protect DC6-enabling-disabling functionality with locks to synchronize with CSR-loading code. v7: Remove grabbing CSR-related mutex in skl_enable/disable_dc6 functions as deferred DC5-enabling functionality is now removed. v8: Remove 'Disabling DC5' from the debug comment during DC6 enabling as when DC6 is allowed, DC5 is not programmed at all. v9: - Rebase to latest. - Move all DC6-related functions from intel_display.c to intel_runtime_pm.c. v10: After adding dmc ver 1.0 support rebased on top of nightly. (Animesh) Issue: VIZ-2819 Signed-off-by: A.Sunil Kamath Signed-off-by: Damien Lespiau Signed-off-by: Animesh Manna Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 5bd7f083aa34..39810844a9c9 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -498,12 +498,35 @@ static void gen9_disable_dc5(struct drm_i915_private *dev_priv) static void skl_enable_dc6(struct drm_i915_private *dev_priv) { - /* TODO: Implementation to be done. */ + struct drm_device *dev = dev_priv->dev; + uint32_t val; + + WARN_ON(!IS_SKYLAKE(dev)); + + DRM_DEBUG_KMS("Enabling DC6\n"); + + gen9_set_dc_state_debugmask_memory_up(dev_priv); + + val = I915_READ(DC_STATE_EN); + val &= ~DC_STATE_EN_UPTO_DC5_DC6_MASK; + val |= DC_STATE_EN_UPTO_DC6; + I915_WRITE(DC_STATE_EN, val); + POSTING_READ(DC_STATE_EN); } static void skl_disable_dc6(struct drm_i915_private *dev_priv) { - /* TODO: Implementation to be done. */ + struct drm_device *dev = dev_priv->dev; + uint32_t val; + + WARN_ON(!IS_SKYLAKE(dev)); + + DRM_DEBUG_KMS("Disabling DC6\n"); + + val = I915_READ(DC_STATE_EN); + val &= ~DC_STATE_EN_UPTO_DC6; + I915_WRITE(DC_STATE_EN, val); + POSTING_READ(DC_STATE_EN); } static void skl_set_power_well(struct drm_i915_private *dev_priv, -- cgit v1.2.3-59-g8ed1b From 93c7cb6c3a2f8c7204fc8bcf7769059875a54027 Mon Sep 17 00:00:00 2001 From: Suketu Shah Date: Thu, 16 Apr 2015 14:22:13 +0530 Subject: drm/i915/skl: Assert the requirements to enter or exit DC6. Warn if the conditions to enter or exit DC6 are not satisfied such as support for runtime PM, state of power well, CSR loading etc. v2: Removed camelcase in functions and variables. v3: Do some minimal check to assert if CSR program is not loaded. v4: 1] Correct the check for backlight-disabling in assert_can_enable_dc6(). 2] Check csr.loaded = false before disabling DC6 and simplify other checks. v5: 1] Remove checks for DC5 state from assert_can_enable_dc6 function as DC5 is no longer enabled before enabling DC6. 2] Correct the check for CSR-loading in assert_can_disable_dc6 function as CSR must be loaded for context restore to happen on DC6 disabling. v6: 1] It's okay to explicitly disable DC6 during driver-load/resume even though it might already be disabled and so don't warn about it. v7: Rebase to latest. v8: Sqashed the patch from Imre - [PATCH] drm/i915/skl: avoid false CSR fw not loaded WARN during driver load/resume v9: After adding dmc ver 1.0 support rebased on top of nightly. (Animesh) v10: During initialization added a early return before disabling DC5. (Animesh) Issue: VIZ-2819 Signed-off-by: A.Sunil Kamath Signed-off-by: Suketu Shah Signed-off-by: Damien Lespiau Signed-off-by: Animesh Manna Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 40 +++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 39810844a9c9..b393db78e5cb 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -459,6 +459,12 @@ static void assert_can_disable_dc5(struct drm_i915_private *dev_priv) { bool pg2_enabled = intel_display_power_well_is_enabled(dev_priv, SKL_DISP_PW_2); + /* + * During initialization, the firmware may not be loaded yet. + * We still want to make sure that the DC enabling flag is cleared. + */ + if (dev_priv->power_domains.initializing) + return; WARN(!pg2_enabled, "PG2 not enabled to disable DC5.\n"); WARN(dev_priv->pm.suspended, @@ -496,12 +502,39 @@ static void gen9_disable_dc5(struct drm_i915_private *dev_priv) POSTING_READ(DC_STATE_EN); } -static void skl_enable_dc6(struct drm_i915_private *dev_priv) +static void assert_can_enable_dc6(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; + + WARN(!IS_SKYLAKE(dev), "Platform doesn't support DC6.\n"); + WARN(!HAS_RUNTIME_PM(dev), "Runtime PM not enabled.\n"); + WARN(I915_READ(UTIL_PIN_CTL) & UTIL_PIN_ENABLE, + "Backlight is not disabled.\n"); + WARN((I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC6), + "DC6 already programmed to be enabled.\n"); + + assert_csr_loaded(dev_priv); +} + +static void assert_can_disable_dc6(struct drm_i915_private *dev_priv) +{ + /* + * During initialization, the firmware may not be loaded yet. + * We still want to make sure that the DC enabling flag is cleared. + */ + if (dev_priv->power_domains.initializing) + return; + + assert_csr_loaded(dev_priv); + WARN(!(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC6), + "DC6 already programmed to be disabled.\n"); +} + +static void skl_enable_dc6(struct drm_i915_private *dev_priv) +{ uint32_t val; - WARN_ON(!IS_SKYLAKE(dev)); + assert_can_enable_dc6(dev_priv); DRM_DEBUG_KMS("Enabling DC6\n"); @@ -516,10 +549,9 @@ static void skl_enable_dc6(struct drm_i915_private *dev_priv) static void skl_disable_dc6(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; uint32_t val; - WARN_ON(!IS_SKYLAKE(dev)); + assert_can_disable_dc6(dev_priv); DRM_DEBUG_KMS("Disabling DC6\n"); -- cgit v1.2.3-59-g8ed1b From aeaa2122af4e53f3bfd28e8f294557bb95af43fc Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 30 Apr 2015 16:39:16 +0100 Subject: drm/i915/skl: Add the INIT power domain to the MISC I/O power well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Damien Lespiau Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index b393db78e5cb..64968d4ec62c 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -314,7 +314,8 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ BIT(POWER_DOMAIN_INIT)) #define SKL_DISPLAY_MISC_IO_POWER_DOMAINS ( \ - SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS) + SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS | \ + BIT(POWER_DOMAIN_INIT)) #define SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS ( \ (POWER_DOMAIN_MASK & ~(SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS | \ SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \ -- cgit v1.2.3-59-g8ed1b From 6222709d60734dd1e11f8d24520d9f23b4eb953e Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Thu, 30 Apr 2015 16:39:20 +0100 Subject: drm/i915/skl: Make the Misc I/O power well part of the PLLS domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The specs tell us to ungate PG1 and Misc I/O at display init. We'll use the PLLS power domain to ensure those two power wells are up. Signed-off-by: Damien Lespiau Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 64968d4ec62c..bd7ad1d2d5f5 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -315,6 +315,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, BIT(POWER_DOMAIN_INIT)) #define SKL_DISPLAY_MISC_IO_POWER_DOMAINS ( \ SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS | \ + BIT(POWER_DOMAIN_PLLS) | \ BIT(POWER_DOMAIN_INIT)) #define SKL_DISPLAY_ALWAYS_ON_POWER_DOMAINS ( \ (POWER_DOMAIN_MASK & ~(SKL_DISPLAY_POWERWELL_1_POWER_DOMAINS | \ -- cgit v1.2.3-59-g8ed1b From 70722468872b0752abaff54d34ed16af0d95cb9f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 10 Apr 2015 18:21:28 +0300 Subject: drm/i915: Work around DISPLAY_PHY_CONTROL register corruption on CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sometimes (exactly when is a bit unclear) DISPLAY_PHY_CONTROL appears to get corrupted. The values I've managed to read from it seem to have some pattern but vary quite a lot. The corruption doesn't seem to just happen when the register is accessed, but can also happen spontaneosly during modeset. When this happens during a modeset things go south and the display doesn't light up. I've managed to hit the problemn when toggling HDMI on port D on and off. When things get corrupted the display doesn't light up, but as soon as I manually write the correct value to the register the display comes up. First I was suspicious that we ourselves accidentally overwrite it with garbage, but didn't catch anything with the reg_rw tracepoint. Also I sprinkled check all over the modeset path to see exactly when the corruption happens, and eg. the read back value was fine just before intel_dp_set_m(), and corrupted immediately after it. I also made my check function repair the register value whenever it was wrong, and with this approach the corruption repeated several times during the modeset operation, always seeming to trigger in the same exact calls to the check function, while other calls to the function never caught anything. So far I've not seen this problem occurring when carefully avoiding all read accesses to DISPLAY_PHY_CONTROL. Not sure if that's just pure luck or an actual workaround, but we can hope it works. So let's avoid reading the register and instead track the desired value of the register in dev_priv. v2: Read out the power well state to determine initial register value v3: Use DPIO_CHx names instead of raw numbers Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_reg.h | 5 ++++- drivers/gpu/drm/i915/intel_runtime_pm.c | 36 ++++++++++++++++++++++++++++----- 3 files changed, 37 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 87fe4f7d5ce5..1321956ec066 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1782,6 +1782,8 @@ struct drm_i915_private { u32 fdi_rx_config; + u32 chv_phy_control; + u32 suspend_count; struct i915_suspend_saved_registers regfile; struct vlv_s0ix_state vlv_s0ix_state; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 98f10810bdbd..58627a319416 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2137,7 +2137,10 @@ enum skl_disp_power_wells { #define DPIO_PHY_STATUS (VLV_DISPLAY_BASE + 0x6240) #define DPLL_PORTD_READY_MASK (0xf) #define DISPLAY_PHY_CONTROL (VLV_DISPLAY_BASE + 0x60100) -#define PHY_COM_LANE_RESET_DEASSERT(phy) (1 << (phy)) +#define PHY_CH_SU_PSR 0x1 +#define PHY_CH_DEEP_PSR 0x7 +#define PHY_CH_POWER_MODE(mode, phy, ch) ((mode) << (6*(phy)+3*(ch)+2)) +#define PHY_COM_LANE_RESET_DEASSERT(phy) (1 << (phy)) #define DISPLAY_PHY_STATUS (VLV_DISPLAY_BASE + 0x60104) #define PHY_POWERGOOD(phy) (((phy) == DPIO_PHY0) ? (1<<31) : (1<<30)) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index bd7ad1d2d5f5..3d7352577bdc 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -949,8 +949,8 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, if (wait_for(I915_READ(DISPLAY_PHY_STATUS) & PHY_POWERGOOD(phy), 1)) DRM_ERROR("Display PHY %d is not power up\n", phy); - I915_WRITE(DISPLAY_PHY_CONTROL, I915_READ(DISPLAY_PHY_CONTROL) | - PHY_COM_LANE_RESET_DEASSERT(phy)); + dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(phy); + I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control); } static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, @@ -970,8 +970,8 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, assert_pll_disabled(dev_priv, PIPE_C); } - I915_WRITE(DISPLAY_PHY_CONTROL, I915_READ(DISPLAY_PHY_CONTROL) & - ~PHY_COM_LANE_RESET_DEASSERT(phy)); + dev_priv->chv_phy_control &= ~PHY_COM_LANE_RESET_DEASSERT(phy); + I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control); vlv_set_power_well(dev_priv, power_well, false); } @@ -1719,6 +1719,30 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv) mutex_unlock(&power_domains->lock); } +static void chv_phy_control_init(struct drm_i915_private *dev_priv) +{ + struct i915_power_well *cmn_bc = + lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC); + struct i915_power_well *cmn_d = + lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_D); + + /* + * DISPLAY_PHY_CONTROL can get corrupted if read. As a + * workaround never ever read DISPLAY_PHY_CONTROL, and + * instead maintain a shadow copy ourselves. Use the actual + * power well state to reconstruct the expected initial + * value. + */ + dev_priv->chv_phy_control = + PHY_CH_POWER_MODE(PHY_CH_SU_PSR, DPIO_PHY0, DPIO_CH0) | + PHY_CH_POWER_MODE(PHY_CH_SU_PSR, DPIO_PHY0, DPIO_CH1) | + PHY_CH_POWER_MODE(PHY_CH_SU_PSR, DPIO_PHY1, DPIO_CH0); + if (cmn_bc->ops->is_enabled(dev_priv, cmn_bc)) + dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY0); + if (cmn_d->ops->is_enabled(dev_priv, cmn_d)) + dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(DPIO_PHY1); +} + static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) { struct i915_power_well *cmn = @@ -1761,7 +1785,9 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv) power_domains->initializing = true; - if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) { + if (IS_CHERRYVIEW(dev)) { + chv_phy_control_init(dev_priv); + } else if (IS_VALLEYVIEW(dev)) { mutex_lock(&power_domains->lock); vlv_cmnlane_wa(dev_priv); mutex_unlock(&power_domains->lock); -- cgit v1.2.3-59-g8ed1b From 71849b67e788ca8899982df7adf21f61f44cb474 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 10 Apr 2015 18:21:29 +0300 Subject: Revert "drm/i915: Hack to tie both common lanes together on chv" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With recent hardware/firmware there don't appear to be any glitches on the other PHY when we toggle the cmnreset for the other PHY. So detangle the cmnlane power wells from one another and let them be controlled independently. This reverts commit 3dd7b97458e8aa2d8985b46622d226fa635071e7. Signed-off-by: Ville Syrjälä Reviewed-by: Deepak S Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 3d7352577bdc..317b9b43d1c1 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -1464,23 +1464,13 @@ static struct i915_power_well chv_power_wells[] = { #endif { .name = "dpio-common-bc", - /* - * XXX: cmnreset for one PHY seems to disturb the other. - * As a workaround keep both powered on at the same - * time for now. - */ - .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS | CHV_DPIO_CMN_D_POWER_DOMAINS, + .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS, .data = PUNIT_POWER_WELL_DPIO_CMN_BC, .ops = &chv_dpio_cmn_power_well_ops, }, { .name = "dpio-common-d", - /* - * XXX: cmnreset for one PHY seems to disturb the other. - * As a workaround keep both powered on at the same - * time for now. - */ - .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS | CHV_DPIO_CMN_D_POWER_DOMAINS, + .domains = CHV_DPIO_CMN_D_POWER_DOMAINS, .data = PUNIT_POWER_WELL_DPIO_CMN_D, .ops = &chv_dpio_cmn_power_well_ops, }, -- cgit v1.2.3-59-g8ed1b From 7e35ab88d8ec652803eb2965c00e3ed9967c4f9d Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sun, 10 May 2015 01:00:23 +0900 Subject: drm/i915: Fix typo in intel_runtime_pm.c This patch fix spelling typo in intel_runtime_pm.c Signed-off-by: Masanari Iida Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 317b9b43d1c1..3800be4ad76b 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -771,7 +771,7 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv, vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl); if (wait_for(COND, 100)) - DRM_ERROR("timout setting power well state %08x (%08x)\n", + DRM_ERROR("timeout setting power well state %08x (%08x)\n", state, vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL)); @@ -1029,7 +1029,7 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv, vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, ctrl); if (wait_for(COND, 100)) - DRM_ERROR("timout setting power well state %08x (%08x)\n", + DRM_ERROR("timeout setting power well state %08x (%08x)\n", state, vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ)); -- cgit v1.2.3-59-g8ed1b From bc284542dad88046eefa3a8d4d9907529c4af9e0 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 26 May 2015 20:22:38 +0300 Subject: drm/i915: Use the default 600ns LDO programming sequence delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not sure which LDO programming sequence delay should be used for the CHV PHY, but the spec says that 600ns is "Used by default for initial bringup", and the BIOS seems to use that, so let's do the same. Reviewed-by: Deepak S Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 4 ++++ drivers/gpu/drm/i915/intel_runtime_pm.c | 2 ++ 2 files changed, 6 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 607766d0a15d..e5910b76043e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2145,6 +2145,10 @@ enum skl_disp_power_wells { #define DPIO_PHY_STATUS (VLV_DISPLAY_BASE + 0x6240) #define DPLL_PORTD_READY_MASK (0xf) #define DISPLAY_PHY_CONTROL (VLV_DISPLAY_BASE + 0x60100) +#define PHY_LDO_DELAY_0NS 0x0 +#define PHY_LDO_DELAY_200NS 0x1 +#define PHY_LDO_DELAY_600NS 0x2 +#define PHY_LDO_SEQ_DELAY(delay, phy) ((delay) << (2*(phy)+23)) #define PHY_CH_SU_PSR 0x1 #define PHY_CH_DEEP_PSR 0x7 #define PHY_CH_POWER_MODE(mode, phy, ch) ((mode) << (6*(phy)+3*(ch)+2)) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 3800be4ad76b..720b0c63b63c 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -1724,6 +1724,8 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv) * value. */ dev_priv->chv_phy_control = + PHY_LDO_SEQ_DELAY(PHY_LDO_DELAY_600NS, DPIO_PHY0) | + PHY_LDO_SEQ_DELAY(PHY_LDO_DELAY_600NS, DPIO_PHY1) | PHY_CH_POWER_MODE(PHY_CH_SU_PSR, DPIO_PHY0, DPIO_CH0) | PHY_CH_POWER_MODE(PHY_CH_SU_PSR, DPIO_PHY0, DPIO_CH1) | PHY_CH_POWER_MODE(PHY_CH_SU_PSR, DPIO_PHY1, DPIO_CH0); -- cgit v1.2.3-59-g8ed1b From fde61e4b80ff23a379210a5780e59ace4bd915e6 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 26 May 2015 20:22:39 +0300 Subject: drm/i915: Throw out WIP CHV power well definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expecting CHV power wells to be just an extended versions of the VLV power wells, a bunch of commented out power wells were added in anticipation when Punit folks would implement it all. Turns out they never did, and instead CHV has fewer power wells than VLV. Rip out all the #if 0'ed junk that's not needed. v2: Rename the "pipe-a" well to "display" to match VLV Clarify the pipe A power well relationship to pipes B and C (Deepak) Reviewed-by: Deepak S Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 4 -- drivers/gpu/drm/i915/intel_runtime_pm.c | 98 ++------------------------------- 2 files changed, 4 insertions(+), 98 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e5910b76043e..6d3fead3a358 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -595,10 +595,6 @@ enum punit_power_well { PUNIT_POWER_WELL_DPIO_RX0 = 10, PUNIT_POWER_WELL_DPIO_RX1 = 11, PUNIT_POWER_WELL_DPIO_CMN_D = 12, - /* FIXME: guesswork below */ - PUNIT_POWER_WELL_DPIO_TX_D_LANES_01 = 13, - PUNIT_POWER_WELL_DPIO_TX_D_LANES_23 = 14, - PUNIT_POWER_WELL_DPIO_RX2 = 15, PUNIT_POWER_WELL_NUM, }; diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 720b0c63b63c..1a45385f4d66 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -1233,18 +1233,6 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, BIT(POWER_DOMAIN_AUX_C) | \ BIT(POWER_DOMAIN_INIT)) -#define CHV_PIPE_A_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PIPE_A) | \ - BIT(POWER_DOMAIN_INIT)) - -#define CHV_PIPE_B_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PIPE_B) | \ - BIT(POWER_DOMAIN_INIT)) - -#define CHV_PIPE_C_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PIPE_C) | \ - BIT(POWER_DOMAIN_INIT)) - #define CHV_DPIO_CMN_BC_POWER_DOMAINS ( \ BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \ BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \ @@ -1260,17 +1248,6 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, BIT(POWER_DOMAIN_AUX_D) | \ BIT(POWER_DOMAIN_INIT)) -#define CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \ - BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ - BIT(POWER_DOMAIN_AUX_D) | \ - BIT(POWER_DOMAIN_INIT)) - -#define CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS ( \ - BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \ - BIT(POWER_DOMAIN_AUX_D) | \ - BIT(POWER_DOMAIN_INIT)) - static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { .sync_hw = i9xx_always_on_power_well_noop, .enable = i9xx_always_on_power_well_noop, @@ -1428,40 +1405,17 @@ static struct i915_power_well chv_power_wells[] = { .domains = VLV_ALWAYS_ON_POWER_DOMAINS, .ops = &i9xx_always_on_power_well_ops, }, -#if 0 { .name = "display", - .domains = VLV_DISPLAY_POWER_DOMAINS, - .data = PUNIT_POWER_WELL_DISP2D, - .ops = &vlv_display_power_well_ops, - }, -#endif - { - .name = "pipe-a", /* - * FIXME: pipe A power well seems to be the new disp2d well. - * At least all registers seem to be housed there. Figure - * out if this a a temporary situation in pre-production - * hardware or a permanent state of affairs. + * Pipe A power well is the new disp2d well. Pipe B and C + * power wells don't actually exist. Pipe A power well is + * required for any pipe to work. */ - .domains = CHV_PIPE_A_POWER_DOMAINS | VLV_DISPLAY_POWER_DOMAINS, + .domains = VLV_DISPLAY_POWER_DOMAINS, .data = PIPE_A, .ops = &chv_pipe_power_well_ops, }, -#if 0 - { - .name = "pipe-b", - .domains = CHV_PIPE_B_POWER_DOMAINS, - .data = PIPE_B, - .ops = &chv_pipe_power_well_ops, - }, - { - .name = "pipe-c", - .domains = CHV_PIPE_C_POWER_DOMAINS, - .data = PIPE_C, - .ops = &chv_pipe_power_well_ops, - }, -#endif { .name = "dpio-common-bc", .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS, @@ -1474,50 +1428,6 @@ static struct i915_power_well chv_power_wells[] = { .data = PUNIT_POWER_WELL_DPIO_CMN_D, .ops = &chv_dpio_cmn_power_well_ops, }, -#if 0 - { - .name = "dpio-tx-b-01", - .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01, - }, - { - .name = "dpio-tx-b-23", - .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23, - }, - { - .name = "dpio-tx-c-01", - .domains = VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01, - }, - { - .name = "dpio-tx-c-23", - .domains = VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS | - VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23, - }, - { - .name = "dpio-tx-d-01", - .domains = CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS | - CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_D_LANES_01, - }, - { - .name = "dpio-tx-d-23", - .domains = CHV_DPIO_TX_D_LANES_01_POWER_DOMAINS | - CHV_DPIO_TX_D_LANES_23_POWER_DOMAINS, - .ops = &vlv_dpio_power_well_ops, - .data = PUNIT_POWER_WELL_DPIO_TX_D_LANES_23, - }, -#endif }; static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv, -- cgit v1.2.3-59-g8ed1b