* [PATCH 1/3] drm/i915: Added a return type for panel fitter config functions
2014-06-20 13:55 [PATCH 0/3] New drm crtc properties akash.goel
@ 2014-06-20 13:55 ` akash.goel
2014-06-20 14:03 ` Chris Wilson
2014-06-20 13:55 ` [PATCH 2/3] drm/i915: Initialized 'set_property' fn pointer field of intel_crtc_funcs structure akash.goel
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: akash.goel @ 2014-06-20 13:55 UTC (permalink / raw)
To: intel-gfx; +Cc: --cc=vijay.a.purushothaman, Akash Goel
From: Akash Goel <akash.goel@intel.com>
This patch changes the return type of panel fitter configuration
functions from 'void', so that an error could be returned back to
User space, either during the modeset time or when the 'border' property
is being set, if the configuation is not valid.
Signed-off-by: Akash Goel <akash.goel@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 5 +++--
drivers/gpu/drm/i915/intel_dp.c | 17 ++++++++++-------
drivers/gpu/drm/i915/intel_drv.h | 6 +++---
drivers/gpu/drm/i915/intel_hdmi.c | 2 +-
drivers/gpu/drm/i915/intel_lvds.c | 13 +++++++------
drivers/gpu/drm/i915/intel_panel.c | 10 ++++++----
drivers/gpu/drm/i915/intel_sdvo.c | 2 +-
drivers/gpu/drm/i915/intel_tv.c | 2 +-
8 files changed, 32 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5e8e711..f764b74 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10631,9 +10631,10 @@ static int intel_set_mode(struct drm_crtc *crtc,
return ret;
}
-void intel_crtc_restore_mode(struct drm_crtc *crtc)
+int intel_crtc_restore_mode(struct drm_crtc *crtc)
{
- intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
+ return intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
+ crtc->primary->fb);
}
#undef for_each_intel_crtc_masked
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 912e9c4..6117639 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -824,12 +824,15 @@ intel_dp_compute_config(struct intel_encoder *encoder,
if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
adjusted_mode);
- if (!HAS_PCH_SPLIT(dev))
- intel_gmch_panel_fitting(intel_crtc, pipe_config,
- intel_connector->panel.fitting_mode);
- else
- intel_pch_panel_fitting(intel_crtc, pipe_config,
- intel_connector->panel.fitting_mode);
+ if (!HAS_PCH_SPLIT(dev)) {
+ if (!intel_gmch_panel_fitting(intel_crtc, pipe_config,
+ intel_connector->panel.fitting_mode))
+ return false;
+ } else {
+ if (!intel_pch_panel_fitting(intel_crtc, pipe_config,
+ intel_connector->panel.fitting_mode))
+ return false;
+ }
}
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
@@ -3782,7 +3785,7 @@ intel_dp_set_property(struct drm_connector *connector,
done:
if (intel_encoder->base.crtc)
- intel_crtc_restore_mode(intel_encoder->base.crtc);
+ return intel_crtc_restore_mode(intel_encoder->base.crtc);
return 0;
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ab5962b..860d531 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -727,7 +727,7 @@ void intel_mark_busy(struct drm_device *dev);
void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
struct intel_engine_cs *ring);
void intel_mark_idle(struct drm_device *dev);
-void intel_crtc_restore_mode(struct drm_crtc *crtc);
+int intel_crtc_restore_mode(struct drm_crtc *crtc);
void intel_crtc_update_dpms(struct drm_crtc *crtc);
void intel_encoder_destroy(struct drm_encoder *encoder);
void intel_connector_dpms(struct drm_connector *, int mode);
@@ -918,10 +918,10 @@ int intel_panel_init(struct intel_panel *panel,
void intel_panel_fini(struct intel_panel *panel);
void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
struct drm_display_mode *adjusted_mode);
-void intel_pch_panel_fitting(struct intel_crtc *crtc,
+bool intel_pch_panel_fitting(struct intel_crtc *crtc,
struct intel_crtc_config *pipe_config,
int fitting_mode);
-void intel_gmch_panel_fitting(struct intel_crtc *crtc,
+bool intel_gmch_panel_fitting(struct intel_crtc *crtc,
struct intel_crtc_config *pipe_config,
int fitting_mode);
void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 318b150..2551b62 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1128,7 +1128,7 @@ intel_hdmi_set_property(struct drm_connector *connector,
done:
if (intel_dig_port->base.base.crtc)
- intel_crtc_restore_mode(intel_dig_port->base.base.crtc);
+ return intel_crtc_restore_mode(intel_dig_port->base.base.crtc);
return 0;
}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 2312602..ca251a0 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -303,12 +303,13 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
if (HAS_PCH_SPLIT(dev)) {
pipe_config->has_pch_encoder = true;
- intel_pch_panel_fitting(intel_crtc, pipe_config,
- intel_connector->panel.fitting_mode);
+ if (!intel_pch_panel_fitting(intel_crtc, pipe_config,
+ intel_connector->panel.fitting_mode))
+ return false;
} else {
- intel_gmch_panel_fitting(intel_crtc, pipe_config,
- intel_connector->panel.fitting_mode);
-
+ if (!intel_gmch_panel_fitting(intel_crtc, pipe_config,
+ intel_connector->panel.fitting_mode))
+ return false;
}
/*
@@ -499,7 +500,7 @@ static int intel_lvds_set_property(struct drm_connector *connector,
* If the CRTC is enabled, the display will be changed
* according to the new panel fitting mode.
*/
- intel_crtc_restore_mode(crtc);
+ return intel_crtc_restore_mode(crtc);
}
}
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 38a9857..e605006 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -96,7 +96,7 @@ intel_find_panel_downclock(struct drm_device *dev,
}
/* adjusted_mode has been preset to be the panel's fixed mode */
-void
+bool
intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
struct intel_crtc_config *pipe_config,
int fitting_mode)
@@ -158,13 +158,14 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
default:
WARN(1, "bad panel fit mode: %d\n", fitting_mode);
- return;
+ return false;
}
done:
pipe_config->pch_pfit.pos = (x << 16) | y;
pipe_config->pch_pfit.size = (width << 16) | height;
pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0;
+ return true;
}
static void
@@ -300,7 +301,7 @@ static void i9xx_scale_aspect(struct intel_crtc_config *pipe_config,
}
}
-void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
+bool intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
struct intel_crtc_config *pipe_config,
int fitting_mode)
{
@@ -352,7 +353,7 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
break;
default:
WARN(1, "bad panel fit mode: %d\n", fitting_mode);
- return;
+ return false;
}
/* 965+ wants fuzzy fitting */
@@ -374,6 +375,7 @@ out:
pipe_config->gmch_pfit.control = pfit_control;
pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
pipe_config->gmch_pfit.lvds_border_bits = border;
+ return true;
}
enum drm_connector_status
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 20375cc..5628cfd 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2223,7 +2223,7 @@ set_value:
done:
if (intel_sdvo->base.base.crtc)
- intel_crtc_restore_mode(intel_sdvo->base.base.crtc);
+ return intel_crtc_restore_mode(intel_sdvo->base.base.crtc);
return 0;
#undef CHECK_PROPERTY
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 67c6c9a..7c04066 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1490,7 +1490,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
}
if (changed && crtc)
- intel_crtc_restore_mode(crtc);
+ return intel_crtc_restore_mode(crtc);
out:
return ret;
}
--
1.9.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 1/3] drm/i915: Added a return type for panel fitter config functions
2014-06-20 13:55 ` [PATCH 1/3] drm/i915: Added a return type for panel fitter config functions akash.goel
@ 2014-06-20 14:03 ` Chris Wilson
2014-06-23 8:27 ` Akash Goel
0 siblings, 1 reply; 8+ messages in thread
From: Chris Wilson @ 2014-06-20 14:03 UTC (permalink / raw)
To: akash.goel; +Cc: intel-gfx, --cc=vijay.a.purushothaman
On Fri, Jun 20, 2014 at 07:25:52PM +0530, akash.goel@intel.com wrote:
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 912e9c4..6117639 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -824,12 +824,15 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
> intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
> adjusted_mode);
> - if (!HAS_PCH_SPLIT(dev))
> - intel_gmch_panel_fitting(intel_crtc, pipe_config,
> - intel_connector->panel.fitting_mode);
> - else
> - intel_pch_panel_fitting(intel_crtc, pipe_config,
> - intel_connector->panel.fitting_mode);
> + if (!HAS_PCH_SPLIT(dev)) {
> + if (!intel_gmch_panel_fitting(intel_crtc, pipe_config,
> + intel_connector->panel.fitting_mode))
> + return false;
> + } else {
> + if (!intel_pch_panel_fitting(intel_crtc, pipe_config,
> + intel_connector->panel.fitting_mode))
> + return false;
> + }
> }
>
> if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
> @@ -3782,7 +3785,7 @@ intel_dp_set_property(struct drm_connector *connector,
>
> done:
> if (intel_encoder->base.crtc)
> - intel_crtc_restore_mode(intel_encoder->base.crtc);
> + return intel_crtc_restore_mode(intel_encoder->base.crtc);
But you don't unwind the property change after failure.
>
> return 0;
> }
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index ab5962b..860d531 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -727,7 +727,7 @@ void intel_mark_busy(struct drm_device *dev);
> void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
> struct intel_engine_cs *ring);
> void intel_mark_idle(struct drm_device *dev);
> -void intel_crtc_restore_mode(struct drm_crtc *crtc);
> +int intel_crtc_restore_mode(struct drm_crtc *crtc);
> void intel_crtc_update_dpms(struct drm_crtc *crtc);
> void intel_encoder_destroy(struct drm_encoder *encoder);
> void intel_connector_dpms(struct drm_connector *, int mode);
> @@ -918,10 +918,10 @@ int intel_panel_init(struct intel_panel *panel,
> void intel_panel_fini(struct intel_panel *panel);
> void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
> struct drm_display_mode *adjusted_mode);
> -void intel_pch_panel_fitting(struct intel_crtc *crtc,
> +bool intel_pch_panel_fitting(struct intel_crtc *crtc,
> struct intel_crtc_config *pipe_config,
> int fitting_mode);
> -void intel_gmch_panel_fitting(struct intel_crtc *crtc,
> +bool intel_gmch_panel_fitting(struct intel_crtc *crtc,
> struct intel_crtc_config *pipe_config,
> int fitting_mode);
Only make significnt changes like this to one interface at a time.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 1/3] drm/i915: Added a return type for panel fitter config functions
2014-06-20 14:03 ` Chris Wilson
@ 2014-06-23 8:27 ` Akash Goel
0 siblings, 0 replies; 8+ messages in thread
From: Akash Goel @ 2014-06-23 8:27 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx
On Fri, 2014-06-20 at 15:03 +0100, Chris Wilson wrote:
> On Fri, Jun 20, 2014 at 07:25:52PM +0530, akash.goel@intel.com wrote:
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index 912e9c4..6117639 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -824,12 +824,15 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> > if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
> > intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
> > adjusted_mode);
> > - if (!HAS_PCH_SPLIT(dev))
> > - intel_gmch_panel_fitting(intel_crtc, pipe_config,
> > - intel_connector->panel.fitting_mode);
> > - else
> > - intel_pch_panel_fitting(intel_crtc, pipe_config,
> > - intel_connector->panel.fitting_mode);
> > + if (!HAS_PCH_SPLIT(dev)) {
> > + if (!intel_gmch_panel_fitting(intel_crtc, pipe_config,
> > + intel_connector->panel.fitting_mode))
> > + return false;
> > + } else {
> > + if (!intel_pch_panel_fitting(intel_crtc, pipe_config,
> > + intel_connector->panel.fitting_mode))
> > + return false;
> > + }
> > }
> >
> > if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
> > @@ -3782,7 +3785,7 @@ intel_dp_set_property(struct drm_connector *connector,
> >
> > done:
> > if (intel_encoder->base.crtc)
> > - intel_crtc_restore_mode(intel_encoder->base.crtc);
> > + return intel_crtc_restore_mode(intel_encoder->base.crtc);
>
> But you don't unwind the property change after failure.
Sorry, will handle this in next version of the patch.
>
> >
> > return 0;
> > }
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index ab5962b..860d531 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -727,7 +727,7 @@ void intel_mark_busy(struct drm_device *dev);
> > void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
> > struct intel_engine_cs *ring);
> > void intel_mark_idle(struct drm_device *dev);
> > -void intel_crtc_restore_mode(struct drm_crtc *crtc);
> > +int intel_crtc_restore_mode(struct drm_crtc *crtc);
> > void intel_crtc_update_dpms(struct drm_crtc *crtc);
> > void intel_encoder_destroy(struct drm_encoder *encoder);
> > void intel_connector_dpms(struct drm_connector *, int mode);
> > @@ -918,10 +918,10 @@ int intel_panel_init(struct intel_panel *panel,
> > void intel_panel_fini(struct intel_panel *panel);
> > void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
> > struct drm_display_mode *adjusted_mode);
> > -void intel_pch_panel_fitting(struct intel_crtc *crtc,
> > +bool intel_pch_panel_fitting(struct intel_crtc *crtc,
> > struct intel_crtc_config *pipe_config,
> > int fitting_mode);
> > -void intel_gmch_panel_fitting(struct intel_crtc *crtc,
> > +bool intel_gmch_panel_fitting(struct intel_crtc *crtc,
> > struct intel_crtc_config *pipe_config,
> > int fitting_mode);
>
> Only make significnt changes like this to one interface at a time.
Fine will split this patch in 2 parts.
> -Chris
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/3] drm/i915: Initialized 'set_property' fn pointer field of intel_crtc_funcs structure
2014-06-20 13:55 [PATCH 0/3] New drm crtc properties akash.goel
2014-06-20 13:55 ` [PATCH 1/3] drm/i915: Added a return type for panel fitter config functions akash.goel
@ 2014-06-20 13:55 ` akash.goel
2014-06-20 13:55 ` [PATCH 3/3] drm/i915: New drm crtc property for varying the size of borders akash.goel
2014-06-20 14:07 ` [PATCH 0/3] New drm crtc properties Damien Lespiau
3 siblings, 0 replies; 8+ messages in thread
From: akash.goel @ 2014-06-20 13:55 UTC (permalink / raw)
To: intel-gfx; +Cc: --cc=vijay.a.purushothaman, Akash Goel
From: Akash Goel <akash.goel@intel.com>
This patch defines a new function & assigns that to the 'set_property'
function pointer field of the 'intel_crtc_funcs' structure.
Signed-off-by: Akash Goel <akash.goel@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f764b74..d95afb6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11064,11 +11064,20 @@ out_config:
return ret;
}
+static int intel_crtc_set_property(struct drm_crtc *crtc,
+ struct drm_property *property, uint64_t val)
+{
+ int ret = -ENOENT;
+
+ return ret;
+}
+
static const struct drm_crtc_funcs intel_crtc_funcs = {
.gamma_set = intel_crtc_gamma_set,
.set_config = intel_crtc_set_config,
.destroy = intel_crtc_destroy,
.page_flip = intel_crtc_page_flip,
+ .set_property = intel_crtc_set_property,
};
static void intel_cpu_pll_init(struct drm_device *dev)
--
1.9.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 3/3] drm/i915: New drm crtc property for varying the size of borders
2014-06-20 13:55 [PATCH 0/3] New drm crtc properties akash.goel
2014-06-20 13:55 ` [PATCH 1/3] drm/i915: Added a return type for panel fitter config functions akash.goel
2014-06-20 13:55 ` [PATCH 2/3] drm/i915: Initialized 'set_property' fn pointer field of intel_crtc_funcs structure akash.goel
@ 2014-06-20 13:55 ` akash.goel
2014-06-20 14:07 ` [PATCH 0/3] New drm crtc properties Damien Lespiau
3 siblings, 0 replies; 8+ messages in thread
From: akash.goel @ 2014-06-20 13:55 UTC (permalink / raw)
To: intel-gfx; +Cc: --cc=vijay.a.purushothaman, Akash Goel
From: Akash Goel <akash.goel@intel.com>
This patch adds a new drm crtc property for varying the size of
the horizontal & vertical borers of the output/display window.
This will control the output of Panel fitter.
There are actually 4 separate properties so as to allow a
control on the size of each border left/top/bottom/right
Testcase: igt/kms_panel_fitter_test
Signed-off-by: Akash Goel <akash.goel@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 10 ++
drivers/gpu/drm/i915/intel_display.c | 118 ++++++++++++++++++-
drivers/gpu/drm/i915/intel_drv.h | 12 ++
drivers/gpu/drm/i915/intel_panel.c | 219 ++++++++++++++++++++++++++++++++---
4 files changed, 344 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0640071..b1d94d3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1515,6 +1515,16 @@ struct drm_i915_private {
struct drm_property *broadcast_rgb_property;
struct drm_property *force_audio_property;
+ /*
+ * Properties to dynamically vary the size of the
+ * borders. This will indirectly control the size
+ * of the display window i.e Panel fitter output
+ */
+ struct drm_property *left_border_property;
+ struct drm_property *right_border_property;
+ struct drm_property *top_border_property;
+ struct drm_property *bottom_border_property;
+
uint32_t hw_context_size;
struct list_head context_list;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d95afb6..cf0b67f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11064,12 +11064,124 @@ out_config:
return ret;
}
+static void intel_create_crtc_properties(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+ /* Create properties*/
+ if (!dev_priv->left_border_property)
+ dev_priv->left_border_property =
+ drm_property_create_range(dev, 0, "left border",
+ 0, (uint64_t)MAX_BORDER_VALUE);
+
+ if (!dev_priv->right_border_property)
+ dev_priv->right_border_property =
+ drm_property_create_range(dev, 0, "right border",
+ 0, (uint64_t)MAX_BORDER_VALUE);
+
+ if (!dev_priv->top_border_property)
+ dev_priv->top_border_property =
+ drm_property_create_range(dev, 0, "top border",
+ 0, (uint64_t)MAX_BORDER_VALUE);
+
+ if (!dev_priv->bottom_border_property)
+ dev_priv->bottom_border_property =
+ drm_property_create_range(dev, 0, "bottom border",
+ 0, (uint64_t)MAX_BORDER_VALUE);
+
+ /* Attach to properties*/
+ if (dev_priv->left_border_property)
+ drm_object_attach_property(&intel_crtc->base.base,
+ dev_priv->left_border_property,
+ 0);
+
+ if (dev_priv->right_border_property)
+ drm_object_attach_property(&intel_crtc->base.base,
+ dev_priv->right_border_property,
+ 0);
+
+ if (dev_priv->top_border_property)
+ drm_object_attach_property(&intel_crtc->base.base,
+ dev_priv->top_border_property,
+ 0);
+
+ if (dev_priv->bottom_border_property)
+ drm_object_attach_property(&intel_crtc->base.base,
+ dev_priv->bottom_border_property,
+ 0);
+}
+
static int intel_crtc_set_property(struct drm_crtc *crtc,
struct drm_property *property, uint64_t val)
{
- int ret = -ENOENT;
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- return ret;
+ if (property == dev_priv->left_border_property) {
+ if (val == (uint64_t)intel_crtc->border[PANEL_BORDER_LEFT])
+ return 0;
+ if (val & 1) {
+ DRM_ERROR("Odd border value not supported\n");
+ return -EINVAL;
+ }
+
+ intel_crtc->border[PANEL_BORDER_LEFT] = (uint32_t)val;
+ goto done;
+ }
+
+ if (property == dev_priv->right_border_property) {
+ if (val == (uint64_t)intel_crtc->border[PANEL_BORDER_RIGHT])
+ return 0;
+ if (val & 1) {
+ DRM_ERROR("Odd border value not supported\n");
+ return -EINVAL;
+ }
+
+ intel_crtc->border[PANEL_BORDER_RIGHT] = (uint32_t)val;
+ goto done;
+ }
+
+ if (property == dev_priv->top_border_property) {
+ if (val == (uint64_t)intel_crtc->border[PANEL_BORDER_TOP])
+ return 0;
+ if (val & 1) {
+ DRM_ERROR("Odd border value not supported\n");
+ return -EINVAL;
+ }
+
+ intel_crtc->border[PANEL_BORDER_TOP] = (uint32_t)val;
+ goto done;
+ }
+
+ if (property == dev_priv->bottom_border_property) {
+ if (val == (uint64_t)intel_crtc->border[PANEL_BORDER_BOTTOM])
+ return 0;
+ if (val & 1) {
+ DRM_ERROR("Odd border value not supported\n");
+ return -EINVAL;
+ }
+
+ intel_crtc->border[PANEL_BORDER_BOTTOM] = (uint32_t)val;
+ goto done;
+ }
+
+ return -EINVAL;
+
+done:
+ if (crtc) {
+ intel_crtc->apply_borders =
+ ((intel_crtc->border[PANEL_BORDER_LEFT] != 0) ||
+ (intel_crtc->border[PANEL_BORDER_RIGHT] != 0) ||
+ (intel_crtc->border[PANEL_BORDER_TOP] != 0) ||
+ (intel_crtc->border[PANEL_BORDER_BOTTOM] != 0));
+
+ return intel_crtc_restore_mode(crtc);
+ }
+
+ return -EINVAL;
}
static const struct drm_crtc_funcs intel_crtc_funcs = {
@@ -11516,6 +11628,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
+ intel_create_crtc_properties(&intel_crtc->base);
+
WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe);
return;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 860d531..34b695f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -109,6 +109,14 @@
#define INTEL_DSI_VIDEO_MODE 0
#define INTEL_DSI_COMMAND_MODE 1
+#define MAX_BORDER_VALUE 256
+enum panel_border {
+ PANEL_BORDER_LEFT = 0,
+ PANEL_BORDER_RIGHT,
+ PANEL_BORDER_TOP,
+ PANEL_BORDER_BOTTOM,
+};
+
struct intel_framebuffer {
struct drm_framebuffer base;
struct drm_i915_gem_object *obj;
@@ -407,6 +415,10 @@ struct intel_crtc {
bool cpu_fifo_underrun_disabled;
bool pch_fifo_underrun_disabled;
+ /* border info for the output/display window */
+ uint32_t border[4];
+ bool apply_borders;
+
/* per-pipe watermark state */
struct {
/* watermarks currently being used */
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index e605006..f459745 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -29,10 +29,25 @@
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+/* Max Downscale ratio of 1.125, expressed in 1.12 fixed point format */
+#define MAX_DOWNSCALE_RATIO (0x9 << 9)
#include <linux/moduleparam.h>
#include "intel_drv.h"
+static inline u32 panel_fitter_scaling(u32 source, u32 target)
+{
+ /*
+ * Floating point operation is not supported. So the FACTOR
+ * is defined, which can avoid the floating point computation
+ * when calculating the panel ratio.
+ */
+#define ACCURACY 12
+#define FACTOR (1 << ACCURACY)
+ u32 ratio = source * FACTOR / target;
+ return (FACTOR * ratio + FACTOR/2) / FACTOR;
+}
+
void
intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
struct drm_display_mode *adjusted_mode)
@@ -95,6 +110,61 @@ intel_find_panel_downclock(struct drm_device *dev,
return NULL;
}
+bool
+intel_pch_manual_panel_fitting(struct intel_crtc *intel_crtc,
+ struct intel_crtc_config *pipe_config)
+{
+ struct drm_display_mode *adjusted_mode;
+ int x, y;
+ u32 pf_horizontal_ratio, pf_vertical_ratio;
+ u32 tot_width, tot_height;
+ u32 src_width, src_height; /* pipesrc.x, pipesrc.y */
+ u32 dst_width, dst_height;
+
+ adjusted_mode = &pipe_config->adjusted_mode;
+
+ src_width = pipe_config->pipe_src_w;
+ src_height = pipe_config->pipe_src_h;
+
+ tot_width = adjusted_mode->hdisplay;
+ tot_height = adjusted_mode->vdisplay;
+
+ /*
+ * Having non zero borders will reduce the size of 'HACTIVE/VACTIVE'
+ * region. So (HACTIVE - Left border - Right Border) *
+ * (VACTIVE - Top Border - Bottom border) will effectively be the
+ * output rectangle on screen
+ */
+ dst_width = tot_width - intel_crtc->border[PANEL_BORDER_LEFT] -
+ intel_crtc->border[PANEL_BORDER_RIGHT];
+ dst_height = tot_height - intel_crtc->border[PANEL_BORDER_TOP] -
+ intel_crtc->border[PANEL_BORDER_BOTTOM];
+
+ if ((dst_width == 0) || (dst_height == 0)) {
+ DRM_ERROR("Invalid border size input\n");
+ return false;
+ }
+
+ pf_horizontal_ratio = panel_fitter_scaling(src_width, dst_width);
+ pf_vertical_ratio = panel_fitter_scaling(src_height, dst_height);
+
+ if (pf_horizontal_ratio > MAX_DOWNSCALE_RATIO) {
+ DRM_ERROR("width is too small\n");
+ return false;
+ } else if (pf_vertical_ratio > MAX_DOWNSCALE_RATIO) {
+ DRM_ERROR("height is too small\n");
+ return false;
+ }
+
+ x = intel_crtc->border[PANEL_BORDER_LEFT];
+ y = intel_crtc->border[PANEL_BORDER_TOP];
+
+ pipe_config->pch_pfit.pos = (x << 16) | y;
+ pipe_config->pch_pfit.size = (dst_width << 16) | dst_height;
+ pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0;
+ return true;
+}
+
/* adjusted_mode has been preset to be the panel's fixed mode */
bool
intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
@@ -108,6 +178,12 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
x = y = width = height = 0;
+ /* check if User wants to apply the borders, otherwise fall
+ through the regular path */
+ if (intel_crtc->apply_borders)
+ return intel_pch_manual_panel_fitting(intel_crtc,
+ pipe_config);
+
/* Native modes don't need fitting */
if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
adjusted_mode->vdisplay == pipe_config->pipe_src_h)
@@ -169,6 +245,50 @@ done:
}
static void
+apply_horizontal_borders(struct drm_display_mode *mode,
+ int *border)
+{
+ u32 width, sync_pos, blank_width, sync_width;
+
+ /* keep the hsync and hblank widths constant */
+ sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start;
+ blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start;
+ sync_pos = (blank_width - sync_width + 1) / 2;
+
+ width = mode->hdisplay - border[PANEL_BORDER_LEFT] -
+ border[PANEL_BORDER_RIGHT];
+
+ mode->crtc_hdisplay = width;
+ mode->crtc_hblank_start = width + border[PANEL_BORDER_RIGHT];
+ mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width;
+
+ mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
+ mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
+}
+
+static void
+apply_vertical_borders(struct drm_display_mode *mode,
+ int *border)
+{
+ u32 height, sync_pos, blank_width, sync_width;
+
+ /* keep the vsync and vblank widths constant */
+ sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start;
+ blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start;
+ sync_pos = (blank_width - sync_width + 1) / 2;
+
+ height = mode->vdisplay - border[PANEL_BORDER_TOP] -
+ border[PANEL_BORDER_BOTTOM];
+
+ mode->crtc_vdisplay = height;
+ mode->crtc_vblank_start = height + border[PANEL_BORDER_BOTTOM];
+ mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width;
+
+ mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
+ mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
+}
+
+static void
centre_horizontally(struct drm_display_mode *mode,
int width)
{
@@ -211,19 +331,6 @@ centre_vertically(struct drm_display_mode *mode,
mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
}
-static inline u32 panel_fitter_scaling(u32 source, u32 target)
-{
- /*
- * Floating point operation is not supported. So the FACTOR
- * is defined, which can avoid the floating point computation
- * when calculating the panel ratio.
- */
-#define ACCURACY 12
-#define FACTOR (1 << ACCURACY)
- u32 ratio = source * FACTOR / target;
- return (FACTOR * ratio + FACTOR/2) / FACTOR;
-}
-
static void i965_scale_aspect(struct intel_crtc_config *pipe_config,
u32 *pfit_control)
{
@@ -301,6 +408,86 @@ static void i9xx_scale_aspect(struct intel_crtc_config *pipe_config,
}
}
+bool intel_gmch_manual_panel_fitting(struct intel_crtc *intel_crtc,
+ struct intel_crtc_config *pipe_config)
+{
+ struct drm_device *dev = intel_crtc->base.dev;
+ u32 pfit_control = 0, border = 0;
+ u32 pf_horizontal_ratio, pf_vertical_ratio;
+ struct drm_display_mode *adjusted_mode;
+ u32 tot_width, tot_height;
+ u32 src_width, src_height; /* pipesrc.x, pipesrc.y */
+ u32 dst_width, dst_height;
+
+ adjusted_mode = &pipe_config->adjusted_mode;
+
+ src_width = pipe_config->pipe_src_w;
+ src_height = pipe_config->pipe_src_h;
+
+ tot_width = adjusted_mode->hdisplay;
+ tot_height = adjusted_mode->vdisplay;
+
+ /*
+ * Having non zero borders will reduce the size of 'HACTIVE/VACTIVE'
+ * region. So (HACTIVE - Left border - Right Border) *
+ * (VACTIVE - Top Border - Bottom border) will effectively be the
+ * output rectangle on screen
+ */
+ dst_width = tot_width - intel_crtc->border[PANEL_BORDER_LEFT] -
+ intel_crtc->border[PANEL_BORDER_RIGHT];
+ dst_height = tot_height - intel_crtc->border[PANEL_BORDER_TOP] -
+ intel_crtc->border[PANEL_BORDER_BOTTOM];
+
+ if ((dst_width == 0) || (dst_height == 0)) {
+ DRM_ERROR("Invalid border size input\n");
+ return false;
+ }
+
+ pf_horizontal_ratio = panel_fitter_scaling(src_width, dst_width);
+ pf_vertical_ratio = panel_fitter_scaling(src_height, dst_height);
+
+ if (pf_horizontal_ratio > MAX_DOWNSCALE_RATIO) {
+ DRM_ERROR("width is too small\n");
+ return false;
+ } else if (pf_vertical_ratio > MAX_DOWNSCALE_RATIO) {
+ DRM_ERROR("height is too small\n");
+ return false;
+ }
+
+ if (dst_width != tot_width)
+ apply_horizontal_borders(adjusted_mode, intel_crtc->border);
+ if (dst_height != tot_height)
+ apply_vertical_borders(adjusted_mode, intel_crtc->border);
+
+ /* No scaling needed now, but still enable the panel fitter,
+ as that will allow the User to subequently do the dynamic
+ flipping of fbs of different resolutions */
+ if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
+ adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h) {
+ DRM_DEBUG_KMS("Forcefully enabling the Panel fitter\n");
+ }
+
+ border = LVDS_BORDER_ENABLE;
+
+ if (INTEL_INFO(dev)->gen >= 4) {
+ /* PFIT_SCALING_PROGRAMMED is de-featured on BYT */
+ pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
+ pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | PFIT_FILTER_FUZZY);
+ } else {
+ pfit_control |= (PFIT_ENABLE |
+ VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
+ VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR);
+ }
+
+ /* Make sure pre-965 set dither correctly for 18bpp panels. */
+ if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18)
+ pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+
+ pipe_config->gmch_pfit.control = pfit_control;
+ pipe_config->gmch_pfit.lvds_border_bits = border;
+ return true;
+}
+
bool intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
struct intel_crtc_config *pipe_config,
int fitting_mode)
@@ -311,6 +498,12 @@ bool intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
adjusted_mode = &pipe_config->adjusted_mode;
+ /* check if User wants to apply the borders, otherwise fall
+ through the regular path */
+ if (intel_crtc->apply_borders)
+ return intel_gmch_manual_panel_fitting(intel_crtc,
+ pipe_config);
+
/* Native modes don't need fitting */
if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
adjusted_mode->vdisplay == pipe_config->pipe_src_h)
--
1.9.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 0/3] New drm crtc properties
2014-06-20 13:55 [PATCH 0/3] New drm crtc properties akash.goel
` (2 preceding siblings ...)
2014-06-20 13:55 ` [PATCH 3/3] drm/i915: New drm crtc property for varying the size of borders akash.goel
@ 2014-06-20 14:07 ` Damien Lespiau
2014-06-23 8:28 ` Akash Goel
3 siblings, 1 reply; 8+ messages in thread
From: Damien Lespiau @ 2014-06-20 14:07 UTC (permalink / raw)
To: akash.goel; +Cc: intel-gfx
On Fri, Jun 20, 2014 at 07:25:51PM +0530, akash.goel@intel.com wrote:
> From: Akash Goel <akash.goel@intel.com>
>
> Added new drm crtc properties which provides control
> to vary the size of horizontal & vertical borders.
> With this the size of the Panel fitter output or
> display window can be controlled.
> Also added a return type to panel fitter config functions,
> so that an error could be returned to User space for an
> invalid configuration.
>
> Akash Goel (3):
> drm/i915: Added a return type for panel fitter config functions
> drm/i915: Initialized 'set_property' fn pointer field of
> intel_crtc_funcs structure
> drm/i915: New drm crtc property for varying the size of borders
As an aside, you're missing the new property documentation in
Documentation/DocBook/drm.tmpl.
--
Damien
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 0/3] New drm crtc properties
2014-06-20 14:07 ` [PATCH 0/3] New drm crtc properties Damien Lespiau
@ 2014-06-23 8:28 ` Akash Goel
0 siblings, 0 replies; 8+ messages in thread
From: Akash Goel @ 2014-06-23 8:28 UTC (permalink / raw)
To: Damien Lespiau; +Cc: intel-gfx
On Fri, 2014-06-20 at 15:07 +0100, Damien Lespiau wrote:
> On Fri, Jun 20, 2014 at 07:25:51PM +0530, akash.goel@intel.com wrote:
> > From: Akash Goel <akash.goel@intel.com>
> >
> > Added new drm crtc properties which provides control
> > to vary the size of horizontal & vertical borders.
> > With this the size of the Panel fitter output or
> > display window can be controlled.
> > Also added a return type to panel fitter config functions,
> > so that an error could be returned to User space for an
> > invalid configuration.
> >
> > Akash Goel (3):
> > drm/i915: Added a return type for panel fitter config functions
> > drm/i915: Initialized 'set_property' fn pointer field of
> > intel_crtc_funcs structure
> > drm/i915: New drm crtc property for varying the size of borders
>
> As an aside, you're missing the new property documentation in
> Documentation/DocBook/drm.tmpl.
Sorry, will float the corresponding Documentation patch in the next
series.
>
^ permalink raw reply [flat|nested] 8+ messages in thread