Skip to content

Commit

Permalink
drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
Browse files Browse the repository at this point in the history
With bigjoiner, there will be 2 pipes driving 2 halves of 1 transcoder,
because of this, we need a pipe_mode for various calculations, including
for example watermarks, plane clipping, etc.

v10:
* remove redundant pipe_mode assignment (Ville)
v9:
* pipe_mode in state dump nd state check (Ville)
v8:
* Add pipe_mode in readout in verify_crtc_state (Ville)
v7:
* Remove redundant comment (Ville)
* Just keep mode instead of pipe_mode (Ville)
v6:
* renaming in separate function, only pipe_mode here (Ville)
* Add description (Maarten)
v5:
* Rebase (Manasi)
v4:
* Manual rebase (Manasi)
v3:
* Change state to crtc_state, fix rebase err  (Manasi)
v2:
* Manual Rebase (Manasi)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Reviewed-by: Animesh Manna <animesh.manna@intel.com>
[vsyrjala:
* Fix state checker
* Fix state dump
* Use pipe_mode for linetime watermarks
* Make sure pipe_mode normal timings are correct since the
  silly ddb code uses them
* Drop the redundant pipe_mode copies from intel_modeset_pipe_config()
  and intel_crtc_copy_uapi_to_hw_state()
* Use drm_mode_copy() all over]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201112191718.16683-7-ville.syrjala@linux.intel.com
  • Loading branch information
Maarten Lankhorst authored and Manasi Navare committed Nov 13, 2020
1 parent c42773b commit bafcdad
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 62 deletions.
67 changes: 45 additions & 22 deletions drivers/gpu/drm/i915/display/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -6073,18 +6073,16 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,

static int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state)
{
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
int width, height;

if (crtc_state->pch_pfit.enabled) {
width = drm_rect_width(&crtc_state->pch_pfit.dst);
height = drm_rect_height(&crtc_state->pch_pfit.dst);
} else {
width = adjusted_mode->crtc_hdisplay;
height = adjusted_mode->crtc_vdisplay;
width = pipe_mode->crtc_hdisplay;
height = pipe_mode->crtc_vdisplay;
}

return skl_update_scaler(crtc_state, !crtc_state->hw.active,
SKL_CRTC_INDEX,
&crtc_state->scaler_state.scaler_id,
Expand Down Expand Up @@ -8098,7 +8096,7 @@ static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)

static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
{
u32 pixel_rate = crtc_state->hw.adjusted_mode.crtc_clock;
u32 pixel_rate = crtc_state->hw.pipe_mode.crtc_clock;
unsigned int pipe_w, pipe_h, pfit_w, pfit_h;

/*
Expand Down Expand Up @@ -8156,7 +8154,7 @@ static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
if (HAS_GMCH(dev_priv))
/* FIXME calculate proper pipe pixel rate for GMCH pfit */
crtc_state->pixel_rate =
crtc_state->hw.adjusted_mode.crtc_clock;
crtc_state->hw.pipe_mode.crtc_clock;
else
crtc_state->pixel_rate =
ilk_pipe_pixel_rate(crtc_state);
Expand All @@ -8165,8 +8163,12 @@ static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
static void intel_crtc_readout_derived_state(struct intel_crtc_state *crtc_state)
{
struct drm_display_mode *mode = &crtc_state->hw.mode;
struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;

drm_mode_copy(pipe_mode, adjusted_mode);

intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
intel_mode_from_crtc_timings(adjusted_mode, adjusted_mode);

intel_crtc_compute_pixel_rate(crtc_state);
Expand All @@ -8188,9 +8190,12 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
struct drm_display_mode *pipe_mode = &pipe_config->hw.pipe_mode;
int clock_limit = dev_priv->max_dotclk_freq;

drm_mode_copy(pipe_mode, &pipe_config->hw.adjusted_mode);
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);

if (INTEL_GEN(dev_priv) < 4) {
clock_limit = dev_priv->max_cdclk_freq * 9 / 10;

Expand All @@ -8199,16 +8204,16 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
* is > 90% of the (display) core speed.
*/
if (intel_crtc_supports_double_wide(crtc) &&
adjusted_mode->crtc_clock > clock_limit) {
pipe_mode->crtc_clock > clock_limit) {
clock_limit = dev_priv->max_dotclk_freq;
pipe_config->double_wide = true;
}
}

if (adjusted_mode->crtc_clock > clock_limit) {
if (pipe_mode->crtc_clock > clock_limit) {
drm_dbg_kms(&dev_priv->drm,
"requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
adjusted_mode->crtc_clock, clock_limit,
pipe_mode->crtc_clock, clock_limit,
yesno(pipe_config->double_wide));
return -EINVAL;
}
Expand Down Expand Up @@ -8251,7 +8256,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
* WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
*/
if ((INTEL_GEN(dev_priv) > 4 || IS_G4X(dev_priv)) &&
adjusted_mode->crtc_hsync_start == adjusted_mode->crtc_hdisplay)
pipe_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
return -EINVAL;

intel_crtc_compute_pixel_rate(pipe_config);
Expand Down Expand Up @@ -12783,30 +12788,30 @@ static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)

static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_state)
{
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
const struct drm_display_mode *pipe_mode =
&crtc_state->hw.pipe_mode;
int linetime_wm;

if (!crtc_state->hw.enable)
return 0;

linetime_wm = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
adjusted_mode->crtc_clock);
linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
pipe_mode->crtc_clock);

return min(linetime_wm, 0x1ff);
}

static u16 hsw_ips_linetime_wm(const struct intel_crtc_state *crtc_state,
const struct intel_cdclk_state *cdclk_state)
{
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
const struct drm_display_mode *pipe_mode =
&crtc_state->hw.pipe_mode;
int linetime_wm;

if (!crtc_state->hw.enable)
return 0;

linetime_wm = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
cdclk_state->logical.cdclk);

return min(linetime_wm, 0x1ff);
Expand All @@ -12816,14 +12821,14 @@ static u16 skl_linetime_wm(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
const struct drm_display_mode *pipe_mode =
&crtc_state->hw.pipe_mode;
int linetime_wm;

if (!crtc_state->hw.enable)
return 0;

linetime_wm = DIV_ROUND_UP(adjusted_mode->crtc_htotal * 1000 * 8,
linetime_wm = DIV_ROUND_UP(pipe_mode->crtc_htotal * 1000 * 8,
crtc_state->pixel_rate);

/* Display WA #1135: BXT:ALL GLK:ALL */
Expand Down Expand Up @@ -13279,6 +13284,9 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
drm_dbg_kms(&dev_priv->drm, "pipe mode:\n");
drm_mode_debug_printmodeline(&pipe_config->hw.pipe_mode);
intel_dump_crtc_timings(dev_priv, &pipe_config->hw.pipe_mode);
drm_dbg_kms(&dev_priv->drm,
"port clock: %d, pipe src size: %dx%d, pixel rate %d\n",
pipe_config->port_clock,
Expand Down Expand Up @@ -14027,6 +14035,20 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,

PIPE_CONF_CHECK_X(output_types);

PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hdisplay);
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_htotal);
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hblank_start);
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hblank_end);
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hsync_start);
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hsync_end);

PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vdisplay);
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vtotal);
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vblank_start);
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vblank_end);
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vsync_start);
PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vsync_end);

PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_start);
Expand Down Expand Up @@ -14153,6 +14175,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
PIPE_CONF_CHECK_I(pipe_bpp);

PIPE_CONF_CHECK_CLOCK_FUZZY(hw.pipe_mode.crtc_clock);
PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);

Expand Down
11 changes: 9 additions & 2 deletions drivers/gpu/drm/i915/display/intel_display_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -817,15 +817,22 @@ struct intel_crtc_state {
* The following members are used to verify the hardware state:
* - enable
* - active
* - mode / adjusted_mode
* - mode / pipe_mode / adjusted_mode
* - color property blobs.
*
* During initial hw readout, they need to be copied to uapi.
*
* Bigjoiner will allow a transcoder mode that spans 2 pipes;
* Use the pipe_mode for calculations like watermarks, pipe
* scaler, and bandwidth.
*
* Use adjusted_mode for things that need to know the full
* mode on the transcoder, which spans all pipes.
*/
struct {
bool active, enable;
struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
struct drm_display_mode mode, adjusted_mode;
struct drm_display_mode mode, pipe_mode, adjusted_mode;
enum drm_scaling_filter scaling_filter;
} hw;

Expand Down
Loading

0 comments on commit bafcdad

Please sign in to comment.