@@ -3765,12 +3765,21 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
}
}
+static int
+get_drrs_pclk(struct drm_display_mode *fixed_mode, int refresh_rate)
+{
+ return (refresh_rate * fixed_mode->htotal * fixed_mode->vtotal) / 1000;
+}
+
static void
intel_dp_drrs_modelist_create(struct intel_digital_port *intel_dig_port,
struct drm_display_mode *fixed_mode,
struct drm_display_mode *lowest_mode)
{
struct intel_dp *intel_dp = &intel_dig_port->dp;
+ struct intel_encoder *intel_encoder = &intel_dig_port->base;
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
intel_dp->drrs_state.refresh_rate_array[DRRS_HIGH_RR] =
fixed_mode->vrefresh;
@@ -3779,6 +3788,29 @@ intel_dp_drrs_modelist_create(struct intel_digital_port *intel_dig_port,
intel_dp->drrs_state.refresh_rate_array[DRRS_LOW_RR] =
lowest_mode->vrefresh;
intel_dp->drrs_state.pixel_clock[DRRS_LOW_RR] = lowest_mode->clock;
+
+ /* Check if DMRRS is supported and create additional entries */
+ if (dev_priv->vbt.intel_dmrrs_enabled) {
+ if (lowest_mode->vrefresh < MEDIA_DMRRS_FREQ_2) {
+ intel_dp->drrs_state.refresh_rate_array[DRRS_50HZ_RR] =
+ MEDIA_DMRRS_FREQ_1;
+ intel_dp->drrs_state.pixel_clock[DRRS_50HZ_RR] =
+ get_drrs_pclk(fixed_mode,
+ MEDIA_DMRRS_FREQ_1);
+ intel_dp->drrs_state.refresh_rate_array[DRRS_48HZ_RR] =
+ MEDIA_DMRRS_FREQ_2;
+ intel_dp->drrs_state.pixel_clock[DRRS_48HZ_RR] =
+ get_drrs_pclk(fixed_mode,
+ MEDIA_DMRRS_FREQ_2);
+ } else if (lowest_mode->vrefresh < MEDIA_DMRRS_FREQ_1) {
+ intel_dp->drrs_state.refresh_rate_array[DRRS_50HZ_RR] =
+ MEDIA_DMRRS_FREQ_1;
+ intel_dp->drrs_state.pixel_clock[DRRS_50HZ_RR] =
+ get_drrs_pclk(fixed_mode,
+ MEDIA_DMRRS_FREQ_1);
+ }
+ } else
+ DRM_INFO("DMRRS not supported.\n");
}
void
@@ -3859,6 +3891,10 @@ intel_dp_attach_drrs_properties(struct intel_dp *intel_dp,
"high_rr"},
{ intel_dp->drrs_state.refresh_rate_array[DRRS_LOW_RR],
"low_rr"},
+ { intel_dp->drrs_state.refresh_rate_array[DRRS_50HZ_RR],
+ "50hz_rr"},
+ { intel_dp->drrs_state.refresh_rate_array[DRRS_48HZ_RR],
+ "48hz_rr"},
/**
* add more entries if more DRRS RRs supported.
* The no.of entries should be equal to
@@ -451,6 +451,11 @@ struct intel_hdmi {
#define DP_MAX_DOWNSTREAM_PORTS 0x10
/**
++ * Media refresh rates for dynamic switching
++ */
+#define MEDIA_DMRRS_FREQ_1 50
+#define MEDIA_DMRRS_FREQ_2 48
+/**
* This enum is used to indicate the DRRS support type.
* The values of the enum map 1-to-1 with the values from VBT.
*/
@@ -467,6 +472,8 @@ enum edp_panel_type {
enum edp_drrs_refresh_rate_type {
DRRS_HIGH_RR,
DRRS_LOW_RR,
+ DRRS_50HZ_RR,
+ DRRS_48HZ_RR,
DRRS_MAX_RR, /* RR count */
};
/**