drm/i915: add pipe_config->timings_set
Only used by the lvds encoder. Note that we shouldn't do the same simple conversion with the FORCE_6BPC flag, since that's much better handled by moving all the pipe_bpc computation around. This requires that we pass the pipe config around to encoders, so that they can set special attributes and set constraints. To do so introduce a new ->compute_config encoder callback, which is called in stead of the drm crtc helper's ->mode_fixup. To avoid massive churn all over the codebase we don't want to convert all existing ->mode_fixup functions. Instead I've opted to convert them on an as-needed basis (mostly to cut down on rebase conflicts and to have more freedom to experiment around while developing the patches). Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
460da91617
commit
7ae892337e
|
@ -3987,7 +3987,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
|
||||||
/* All interlaced capable intel hw wants timings in frames. Note though
|
/* All interlaced capable intel hw wants timings in frames. Note though
|
||||||
* that intel_lvds_mode_fixup does some funny tricks with the crtc
|
* that intel_lvds_mode_fixup does some funny tricks with the crtc
|
||||||
* timings, so we need to be careful not to clobber these.*/
|
* timings, so we need to be careful not to clobber these.*/
|
||||||
if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
|
if (!pipe_config->timings_set)
|
||||||
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
||||||
|
|
||||||
/* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes
|
/* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes
|
||||||
|
@ -7560,6 +7560,16 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
|
||||||
|
|
||||||
if (&encoder->new_crtc->base != crtc)
|
if (&encoder->new_crtc->base != crtc)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (encoder->compute_config) {
|
||||||
|
if (!(encoder->compute_config(encoder, pipe_config))) {
|
||||||
|
DRM_DEBUG_KMS("Encoder config failure\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
encoder_funcs = encoder->base.helper_private;
|
encoder_funcs = encoder->base.helper_private;
|
||||||
if (!(encoder_funcs->mode_fixup(&encoder->base,
|
if (!(encoder_funcs->mode_fixup(&encoder->base,
|
||||||
&pipe_config->requested_mode,
|
&pipe_config->requested_mode,
|
||||||
|
|
|
@ -105,10 +105,6 @@
|
||||||
#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
|
#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
|
||||||
#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
|
#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
|
||||||
#define INTEL_MODE_DP_FORCE_6BPC (0x10)
|
#define INTEL_MODE_DP_FORCE_6BPC (0x10)
|
||||||
/* This flag must be set by the encoder's mode_fixup if it changes the crtc
|
|
||||||
* timings in the mode to prevent the crtc fixup from overwriting them.
|
|
||||||
* Currently only lvds needs that. */
|
|
||||||
#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)
|
|
||||||
/*
|
/*
|
||||||
* Set when limited 16-235 (as opposed to full 0-255) RGB color range is
|
* Set when limited 16-235 (as opposed to full 0-255) RGB color range is
|
||||||
* to be used.
|
* to be used.
|
||||||
|
@ -158,6 +154,8 @@ struct intel_encoder {
|
||||||
bool cloneable;
|
bool cloneable;
|
||||||
bool connectors_active;
|
bool connectors_active;
|
||||||
void (*hot_plug)(struct intel_encoder *);
|
void (*hot_plug)(struct intel_encoder *);
|
||||||
|
bool (*compute_config)(struct intel_encoder *,
|
||||||
|
struct intel_crtc_config *);
|
||||||
void (*pre_pll_enable)(struct intel_encoder *);
|
void (*pre_pll_enable)(struct intel_encoder *);
|
||||||
void (*pre_enable)(struct intel_encoder *);
|
void (*pre_enable)(struct intel_encoder *);
|
||||||
void (*enable)(struct intel_encoder *);
|
void (*enable)(struct intel_encoder *);
|
||||||
|
@ -203,6 +201,10 @@ struct intel_connector {
|
||||||
struct intel_crtc_config {
|
struct intel_crtc_config {
|
||||||
struct drm_display_mode requested_mode;
|
struct drm_display_mode requested_mode;
|
||||||
struct drm_display_mode adjusted_mode;
|
struct drm_display_mode adjusted_mode;
|
||||||
|
/* This flag must be set by the encoder's compute_config callback if it
|
||||||
|
* changes the crtc timings in the mode to prevent the crtc fixup from
|
||||||
|
* overwriting them. Currently only lvds needs that. */
|
||||||
|
bool timings_set;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct intel_crtc {
|
struct intel_crtc {
|
||||||
|
|
|
@ -261,8 +261,6 @@ centre_horizontally(struct drm_display_mode *mode,
|
||||||
|
|
||||||
mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
|
mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
|
||||||
mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
|
mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
|
||||||
|
|
||||||
mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -284,8 +282,6 @@ centre_vertically(struct drm_display_mode *mode,
|
||||||
|
|
||||||
mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
|
mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
|
||||||
mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
|
mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
|
||||||
|
|
||||||
mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 panel_fitter_scaling(u32 source, u32 target)
|
static inline u32 panel_fitter_scaling(u32 source, u32 target)
|
||||||
|
@ -301,15 +297,17 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target)
|
||||||
return (FACTOR * ratio + FACTOR/2) / FACTOR;
|
return (FACTOR * ratio + FACTOR/2) / FACTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
|
static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
|
||||||
const struct drm_display_mode *mode,
|
struct intel_crtc_config *pipe_config)
|
||||||
struct drm_display_mode *adjusted_mode)
|
|
||||||
{
|
{
|
||||||
struct drm_device *dev = encoder->dev;
|
struct drm_device *dev = intel_encoder->base.dev;
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
|
struct intel_lvds_encoder *lvds_encoder =
|
||||||
|
to_lvds_encoder(&intel_encoder->base);
|
||||||
struct intel_connector *intel_connector =
|
struct intel_connector *intel_connector =
|
||||||
&lvds_encoder->attached_connector->base;
|
&lvds_encoder->attached_connector->base;
|
||||||
|
struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
|
||||||
|
struct drm_display_mode *mode = &pipe_config->requested_mode;
|
||||||
struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
|
struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
|
||||||
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
|
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
|
||||||
int pipe;
|
int pipe;
|
||||||
|
@ -359,6 +357,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
|
||||||
I915_WRITE(BCLRPAT(pipe), 0);
|
I915_WRITE(BCLRPAT(pipe), 0);
|
||||||
|
|
||||||
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
drm_mode_set_crtcinfo(adjusted_mode, 0);
|
||||||
|
pipe_config->timings_set = true;
|
||||||
|
|
||||||
switch (intel_connector->panel.fitting_mode) {
|
switch (intel_connector->panel.fitting_mode) {
|
||||||
case DRM_MODE_SCALE_CENTER:
|
case DRM_MODE_SCALE_CENTER:
|
||||||
|
@ -661,7 +660,6 @@ static int intel_lvds_set_property(struct drm_connector *connector,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
|
static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
|
||||||
.mode_fixup = intel_lvds_mode_fixup,
|
|
||||||
.mode_set = intel_lvds_mode_set,
|
.mode_set = intel_lvds_mode_set,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1105,6 +1103,7 @@ bool intel_lvds_init(struct drm_device *dev)
|
||||||
intel_encoder->enable = intel_enable_lvds;
|
intel_encoder->enable = intel_enable_lvds;
|
||||||
intel_encoder->pre_enable = intel_pre_enable_lvds;
|
intel_encoder->pre_enable = intel_pre_enable_lvds;
|
||||||
intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds;
|
intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds;
|
||||||
|
intel_encoder->compute_config = intel_lvds_compute_config;
|
||||||
intel_encoder->disable = intel_disable_lvds;
|
intel_encoder->disable = intel_disable_lvds;
|
||||||
intel_encoder->get_hw_state = intel_lvds_get_hw_state;
|
intel_encoder->get_hw_state = intel_lvds_get_hw_state;
|
||||||
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
||||||
|
|
Loading…
Reference in New Issue