* [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
2013-12-20 10:10 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
@ 2013-12-20 10:10 ` Vandana Kannan
2013-12-20 10:10 ` [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support Vandana Kannan
` (3 subsequent siblings)
4 siblings, 0 replies; 19+ messages in thread
From: Vandana Kannan @ 2013-12-20 10:10 UTC (permalink / raw)
To: intel-gfx
From: Pradeep Bhat <pradeep.bhat@intel.com>
This patch reads the DRRS support and Mode type from VBT fields.
The read information will be stored in VBT struct during BIOS
parsing. The above functionality is needed for decision making
whether DRRS feature is supported in i915 driver for eDP panels.
This information helps us decide if seamless DRRS can be done
at runtime to support certain power saving features. This patch
was tested by setting necessary bit in VBT struct and merging
the new VBT with system BIOS so that we can read the value.
v2: Incorporated review comments from Chris Wilson
Removed "intel_" as a prefix for DRRS specific declarations.
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.h | 9 +++++++++
drivers/gpu/drm/i915/intel_bios.c | 23 +++++++++++++++++++++++
drivers/gpu/drm/i915/intel_bios.h | 29 +++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ae2c80c..f8fd045 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1174,6 +1174,15 @@ struct intel_vbt_data {
int lvds_ssc_freq;
unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
+ /**
+ * DRRS mode type (Seamless OR Static DRRS)
+ * drrs_mode Val 0x2 is Seamless DRRS and 0 is Static DRRS.
+ * These values correspond to the VBT values for drrs mode.
+ */
+ int drrs_mode;
+ /* DRRS enabled or disabled in VBT */
+ bool drrs_enabled;
+
/* eDP */
int edp_rate;
int edp_lanes;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index f88e507..5b04a69 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -195,6 +195,21 @@ get_lvds_fp_timing(const struct bdb_header *bdb,
return (const struct lvds_fp_timing *)((const u8 *)bdb + ofs);
}
+/**
+ * This function returns the 2 bit information pertaining to a panel type
+ * present in a 32 bit field in VBT blocks. There are 16 panel types in VBT
+ * each occupying 2 bits of information in some 32 bit fields of VBT blocks.
+ */
+static int
+get_mode_by_paneltype(unsigned int word)
+{
+ /**
+ * The caller of this API should interpret the 2 bits
+ * based on VBT description for that field.
+ */
+ return (word >> ((panel_type - 1) * 2)) & MODE_MASK;
+}
+
/* Try to find integrated panel data */
static void
parse_lfp_panel_data(struct drm_i915_private *dev_priv,
@@ -218,6 +233,11 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
panel_type = lvds_options->panel_type;
+ dev_priv->vbt.drrs_mode =
+ get_mode_by_paneltype(lvds_options->dps_panel_type_bits);
+ DRM_DEBUG_KMS("DRRS supported mode is : %s\n",
+ (dev_priv->vbt.drrs_mode == 0) ? "STATIC" : "SEAMLESS");
+
lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
if (!lvds_lfp_data)
return;
@@ -488,6 +508,9 @@ parse_driver_features(struct drm_i915_private *dev_priv,
if (driver->dual_frequency)
dev_priv->render_reclock_avail = true;
+
+ dev_priv->vbt.drrs_enabled = driver->drrs_state;
+ DRM_DEBUG_KMS("DRRS State Enabled : %d\n", driver->drrs_state);
}
static void
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 81ed58c..0a3a751 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -281,6 +281,9 @@ struct bdb_general_definitions {
union child_device_config devices[0];
} __packed;
+/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
+#define MODE_MASK 0x3
+
struct bdb_lvds_options {
u8 panel_type;
u8 rsvd1;
@@ -293,6 +296,18 @@ struct bdb_lvds_options {
u8 lvds_edid:1;
u8 rsvd2:1;
u8 rsvd4;
+ /* LVDS Panel channel bits stored here */
+ u32 lvds_panel_channel_bits;
+ /* LVDS SSC (Spread Spectrum Clock) bits stored here. */
+ u16 ssc_bits;
+ u16 ssc_freq;
+ u16 ssc_ddt;
+ /* Panel color depth defined here */
+ u16 panel_color_depth;
+ /* LVDS panel type bits stored here */
+ u32 dps_panel_type_bits;
+ /* LVDS backlight control type bits stored here */
+ u32 blt_control_type_bits;
} __packed;
/* LFP pointer table contains entries to the struct below */
@@ -462,6 +477,20 @@ struct bdb_driver_features {
u8 hdmi_termination;
u8 custom_vbt_version;
+ /* Driver features data block */
+ u16 rmpm_state:1;
+ u16 s2ddt_state:1;
+ u16 dpst_state:1;
+ u16 bltclt_state:1;
+ u16 adb_state:1;
+ u16 drrs_state:1;
+ u16 grs_state:1;
+ u16 gpmt_state:1;
+ u16 tbt_state:1;
+ u16 psr_state:1;
+ u16 ips_state:1;
+ u16 reserved3:4;
+ u16 pc_feature_validity:1;
} __packed;
#define EDP_18BPP 0
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support
2013-12-20 10:10 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
2013-12-20 10:10 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
@ 2013-12-20 10:10 ` Vandana Kannan
2013-12-20 12:29 ` Jani Nikula
2013-12-20 10:10 ` [PATCH 3/5] drm/i915: Add support for DRRS to switch RR Vandana Kannan
` (2 subsequent siblings)
4 siblings, 1 reply; 19+ messages in thread
From: Vandana Kannan @ 2013-12-20 10:10 UTC (permalink / raw)
To: intel-gfx
From: Pradeep Bhat <pradeep.bhat@intel.com>
This patch and finds out the lowest refresh rate supported for the resolution
same as the fixed_mode, based on the implementaion find_panel_downclock.
It also checks the VBT fields to see if panel supports seamless DRRS or not.
Based on above data it marks whether eDP panel supports seamless DRRS or not.
This information is needed for supporting seamless DRRS switch for certain
power saving usecases. This patch is tested by enabling the DRM logs and
user should see whether Seamless DRRS is supported or not.
v2: Daniel's review comments
Modified downclock deduction based on intel_find_panel_downclock
v3: Chris's review comments
Moved edp_downclock_avail and edp_downclock to intel_panel
v4: Jani's review comments.
Changed name of the enum edp_panel_type to drrs_support type.
Change is_drrs_supported to drrs_support of type enum drrs_support_type.
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Jani Nikula <jani.nikula@linux.intel.com>
---
drivers/gpu/drm/i915/intel_dp.c | 45 ++++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_drv.h | 30 +++++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 8f17f8f..079b53f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3522,6 +3522,46 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
I915_READ(pp_div_reg));
}
+static void
+intel_dp_drrs_initialize(struct intel_digital_port *intel_dig_port,
+ struct intel_connector *intel_connector,
+ struct drm_display_mode *fixed_mode) {
+ struct drm_connector *connector = &intel_connector->base;
+ struct intel_dp *intel_dp = &intel_dig_port->dp;
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ /**
+ * Check if PSR is supported by panel and enabled
+ * if so then DRRS is reported as not supported for Haswell.
+ */
+ if (INTEL_INFO(dev)->gen < 8 && intel_edp_is_psr_enabled(dev)) {
+ DRM_INFO("eDP panel has PSR enabled. Cannot support DRRS\n");
+ return;
+ }
+
+ /* First check if DRRS is enabled from VBT struct */
+ if (!dev_priv->vbt.drrs_enabled) {
+ DRM_INFO("VBT doesn't support DRRS\n");
+ return;
+ }
+
+ intel_connector->panel.downclock_mode = intel_find_panel_downclock(dev,
+ fixed_mode, connector);
+
+ if (intel_connector->panel.downclock_mode != NULL &&
+ dev_priv->vbt.drrs_mode == SEAMLESS_DRRS_SUPPORT) {
+ intel_connector->panel.edp_downclock_avail = true;
+ intel_connector->panel.edp_downclock =
+ intel_connector->panel.downclock_mode->clock;
+
+ intel_dp->drrs_state.drrs_support = dev_priv->vbt.drrs_mode;
+
+ intel_dp->drrs_state.drrs_refresh_rate_type = DRRS_HIGH_RR;
+ DRM_INFO("SEAMLESS DRRS supported for eDP panel.\n");
+ }
+}
+
static bool intel_edp_init_connector(struct intel_dp *intel_dp,
struct intel_connector *intel_connector)
{
@@ -3535,6 +3575,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
struct drm_display_mode *scan;
struct edid *edid;
+ intel_dp->drrs_state.drrs_support = DRRS_NOT_SUPPORTED;
+
if (!is_edp(intel_dp))
return true;
@@ -3579,6 +3621,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
list_for_each_entry(scan, &connector->probed_modes, head) {
if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
fixed_mode = drm_mode_duplicate(dev, scan);
+ if (INTEL_INFO(dev)->gen >= 5)
+ intel_dp_drrs_initialize(intel_dig_port,
+ intel_connector, fixed_mode);
break;
}
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e903432..d208bf5 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -168,6 +168,9 @@ struct intel_panel {
bool active_low_pwm;
struct backlight_device *device;
} backlight;
+
+ bool edp_downclock_avail;
+ int edp_downclock;
};
struct intel_connector {
@@ -462,6 +465,32 @@ struct intel_hdmi {
#define DP_MAX_DOWNSTREAM_PORTS 0x10
+/**
+ * This enum is used to indicate the DRRS support type.
+ */
+enum drrs_support_type {
+ DRRS_NOT_SUPPORTED = -1,
+ STATIC_DRRS_SUPPORT = 0, /* 1:1 mapping with VBT */
+ SEAMLESS_DRRS_SUPPORT = 2 /* 1:1 mapping with VBT */ };
+/**
+ * HIGH_RR is the highest eDP panel refresh rate read from EDID
+ * LOW_RR is the lowest eDP panel refresh rate found from EDID
+ * parsing for same resolution.
+ */
+enum edp_drrs_refresh_rate_type {
+ DRRS_HIGH_RR,
+ DRRS_LOW_RR,
+ DRRS_MAX_RR, /* RR count */
+};
+/**
+ * The drrs_info struct will represent the DRRS feature for eDP
+ * panel.
+ */
+struct drrs_info {
+ enum drrs_support_type drrs_support;
+ enum edp_drrs_refresh_rate_type drrs_refresh_rate_type;
+};
+
struct intel_dp {
uint32_t output_reg;
uint32_t aux_ch_ctl_reg;
@@ -487,6 +516,7 @@ struct intel_dp {
bool want_panel_vdd;
bool psr_setup_done;
struct intel_connector *attached_connector;
+ struct drrs_info drrs_state;
};
struct intel_digital_port {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support
2013-12-20 10:10 ` [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support Vandana Kannan
@ 2013-12-20 12:29 ` Jani Nikula
2013-12-20 14:05 ` Daniel Vetter
0 siblings, 1 reply; 19+ messages in thread
From: Jani Nikula @ 2013-12-20 12:29 UTC (permalink / raw)
To: Vandana Kannan, intel-gfx
On Fri, 20 Dec 2013, Vandana Kannan <vandana.kannan@intel.com> wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
>
> This patch and finds out the lowest refresh rate supported for the resolution
> same as the fixed_mode, based on the implementaion find_panel_downclock.
> It also checks the VBT fields to see if panel supports seamless DRRS or not.
> Based on above data it marks whether eDP panel supports seamless DRRS or not.
> This information is needed for supporting seamless DRRS switch for certain
> power saving usecases. This patch is tested by enabling the DRM logs and
> user should see whether Seamless DRRS is supported or not.
>
> v2: Daniel's review comments
> Modified downclock deduction based on intel_find_panel_downclock
>
> v3: Chris's review comments
> Moved edp_downclock_avail and edp_downclock to intel_panel
>
> v4: Jani's review comments.
> Changed name of the enum edp_panel_type to drrs_support type.
> Change is_drrs_supported to drrs_support of type enum drrs_support_type.
>
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
> Reviewed-by: Jani Nikula <jani.nikula@linux.intel.com>
I'm sorry, this is not true. Only I get to say when you can add my
Reviewed-by.
Sometimes when the issues to be addressed are trivial, people say, "fix
this and you have my Reviewed-by", and adding it is okay.
Here, I was merely commenting on a few specific issues that I spotted on
a cursory reading of the patch, but I did not review the patch, and I
want my Reviewed-by carry some weight.
Thank you for your understanding,
Jani.
> ---
> drivers/gpu/drm/i915/intel_dp.c | 45 ++++++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_drv.h | 30 +++++++++++++++++++++++++
> 2 files changed, 75 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 8f17f8f..079b53f 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3522,6 +3522,46 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
> I915_READ(pp_div_reg));
> }
>
> +static void
> +intel_dp_drrs_initialize(struct intel_digital_port *intel_dig_port,
> + struct intel_connector *intel_connector,
> + struct drm_display_mode *fixed_mode) {
> + struct drm_connector *connector = &intel_connector->base;
> + struct intel_dp *intel_dp = &intel_dig_port->dp;
> + struct drm_device *dev = intel_dig_port->base.base.dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> +
> + /**
> + * Check if PSR is supported by panel and enabled
> + * if so then DRRS is reported as not supported for Haswell.
> + */
> + if (INTEL_INFO(dev)->gen < 8 && intel_edp_is_psr_enabled(dev)) {
> + DRM_INFO("eDP panel has PSR enabled. Cannot support DRRS\n");
> + return;
> + }
> +
> + /* First check if DRRS is enabled from VBT struct */
> + if (!dev_priv->vbt.drrs_enabled) {
> + DRM_INFO("VBT doesn't support DRRS\n");
> + return;
> + }
> +
> + intel_connector->panel.downclock_mode = intel_find_panel_downclock(dev,
> + fixed_mode, connector);
> +
> + if (intel_connector->panel.downclock_mode != NULL &&
> + dev_priv->vbt.drrs_mode == SEAMLESS_DRRS_SUPPORT) {
> + intel_connector->panel.edp_downclock_avail = true;
> + intel_connector->panel.edp_downclock =
> + intel_connector->panel.downclock_mode->clock;
> +
> + intel_dp->drrs_state.drrs_support = dev_priv->vbt.drrs_mode;
> +
> + intel_dp->drrs_state.drrs_refresh_rate_type = DRRS_HIGH_RR;
> + DRM_INFO("SEAMLESS DRRS supported for eDP panel.\n");
> + }
> +}
> +
> static bool intel_edp_init_connector(struct intel_dp *intel_dp,
> struct intel_connector *intel_connector)
> {
> @@ -3535,6 +3575,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
> struct drm_display_mode *scan;
> struct edid *edid;
>
> + intel_dp->drrs_state.drrs_support = DRRS_NOT_SUPPORTED;
> +
> if (!is_edp(intel_dp))
> return true;
>
> @@ -3579,6 +3621,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
> list_for_each_entry(scan, &connector->probed_modes, head) {
> if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
> fixed_mode = drm_mode_duplicate(dev, scan);
> + if (INTEL_INFO(dev)->gen >= 5)
> + intel_dp_drrs_initialize(intel_dig_port,
> + intel_connector, fixed_mode);
> break;
> }
> }
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index e903432..d208bf5 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -168,6 +168,9 @@ struct intel_panel {
> bool active_low_pwm;
> struct backlight_device *device;
> } backlight;
> +
> + bool edp_downclock_avail;
> + int edp_downclock;
> };
>
> struct intel_connector {
> @@ -462,6 +465,32 @@ struct intel_hdmi {
>
> #define DP_MAX_DOWNSTREAM_PORTS 0x10
>
> +/**
> + * This enum is used to indicate the DRRS support type.
> + */
> +enum drrs_support_type {
> + DRRS_NOT_SUPPORTED = -1,
> + STATIC_DRRS_SUPPORT = 0, /* 1:1 mapping with VBT */
> + SEAMLESS_DRRS_SUPPORT = 2 /* 1:1 mapping with VBT */ };
> +/**
> + * HIGH_RR is the highest eDP panel refresh rate read from EDID
> + * LOW_RR is the lowest eDP panel refresh rate found from EDID
> + * parsing for same resolution.
> + */
> +enum edp_drrs_refresh_rate_type {
> + DRRS_HIGH_RR,
> + DRRS_LOW_RR,
> + DRRS_MAX_RR, /* RR count */
> +};
> +/**
> + * The drrs_info struct will represent the DRRS feature for eDP
> + * panel.
> + */
> +struct drrs_info {
> + enum drrs_support_type drrs_support;
> + enum edp_drrs_refresh_rate_type drrs_refresh_rate_type;
> +};
> +
> struct intel_dp {
> uint32_t output_reg;
> uint32_t aux_ch_ctl_reg;
> @@ -487,6 +516,7 @@ struct intel_dp {
> bool want_panel_vdd;
> bool psr_setup_done;
> struct intel_connector *attached_connector;
> + struct drrs_info drrs_state;
> };
>
> struct intel_digital_port {
> --
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Jani Nikula, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support
2013-12-20 12:29 ` Jani Nikula
@ 2013-12-20 14:05 ` Daniel Vetter
2013-12-23 5:25 ` Vandana Kannan
0 siblings, 1 reply; 19+ messages in thread
From: Daniel Vetter @ 2013-12-20 14:05 UTC (permalink / raw)
To: Jani Nikula; +Cc: intel-gfx
On Fri, Dec 20, 2013 at 1:29 PM, Jani Nikula
<jani.nikula@linux.intel.com> wrote:
>> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
>> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
>> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
>> Reviewed-by: Jani Nikula <jani.nikula@linux.intel.com>
>
> I'm sorry, this is not true. Only I get to say when you can add my
> Reviewed-by.
Yeah, you can't just add review-by comments. In the linux kernel this
has a very specific meaning and can't just get handed out for "has
looked at the patches". For details of what a reviewed-by tag means
please see the "Reviewer's statement of oversight" in
Documentation/SubmittingPatches. I've noticed that you've also done
this with Ville's r-b tag for the picture ratio patch, I'll send out a
note that this r-b isn't legit.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support
2013-12-20 14:05 ` Daniel Vetter
@ 2013-12-23 5:25 ` Vandana Kannan
0 siblings, 0 replies; 19+ messages in thread
From: Vandana Kannan @ 2013-12-23 5:25 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
On Dec-20-2013 7:35 PM, Daniel Vetter wrote:
> On Fri, Dec 20, 2013 at 1:29 PM, Jani Nikula
> <jani.nikula@linux.intel.com> wrote:
>>> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
>>> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
>>> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>>> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
>>> Reviewed-by: Jani Nikula <jani.nikula@linux.intel.com>
>>
>> I'm sorry, this is not true. Only I get to say when you can add my
>> Reviewed-by.
>
> Yeah, you can't just add review-by comments. In the linux kernel this
> has a very specific meaning and can't just get handed out for "has
> looked at the patches". For details of what a reviewed-by tag means
> please see the "Reviewer's statement of oversight" in
> Documentation/SubmittingPatches. I've noticed that you've also done
> this with Ville's r-b tag for the picture ratio patch, I'll send out a
> note that this r-b isn't legit.
> -Daniel
>
Thanks for your inputs.
I will remove the r-b tag from all DRRS related patches, keeping the
details of versions/review comments incorporated in the commit message.
Also, I will follow the same and resend the patch on picture aspect ratio.
- Vandana
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/5] drm/i915: Add support for DRRS to switch RR
2013-12-20 10:10 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
2013-12-20 10:10 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
2013-12-20 10:10 ` [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support Vandana Kannan
@ 2013-12-20 10:10 ` Vandana Kannan
2013-12-20 10:10 ` [PATCH 4/5] drm/i915: Idleness detection for DRRS Vandana Kannan
2013-12-20 10:10 ` [PATCH 5/5] drm/i915/bdw: Add support for DRRS to switch RR Vandana Kannan
4 siblings, 0 replies; 19+ messages in thread
From: Vandana Kannan @ 2013-12-20 10:10 UTC (permalink / raw)
To: intel-gfx
From: Pradeep Bhat <pradeep.bhat@intel.com>
This patch computes and stored 2nd M/N/TU for switching to different
refresh rate dynamically. PIPECONF_EDP_RR_MODE_SWITCH bit helps toggle
between alternate refresh rates programmed in 2nd M/N/TU registers.
v2: Daniel's review comments
Computing M2/N2 in compute_config and storing it in crtc_config
v3: Modified reference to edp_downclock and edp_downclock_avail based on the
changes made to move them from dev_private to intel_panel.
v4: Modified references to is_drrs_supported based on the changes made to
rename it to drrs_support.
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/i915_reg.h | 1 +
drivers/gpu/drm/i915/intel_dp.c | 106 ++++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_drv.h | 6 ++-
3 files changed, 112 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f1eece4..57d2b64 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3206,6 +3206,7 @@
#define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */
#define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */
#define PIPECONF_INTERLACE_MODE_MASK (7 << 21)
+#define PIPECONF_EDP_RR_MODE_SWITCH (1 << 20)
#define PIPECONF_CXSR_DOWNCLOCK (1<<16)
#define PIPECONF_COLOR_RANGE_SELECT (1 << 13)
#define PIPECONF_BPC_MASK (0x7 << 5)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 079b53f..c473d02 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -791,6 +791,21 @@ intel_dp_set_clock(struct intel_encoder *encoder,
}
}
+static void
+intel_dp_set_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n)
+{
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum transcoder transcoder = crtc->config.cpu_transcoder;
+
+ I915_WRITE(PIPE_DATA_M2(transcoder),
+ TU_SIZE(m_n->tu) | m_n->gmch_m);
+ I915_WRITE(PIPE_DATA_N2(transcoder), m_n->gmch_n);
+ I915_WRITE(PIPE_LINK_M2(transcoder), m_n->link_m);
+ I915_WRITE(PIPE_LINK_N2(transcoder), m_n->link_n);
+ return;
+}
+
bool
intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
@@ -894,6 +909,14 @@ found:
pipe_config->port_clock,
&pipe_config->dp_m_n);
+ if (intel_connector->panel.edp_downclock_avail &&
+ intel_dp->drrs_state.drrs_support == SEAMLESS_DRRS_SUPPORT) {
+ intel_link_compute_m_n(bpp, lane_count,
+ intel_connector->panel.edp_downclock,
+ pipe_config->port_clock,
+ &pipe_config->dp_m2_n2);
+ }
+
intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
return true;
@@ -3522,6 +3545,87 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
I915_READ(pp_div_reg));
}
+void
+intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mode_config *mode_config = &dev->mode_config;
+ struct intel_encoder *encoder;
+ struct intel_dp *intel_dp = NULL;
+ struct intel_crtc_config *config = NULL;
+ struct intel_crtc *intel_crtc = NULL;
+ struct intel_connector *intel_connector = NULL;
+ bool found_edp = false;
+ u32 reg, val;
+ int index = 0;
+
+ if (refresh_rate <= 0) {
+ DRM_INFO("Refresh rate should be positive non-zero.\n");
+ goto out;
+ }
+
+ list_for_each_entry(encoder, &mode_config->encoder_list, base.head) {
+ if (encoder->type == INTEL_OUTPUT_EDP) {
+ intel_dp = enc_to_intel_dp(&encoder->base);
+ intel_crtc = encoder->new_crtc;
+ if (!intel_crtc) {
+ DRM_INFO("DRRS: intel_crtc not initialized\n");
+ goto out;
+ }
+ config = &intel_crtc->config;
+ intel_connector = intel_dp->attached_connector;
+ found_edp = true;
+ break;
+ }
+ }
+
+ if (!found_edp) {
+ DRM_INFO("DRRS supported for eDP only.\n");
+ goto out;
+ }
+
+ if (intel_dp->drrs_state.drrs_support < SEAMLESS_DRRS_SUPPORT) {
+ DRM_INFO("Seamless DRRS not supported.\n");
+ goto out;
+ }
+
+ if (intel_connector->panel.fixed_mode->vrefresh == refresh_rate)
+ index = DRRS_HIGH_RR;
+ else
+ index = DRRS_LOW_RR;
+
+ if (index == intel_dp->drrs_state.drrs_refresh_rate_type) {
+ DRM_INFO("DRRS requested for previously set RR...ignoring\n");
+ goto out;
+ }
+
+ if (!intel_crtc->active) {
+ DRM_INFO("eDP encoder has been disabled. CRTC not Active\n");
+ goto out;
+ }
+
+ mutex_lock(&intel_dp->drrs_state.mutex);
+
+ /* Haswell and below */
+ if (INTEL_INFO(dev)->gen >= 5 && INTEL_INFO(dev)->gen < 8) {
+ reg = PIPECONF(intel_crtc->config.cpu_transcoder);
+ val = I915_READ(reg);
+ if (index > DRRS_HIGH_RR) {
+ val |= PIPECONF_EDP_RR_MODE_SWITCH;
+ intel_dp_set_m2_n2(intel_crtc, &config->dp_m2_n2);
+ } else
+ val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
+ I915_WRITE(reg, val);
+ }
+
+ intel_dp->drrs_state.drrs_refresh_rate_type = index;
+ DRM_INFO("eDP Refresh Rate set to : %dHz\n", refresh_rate);
+
+ mutex_unlock(&intel_dp->drrs_state.mutex);
+
+out:
+ return;
+}
+
static void
intel_dp_drrs_initialize(struct intel_digital_port *intel_dig_port,
struct intel_connector *intel_connector,
@@ -3555,6 +3659,8 @@ intel_dp_drrs_initialize(struct intel_digital_port *intel_dig_port,
intel_connector->panel.edp_downclock =
intel_connector->panel.downclock_mode->clock;
+ mutex_init(&intel_dp->drrs_state.mutex);
+
intel_dp->drrs_state.drrs_support = dev_priv->vbt.drrs_mode;
intel_dp->drrs_state.drrs_refresh_rate_type = DRRS_HIGH_RR;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d208bf5..d1c60fa 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -291,6 +291,9 @@ struct intel_crtc_config {
int pipe_bpp;
struct intel_link_m_n dp_m_n;
+ /* m2_n2 for eDP downclock */
+ struct intel_link_m_n dp_m2_n2;
+
/*
* Frequence the dpll for the port should run at. Differs from the
* adjusted dotclock e.g. for DP or 12bpc hdmi mode. This is also
@@ -489,6 +492,7 @@ enum edp_drrs_refresh_rate_type {
struct drrs_info {
enum drrs_support_type drrs_support;
enum edp_drrs_refresh_rate_type drrs_refresh_rate_type;
+ struct mutex mutex;
};
struct intel_dp {
@@ -761,7 +765,7 @@ void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
void intel_edp_psr_enable(struct intel_dp *intel_dp);
void intel_edp_psr_disable(struct intel_dp *intel_dp);
void intel_edp_psr_update(struct drm_device *dev);
-
+extern void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate);
/* intel_dsi.c */
bool intel_dsi_init(struct drm_device *dev);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 4/5] drm/i915: Idleness detection for DRRS
2013-12-20 10:10 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
` (2 preceding siblings ...)
2013-12-20 10:10 ` [PATCH 3/5] drm/i915: Add support for DRRS to switch RR Vandana Kannan
@ 2013-12-20 10:10 ` Vandana Kannan
2013-12-20 10:10 ` [PATCH 5/5] drm/i915/bdw: Add support for DRRS to switch RR Vandana Kannan
4 siblings, 0 replies; 19+ messages in thread
From: Vandana Kannan @ 2013-12-20 10:10 UTC (permalink / raw)
To: intel-gfx
Adding support to detect display idleness by tracking page flip from
user space. Switch to low refresh rate is triggered after 2 seconds of
idleness. The delay is configurable. If there is a page flip or call to
update the plane, then high refresh rate is applied.
The feature is not used in dual-display mode.
v2: Chris's review comments
Modify idleness detection implementation to make it similar to the
implementation of intel_update_fbc/intel_disable_fbc
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.h | 16 +++++
drivers/gpu/drm/i915/intel_display.c | 14 ++++
drivers/gpu/drm/i915/intel_dp.c | 10 +++
drivers/gpu/drm/i915/intel_drv.h | 4 ++
drivers/gpu/drm/i915/intel_pm.c | 122 ++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_sprite.c | 2 +
6 files changed, 168 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f8fd045..d7308cc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -712,6 +712,21 @@ struct i915_fbc {
} no_fbc_reason;
};
+/* configure the number of secs the system must be idle
+ * before DRRS is enabled
+*/
+#define DRRS_IDLENESS_TIME 2000 /* in millisecs */
+
+struct i915_drrs {
+ struct intel_connector *connector;
+ struct intel_dp *dp;
+ struct intel_drrs_work {
+ struct delayed_work work;
+ struct drm_crtc *crtc;
+ int interval;
+ } *drrs_work;
+};
+
struct i915_psr {
bool sink_support;
bool source_ok;
@@ -1400,6 +1415,7 @@ typedef struct drm_i915_private {
int num_plane;
struct i915_fbc fbc;
+ struct i915_drrs drrs;
struct intel_opregion opregion;
struct intel_vbt_data vbt;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a40651e..995d117 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2395,6 +2395,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
}
intel_update_fbc(dev);
+ intel_update_drrs(dev);
intel_edp_psr_update(dev);
mutex_unlock(&dev->struct_mutex);
@@ -3559,6 +3560,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
+ intel_update_drrs(dev);
mutex_unlock(&dev->struct_mutex);
for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -3600,6 +3602,7 @@ static void haswell_crtc_enable_planes(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
+ intel_update_drrs(dev);
mutex_unlock(&dev->struct_mutex);
}
@@ -3806,6 +3809,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
+ intel_update_drrs(dev);
mutex_unlock(&dev->struct_mutex);
}
@@ -3853,6 +3857,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
+ intel_update_drrs(dev);
mutex_unlock(&dev->struct_mutex);
}
@@ -8226,6 +8231,11 @@ static void intel_unpin_work_fn(struct work_struct *__work)
drm_gem_object_unreference(&work->old_fb_obj->base);
intel_update_fbc(dev);
+
+ /* disable current DRRS work scheduled and restart
+ * to push work by another x seconds
+ */
+ intel_update_drrs(dev);
mutex_unlock(&dev->struct_mutex);
BUG_ON(atomic_read(&to_intel_crtc(work->crtc)->unpin_work_count) == 0);
@@ -8665,6 +8675,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
goto cleanup_pending;
intel_disable_fbc(dev);
+ intel_disable_drrs(dev);
intel_mark_fb_busy(obj, NULL);
mutex_unlock(&dev->struct_mutex);
@@ -10880,6 +10891,7 @@ void intel_modeset_init(struct drm_device *dev)
/* Just in case the BIOS is doing something questionable. */
intel_disable_fbc(dev);
+ intel_disable_drrs(dev);
}
static void
@@ -11286,6 +11298,8 @@ void intel_modeset_cleanup(struct drm_device *dev)
intel_disable_fbc(dev);
+ intel_disable_drrs(dev);
+
intel_disable_gt_powersave(dev);
ironlake_teardown_rc6(dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index c473d02..d9c5aca 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3289,11 +3289,18 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
struct intel_dp *intel_dp = &intel_dig_port->dp;
struct drm_device *dev = intel_dp_to_dev(intel_dp);
+ struct drm_i915_private *dev_priv = dev->dev_private;
i2c_del_adapter(&intel_dp->adapter);
drm_encoder_cleanup(encoder);
if (is_edp(intel_dp)) {
cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
+ /* DRRS cleanup */
+ if (intel_dp->drrs_state.drrs_support
+ == SEAMLESS_DRRS_SUPPORT) {
+ kfree(dev_priv->drrs.drrs_work);
+ dev_priv->drrs.drrs_work = NULL;
+ }
mutex_lock(&dev->mode_config.mutex);
ironlake_panel_vdd_off_sync(intel_dp);
mutex_unlock(&dev->mode_config.mutex);
@@ -3659,6 +3666,9 @@ intel_dp_drrs_initialize(struct intel_digital_port *intel_dig_port,
intel_connector->panel.edp_downclock =
intel_connector->panel.downclock_mode->clock;
+ intel_init_drrs_idleness_detection(dev,
+ intel_connector, intel_dp);
+
mutex_init(&intel_dp->drrs_state.mutex);
intel_dp->drrs_state.drrs_support = dev_priv->vbt.drrs_mode;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d1c60fa..84cadf8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -902,6 +902,10 @@ void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
void ilk_wm_get_hw_state(struct drm_device *dev);
+void intel_init_drrs_idleness_detection(struct drm_device *dev,
+ struct intel_connector *connector, struct intel_dp *dp);
+void intel_update_drrs(struct drm_device *dev);
+void intel_disable_drrs(struct drm_device *dev);
/* intel_sdvo.c */
bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b35f65e..69f31c5 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -615,6 +615,128 @@ out_disable:
i915_gem_stolen_cleanup_compression(dev);
}
+static void intel_drrs_work_fn(struct work_struct *__work)
+{
+ struct intel_drrs_work *work =
+ container_of(to_delayed_work(__work),
+ struct intel_drrs_work, work);
+ struct drm_device *dev = work->crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ intel_dp_set_drrs_state(work->crtc->dev,
+ dev_priv->drrs.connector->panel.downclock_mode->vrefresh);
+}
+
+static void intel_cancel_drrs_work(struct drm_i915_private *dev_priv)
+{
+ if (dev_priv->drrs.drrs_work == NULL)
+ return;
+
+ DRM_DEBUG_KMS("cancelling pending DRRS enable\n");
+
+ cancel_delayed_work_sync(&dev_priv->drrs.drrs_work->work);
+}
+
+static void intel_enable_drrs(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ intel_cancel_drrs_work(dev_priv);
+
+ if (dev_priv->drrs.dp->drrs_state.drrs_refresh_rate_type
+ != DRRS_LOW_RR) {
+ dev_priv->drrs.drrs_work->crtc = crtc;
+
+ /* Delay the actual enabling to let pageflipping cease and the
+ * display to settle before starting DRRS
+ */
+ schedule_delayed_work(&dev_priv->drrs.drrs_work->work,
+ msecs_to_jiffies(dev_priv->drrs.drrs_work->interval));
+ }
+}
+
+void intel_disable_drrs(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+
+ /* as part of disable DRRS, reset refresh rate to HIGH_RR */
+ if (dev_priv->drrs.dp->drrs_state.drrs_refresh_rate_type
+ == DRRS_LOW_RR) {
+ intel_cancel_drrs_work(dev_priv);
+ intel_dp_set_drrs_state(dev,
+ dev_priv->drrs.connector->panel.fixed_mode->vrefresh);
+ }
+}
+
+/**
+ * intel_update_drrs - enable/disable DRRS as needed
+ * @dev: the drm_device
+ * @update: if set to true, cancel current work and schedule new work.
+* if set to false, cancel current work and disable DRRS.
+*/
+void intel_update_drrs(struct drm_device *dev)
+{
+ struct drm_crtc *crtc = NULL, *tmp_crtc;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ /* if drrs.connector is NULL, then drrs_init did not get called.
+ * which means DRRS is not supported.
+ */
+ if (dev_priv->drrs.connector == NULL) {
+ DRM_INFO("DRRS is not supported.\n");
+ return;
+ }
+
+ list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
+ if (tmp_crtc != NULL && intel_crtc_active(tmp_crtc) &&
+ to_intel_crtc(tmp_crtc)->primary_enabled) {
+ if (crtc) {
+ DRM_DEBUG_KMS(
+ "more than one pipe active, disabling DRRS\n");
+ goto out_drrs_disable;
+ }
+ crtc = tmp_crtc;
+ }
+ }
+
+ if (crtc == NULL) {
+ DRM_INFO("DRRS: crtc not initialized\n");
+ return;
+ }
+
+ intel_disable_drrs(dev);
+
+ /* re-enable idleness detection */
+ intel_enable_drrs(crtc);
+
+out_drrs_disable:
+ intel_disable_drrs(dev);
+}
+
+void intel_init_drrs_idleness_detection(struct drm_device *dev,
+ struct intel_connector *connector,
+ struct intel_dp *dp)
+{
+ struct intel_drrs_work *work;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ work = kzalloc(sizeof(struct intel_drrs_work), GFP_KERNEL);
+ if (!work) {
+ DRM_ERROR("Failed to allocate DRRS work structure\n");
+ return;
+ }
+
+ dev_priv->drrs.connector = connector;
+ dev_priv->drrs.dp = dp;
+
+ work->interval = DRRS_IDLENESS_TIME;
+ INIT_DELAYED_WORK(&work->work, intel_drrs_work_fn);
+
+ dev_priv->drrs.drrs_work = work;
+}
+
static void i915_pineview_get_mem_freq(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 90a3f6d..c3dcffd 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -560,6 +560,7 @@ intel_enable_primary(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
+ intel_update_drrs(dev);
mutex_unlock(&dev->struct_mutex);
}
@@ -579,6 +580,7 @@ intel_disable_primary(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
if (dev_priv->fbc.plane == intel_crtc->plane)
intel_disable_fbc(dev);
+ intel_disable_drrs(dev);
mutex_unlock(&dev->struct_mutex);
/*
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5/5] drm/i915/bdw: Add support for DRRS to switch RR
2013-12-20 10:10 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
` (3 preceding siblings ...)
2013-12-20 10:10 ` [PATCH 4/5] drm/i915: Idleness detection for DRRS Vandana Kannan
@ 2013-12-20 10:10 ` Vandana Kannan
4 siblings, 0 replies; 19+ messages in thread
From: Vandana Kannan @ 2013-12-20 10:10 UTC (permalink / raw)
To: intel-gfx
For Broadwell, there is one instance of Transcoder MN values per transcoder.
For dynamic switching between multiple refreshr rates, M/N values may be
reprogrammed on the fly. Link N programming triggers update of all data and
link M & N registers and the new M/N values will be used in the next frame
that is output.
v2: Incorporated Chris's review comments
Changed to check for gen >=8 or gen > 5 before setting M/N registers
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/intel_dp.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d9c5aca..42aea17 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -798,11 +798,20 @@ intel_dp_set_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n)
struct drm_i915_private *dev_priv = dev->dev_private;
enum transcoder transcoder = crtc->config.cpu_transcoder;
- I915_WRITE(PIPE_DATA_M2(transcoder),
- TU_SIZE(m_n->tu) | m_n->gmch_m);
- I915_WRITE(PIPE_DATA_N2(transcoder), m_n->gmch_n);
- I915_WRITE(PIPE_LINK_M2(transcoder), m_n->link_m);
- I915_WRITE(PIPE_LINK_N2(transcoder), m_n->link_n);
+ if (INTEL_INFO(dev)->gen >= 8) {
+ I915_WRITE(PIPE_DATA_M1(transcoder),
+ TU_SIZE(m_n->tu) | m_n->gmch_m);
+ I915_WRITE(PIPE_DATA_N1(transcoder), m_n->gmch_n);
+ I915_WRITE(PIPE_LINK_M1(transcoder), m_n->link_m);
+ I915_WRITE(PIPE_LINK_N1(transcoder), m_n->link_n);
+ } else if (INTEL_INFO(dev)->gen >= 5) {
+ I915_WRITE(PIPE_DATA_M2(transcoder),
+ TU_SIZE(m_n->tu) | m_n->gmch_m);
+ I915_WRITE(PIPE_DATA_N2(transcoder), m_n->gmch_n);
+ I915_WRITE(PIPE_LINK_M2(transcoder), m_n->link_m);
+ I915_WRITE(PIPE_LINK_N2(transcoder), m_n->link_n);
+ }
+
return;
}
@@ -3612,8 +3621,17 @@ intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) {
mutex_lock(&intel_dp->drrs_state.mutex);
- /* Haswell and below */
- if (INTEL_INFO(dev)->gen >= 5 && INTEL_INFO(dev)->gen < 8) {
+ if (INTEL_INFO(dev)->gen >= 8) {
+ switch (index) {
+ case DRRS_HIGH_RR:
+ intel_dp_set_m2_n2(intel_crtc, &config->dp_m_n);
+ break;
+ case DRRS_LOW_RR:
+ intel_dp_set_m2_n2(intel_crtc, &config->dp_m2_n2);
+ break;
+ };
+ } else if (INTEL_INFO(dev)->gen >= 5) {
+ /* Haswell and below */
reg = PIPECONF(intel_crtc->config.cpu_transcoder);
val = I915_READ(reg);
if (index > DRRS_HIGH_RR) {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread