This series is a follow up from the discussion at [1]. We start by introducing crtc->mode_valid(), encoder->mode_valid() and bridge->mode_valid() callbacks which will be used in followup patches and also by cleaning the documentation a little bit. This patch is available at [2] and the series depends on it.
We proceed by introducing new helpers to call this new callbacks at 1/10.
At 2/10 a helper function is introduced that calls all mode_valid() from a set of bridges.
Next, at 3/10 we modify the connector probe helper so that only modes which are supported by a given bridge+encoder+crtc combination are probbed.
At 4/10 we call all the mode_valid() callbacks for a given pipeline, except the connector->mode_valid one, so that the mode is validated. This is done before calling mode_fixup().
Finally, from 5/10 to 10/10 we use the new callbacks in drivers that can implement it.
[1] https://patchwork.kernel.org/patch/9702233/ [2] https://lists.freedesktop.org/archives/dri-devel/2017-May/141761.html
Jose Abreu (10): drm: Add drm_{crtc/encoder/connector}_mode_valid() drm: Introduce drm_bridge_mode_valid() drm: Use new mode_valid() helpers in connector probe helper drm: Use mode_valid() in atomic modeset drm: arc: Use crtc->mode_valid() callback drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback drm/arm: malidp: Use crtc->mode_valid() callback drm/atmel-hlcdc: Use crtc->mode_valid() callback drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks
Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com
drivers/gpu/drm/arc/arcpgu_crtc.c | 29 ++++--- drivers/gpu/drm/arm/malidp_crtc.c | 11 ++- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 9 +-- drivers/gpu/drm/bridge/analogix-anx78xx.c | 13 ++- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 40 +++------- drivers/gpu/drm/drm_atomic_helper.c | 76 +++++++++++++++++- drivers/gpu/drm/drm_bridge.c | 33 ++++++++ drivers/gpu/drm/drm_crtc_helper_internal.h | 13 +++ drivers/gpu/drm/drm_probe_helper.c | 105 ++++++++++++++++++++++++- drivers/gpu/drm/imx/dw_hdmi-imx.c | 4 +- drivers/gpu/drm/meson/meson_dw_hdmi.c | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- drivers/gpu/drm/vc4/vc4_crtc.c | 13 ++- drivers/gpu/drm/vc4/vc4_dpi.c | 13 ++- include/drm/bridge/dw_hdmi.h | 2 +- include/drm/drm_bridge.h | 2 + 16 files changed, 280 insertions(+), 87 deletions(-)
Add a new helper to call crtc->mode_valid, connector->mode_valid and encoder->mode_valid callbacks.
Suggested-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Jose Abreu joabreu@synopsys.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Reviewed-by: Andrzej Hajda a.hajda@samsung.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/drm_crtc_helper_internal.h | 13 ++++++++++ drivers/gpu/drm/drm_probe_helper.c | 38 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+)
diff --git a/drivers/gpu/drm/drm_crtc_helper_internal.h b/drivers/gpu/drm/drm_crtc_helper_internal.h index 28295e5..97dfe20 100644 --- a/drivers/gpu/drm/drm_crtc_helper_internal.h +++ b/drivers/gpu/drm/drm_crtc_helper_internal.h @@ -26,7 +26,11 @@ * implementation details and are not exported to drivers. */
+#include <drm/drm_connector.h> +#include <drm/drm_crtc.h> #include <drm/drm_dp_helper.h> +#include <drm/drm_encoder.h> +#include <drm/drm_modes.h>
/* drm_fb_helper.c */ #ifdef CONFIG_DRM_FBDEV_EMULATION @@ -62,4 +66,13 @@ static inline int drm_dp_aux_register_devnode(struct drm_dp_aux *aux) static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux) { } + +/* drm_probe_helper.c */ +enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode); +enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder, + const struct drm_display_mode *mode); +enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode); + #endif diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 1b0c14a..f01abdc 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -38,6 +38,9 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> #include <drm/drm_edid.h> +#include <drm/drm_modeset_helper_vtables.h> + +#include "drm_crtc_helper_internal.h"
/** * DOC: output probing helper overview @@ -113,6 +116,41 @@ static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector) return 1; }
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) +{ + const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + + if (!crtc_funcs || !crtc_funcs->mode_valid) + return MODE_OK; + + return crtc_funcs->mode_valid(crtc, mode); +} + +enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder, + const struct drm_display_mode *mode) +{ + const struct drm_encoder_helper_funcs *encoder_funcs = + encoder->helper_private; + + if (!encoder_funcs || !encoder_funcs->mode_valid) + return MODE_OK; + + return encoder_funcs->mode_valid(encoder, mode); +} + +enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + const struct drm_connector_helper_funcs *connector_funcs = + connector->helper_private; + + if (!connector_funcs || !connector_funcs->mode_valid) + return MODE_OK; + + return connector_funcs->mode_valid(connector, mode); +} + #define DRM_OUTPUT_POLL_PERIOD (10*HZ) /** * drm_kms_helper_poll_enable - re-enable output polling.
Introduce a new helper function which calls mode_valid() callback for all bridges in an encoder chain.
Signed-off-by: Jose Abreu joabreu@synopsys.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++ include/drm/drm_bridge.h | 2 ++ 2 files changed, 35 insertions(+)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 86a7637..dc8cdfe 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge, EXPORT_SYMBOL(drm_bridge_mode_fixup);
/** + * drm_bridge_mode_valid - validate the mode against all bridges in the + * encoder chain. + * @bridge: bridge control structure + * @mode: desired mode to be validated + * + * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder + * chain, starting from the first bridge to the last. If at least one bridge + * does not accept the mode the function returns the error code. + * + * Note: the bridge passed should be the one closest to the encoder. + * + * RETURNS: + * MODE_OK on success, drm_mode_status Enum error code on failure + */ +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_mode *mode) +{ + enum drm_mode_status ret = MODE_OK; + + if (!bridge) + return ret; + + if (bridge->funcs->mode_valid) + ret = bridge->funcs->mode_valid(bridge, mode); + + if (ret != MODE_OK) + return ret; + + return drm_bridge_mode_valid(bridge->next, mode); +} +EXPORT_SYMBOL(drm_bridge_mode_valid); + +/** * drm_bridge_disable - disables all bridges in the encoder chain * @bridge: bridge control structure * diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 00c6c36..8358eb3 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, bool drm_bridge_mode_fixup(struct drm_bridge *bridge, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_mode *mode); void drm_bridge_disable(struct drm_bridge *bridge); void drm_bridge_post_disable(struct drm_bridge *bridge); void drm_bridge_mode_set(struct drm_bridge *bridge,
This changes the connector probe helper function to use the new encoder->mode_valid(), bridge->mode_valid() and crtc->mode_valid() helper callbacks to validate the modes.
The new callbacks are optional so the behaviour remains the same if they are not implemented. If they are, then the code loops through all the connector's encodersXbridgesXcrtcs and calls the callback.
If at least a valid encoderXbridgeXcrtc combination is found which accepts the mode then the function returns MODE_OK.
Signed-off-by: Jose Abreu joabreu@synopsys.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/drm_probe_helper.c | 67 +++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index f01abdc..00e6832 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -83,6 +83,61 @@ return MODE_OK; }
+static enum drm_mode_status +drm_mode_validate_pipeline(struct drm_display_mode *mode, + struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + uint32_t *ids = connector->encoder_ids; + enum drm_mode_status ret = MODE_OK; + unsigned int i; + + /* Step 1: Validate against connector */ + ret = drm_connector_mode_valid(connector, mode); + if (ret != MODE_OK) + return ret; + + /* Step 2: Validate against encoders and crtcs */ + for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { + struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]); + struct drm_crtc *crtc; + + if (!encoder) + continue; + + ret = drm_encoder_mode_valid(encoder, mode); + if (ret != MODE_OK) { + /* No point in continuing for crtc check as this encoder + * will not accept the mode anyway. If all encoders + * reject the mode then, at exit, ret will not be + * MODE_OK. */ + continue; + } + + ret = drm_bridge_mode_valid(encoder->bridge, mode); + if (ret != MODE_OK) { + /* There is also no point in continuing for crtc check + * here. */ + continue; + } + + drm_for_each_crtc(crtc, dev) { + if (!drm_encoder_crtc_ok(encoder, crtc)) + continue; + + ret = drm_crtc_mode_valid(crtc, mode); + if (ret == MODE_OK) { + /* If we get to this point there is at least + * one combination of encoder+crtc that works + * for this mode. Lets return now. */ + return ret; + } + } + } + + return ret; +} + static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector) { struct drm_cmdline_mode *cmdline_mode; @@ -322,7 +377,11 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) * - drm_mode_validate_flag() checks the modes against basic connector * capabilities (interlace_allowed,doublescan_allowed,stereo_allowed) * - the optional &drm_connector_helper_funcs.mode_valid helper can perform - * driver and/or hardware specific checks + * driver and/or sink specific checks + * - the optional &drm_crtc_helper_funcs.mode_valid, + * &drm_bridge_funcs.mode_valid and &drm_encoder_helper_funcs.mode_valid + * helpers can perform driver and/or source specific checks which are also + * enforced by the modeset/atomic helpers * * 5. Any mode whose status is not OK is pruned from the connector's modes list, * accompanied by a debug message indicating the reason for the mode's @@ -466,9 +525,9 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, if (mode->status == MODE_OK) mode->status = drm_mode_validate_flag(mode, mode_flags);
- if (mode->status == MODE_OK && connector_funcs->mode_valid) - mode->status = connector_funcs->mode_valid(connector, - mode); + if (mode->status == MODE_OK) + mode->status = drm_mode_validate_pipeline(mode, + connector); }
prune:
On Fri, May 19, 2017 at 01:52:12AM +0100, Jose Abreu wrote:
This changes the connector probe helper function to use the new encoder->mode_valid(), bridge->mode_valid() and crtc->mode_valid() helper callbacks to validate the modes.
The new callbacks are optional so the behaviour remains the same if they are not implemented. If they are, then the code loops through all the connector's encodersXbridgesXcrtcs and calls the callback.
If at least a valid encoderXbridgeXcrtc combination is found which accepts the mode then the function returns MODE_OK.
Signed-off-by: Jose Abreu joabreu@synopsys.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com
You've lost the per-patch changelog here, which is pretty easy to accidentally do if you keep it below the ---. That's one of the reasons why in drm we prefer the per-patch changelog to be part of the commit itself.
Anyway I have no opinion on the bikshed discussion itself (it's a static inline helper ffs, it doesn't really matter), and that bikeshed is the last open I could distill from the previous submissions:
Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/drm_probe_helper.c | 67 +++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index f01abdc..00e6832 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -83,6 +83,61 @@ return MODE_OK; }
+static enum drm_mode_status +drm_mode_validate_pipeline(struct drm_display_mode *mode,
struct drm_connector *connector)
+{
- struct drm_device *dev = connector->dev;
- uint32_t *ids = connector->encoder_ids;
- enum drm_mode_status ret = MODE_OK;
- unsigned int i;
- /* Step 1: Validate against connector */
- ret = drm_connector_mode_valid(connector, mode);
- if (ret != MODE_OK)
return ret;
- /* Step 2: Validate against encoders and crtcs */
- for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
struct drm_crtc *crtc;
if (!encoder)
continue;
ret = drm_encoder_mode_valid(encoder, mode);
if (ret != MODE_OK) {
/* No point in continuing for crtc check as this encoder
* will not accept the mode anyway. If all encoders
* reject the mode then, at exit, ret will not be
* MODE_OK. */
continue;
}
ret = drm_bridge_mode_valid(encoder->bridge, mode);
if (ret != MODE_OK) {
/* There is also no point in continuing for crtc check
* here. */
continue;
}
drm_for_each_crtc(crtc, dev) {
if (!drm_encoder_crtc_ok(encoder, crtc))
continue;
ret = drm_crtc_mode_valid(crtc, mode);
if (ret == MODE_OK) {
/* If we get to this point there is at least
* one combination of encoder+crtc that works
* for this mode. Lets return now. */
return ret;
}
}
- }
- return ret;
+}
static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector) { struct drm_cmdline_mode *cmdline_mode; @@ -322,7 +377,11 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
- drm_mode_validate_flag() checks the modes against basic connector
capabilities (interlace_allowed,doublescan_allowed,stereo_allowed)
- the optional &drm_connector_helper_funcs.mode_valid helper can perform
driver and/or hardware specific checks
driver and/or sink specific checks
- the optional &drm_crtc_helper_funcs.mode_valid,
&drm_bridge_funcs.mode_valid and &drm_encoder_helper_funcs.mode_valid
helpers can perform driver and/or source specific checks which are also
enforced by the modeset/atomic helpers
- Any mode whose status is not OK is pruned from the connector's modes list,
- accompanied by a debug message indicating the reason for the mode's
@@ -466,9 +525,9 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, if (mode->status == MODE_OK) mode->status = drm_mode_validate_flag(mode, mode_flags);
if (mode->status == MODE_OK && connector_funcs->mode_valid)
mode->status = connector_funcs->mode_valid(connector,
mode);
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_pipeline(mode,
}connector);
prune:
1.9.1
This patches makes use of the new mode_valid() callbacks introduced previously to validate the full video pipeline when modesetting.
This calls the connector->mode_valid(), encoder->mode_valid(), bridge->mode_valid() and crtc->mode_valid() so that we can make sure that the mode will be accepted in every components.
Signed-off-by: Jose Abreu joabreu@synopsys.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Reviewed-by: Andrzej Hajda a.hajda@samsung.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/drm_atomic_helper.c | 76 +++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 8be9719..5a3c458 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -32,6 +32,7 @@ #include <drm/drm_atomic_helper.h> #include <linux/dma-fence.h>
+#include "drm_crtc_helper_internal.h" #include "drm_crtc_internal.h"
/** @@ -452,6 +453,69 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, return 0; }
+static enum drm_mode_status mode_valid_path(struct drm_connector *connector, + struct drm_encoder *encoder, + struct drm_crtc *crtc, + struct drm_display_mode *mode) +{ + enum drm_mode_status ret; + + ret = drm_encoder_mode_valid(encoder, mode); + if (ret != MODE_OK) { + DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] mode_valid() failed\n", + encoder->base.id, encoder->name); + return ret; + } + + ret = drm_bridge_mode_valid(encoder->bridge, mode); + if (ret != MODE_OK) { + DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n"); + return ret; + } + + ret = drm_crtc_mode_valid(crtc, mode); + if (ret != MODE_OK) { + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode_valid() failed\n", + crtc->base.id, crtc->name); + return ret; + } + + return ret; +} + +static int +mode_valid(struct drm_atomic_state *state) +{ + struct drm_connector_state *conn_state; + struct drm_connector *connector; + int i; + + for_each_new_connector_in_state(state, connector, conn_state, i) { + struct drm_encoder *encoder = conn_state->best_encoder; + struct drm_crtc *crtc = conn_state->crtc; + struct drm_crtc_state *crtc_state; + enum drm_mode_status mode_status; + struct drm_display_mode *mode; + + if (!crtc || !encoder) + continue; + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + if (!crtc_state) + continue; + if (!crtc_state->mode_changed && !crtc_state->connectors_changed) + continue; + + mode = &crtc_state->mode; + + mode_status = mode_valid_path(connector, encoder, crtc, mode); + if (mode_status != MODE_OK) + return -EINVAL; + } + + return 0; +} + /** * drm_atomic_helper_check_modeset - validate state object for modeset changes * @dev: DRM device @@ -466,13 +530,15 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, * 2. &drm_connector_helper_funcs.atomic_check to validate the connector state. * 3. If it's determined a modeset is needed then all connectors on the affected crtc * crtc are added and &drm_connector_helper_funcs.atomic_check is run on them. - * 4. &drm_bridge_funcs.mode_fixup is called on all encoder bridges. - * 5. &drm_encoder_helper_funcs.atomic_check is called to validate any encoder state. + * 4. &drm_encoder_helper_funcs.mode_valid, &drm_bridge_funcs.mode_valid and + * &drm_crtc_helper_funcs.mode_valid are called on the affected components. + * 5. &drm_bridge_funcs.mode_fixup is called on all encoder bridges. + * 6. &drm_encoder_helper_funcs.atomic_check is called to validate any encoder state. * This function is only called when the encoder will be part of a configured crtc, * it must not be used for implementing connector property validation. * If this function is NULL, &drm_atomic_encoder_helper_funcs.mode_fixup is called * instead. - * 6. &drm_crtc_helper_funcs.mode_fixup is called last, to fix up the mode with crtc constraints. + * 7. &drm_crtc_helper_funcs.mode_fixup is called last, to fix up the mode with crtc constraints. * * &drm_crtc_state.mode_changed is set when the input mode is changed. * &drm_crtc_state.connectors_changed is set when a connector is added or @@ -617,6 +683,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, return ret; }
+ ret = mode_valid(state); + if (ret) + return ret; + return mode_fixup(state); } EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
Now that we have a callback to check if crtc supports a given mode we can use it in arcpgu so that we restrict the number of probbed modes to the ones we can actually display.
This is specially useful because arcpgu crtc is responsible to set a clock value in the commit() stage but unfortunatelly this clock does not support all the needed ranges.
Also, remove the atomic_check() callback as mode_valid() callback will be called before.
Signed-off-by: Jose Abreu joabreu@synopsys.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/arc/arcpgu_crtc.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index ad9a959..99fbdae 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -64,6 +64,19 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc) .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, };
+enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) +{ + struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc); + long rate, clk_rate = mode->clock * 1000; + + rate = clk_round_rate(arcpgu->clk, clk_rate); + if (rate != clk_rate) + return MODE_NOCLOCK; + + return MODE_OK; +} + static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc); @@ -129,20 +142,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc) ~ARCPGU_CTRL_ENABLE_MASK); }
-static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc, - struct drm_crtc_state *state) -{ - struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc); - struct drm_display_mode *mode = &state->adjusted_mode; - long rate, clk_rate = mode->clock * 1000; - - rate = clk_round_rate(arcpgu->clk, clk_rate); - if (rate != clk_rate) - return -EINVAL; - - return 0; -} - static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -158,6 +157,7 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc, }
static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = { + .mode_valid = arc_pgu_crtc_mode_valid, .mode_set = drm_helper_crtc_mode_set, .mode_set_base = drm_helper_crtc_mode_set_base, .mode_set_nofb = arc_pgu_crtc_mode_set_nofb, @@ -165,7 +165,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc, .disable = arc_pgu_crtc_disable, .prepare = arc_pgu_crtc_disable, .commit = arc_pgu_crtc_enable, - .atomic_check = arc_pgu_crtc_atomic_check, .atomic_begin = arc_pgu_crtc_atomic_begin, };
Hi Jose,
The only nitpicking note from my side is patch name.
Probably full driver name as "arcpgu" might give a bit more context especially if later something else from ARC appears in "drm" folder. But IMHO that doesn't worth another respin.
On Fri, 2017-05-19 at 01:52 +0100, Jose Abreu wrote:
Now that we have a callback to check if crtc supports a given mode we can use it in arcpgu so that we restrict the number of probbed modes to the ones we can actually display.
This is specially useful because arcpgu crtc is responsible to set a clock value in the commit() stage but unfortunatelly this clock does not support all the needed ranges.
Also, remove the atomic_check() callback as mode_valid() callback will be called before.
Signed-off-by: Jose Abreu joabreu@synopsys.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com
Reviewed-by: Alexey Brodkin abrodkin@synopsys.com
Now that we have a callback to check if bridge supports a given mode we can use it in Analogix bridge so that we restrict the number of probbed modes to the ones we can actually display.
Also, there is no need to use mode_fixup() callback as mode_valid() will handle the mode validation.
NOTE: Only compile tested.
Signed-off-by: Jose Abreu joabreu@synopsys.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/bridge/analogix-anx78xx.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c index a2a8236..cf69a1c 100644 --- a/drivers/gpu/drm/bridge/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c @@ -1061,18 +1061,17 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge) return 0; }
-static bool anx78xx_bridge_mode_fixup(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +enum drm_mode_status anx78xx_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_mode *mode) { if (mode->flags & DRM_MODE_FLAG_INTERLACE) - return false; + return MODE_NO_INTERLACE;
/* Max 1200p at 5.4 Ghz, one lane */ if (mode->clock > 154000) - return false; + return MODE_CLOCK_HIGH;
- return true; + return MODE_OK; }
static void anx78xx_bridge_disable(struct drm_bridge *bridge) @@ -1129,7 +1128,7 @@ static void anx78xx_bridge_enable(struct drm_bridge *bridge)
static const struct drm_bridge_funcs anx78xx_bridge_funcs = { .attach = anx78xx_bridge_attach, - .mode_fixup = anx78xx_bridge_mode_fixup, + .mode_valid = anx78xx_bridge_mode_valid, .disable = anx78xx_bridge_disable, .mode_set = anx78xx_bridge_mode_set, .enable = anx78xx_bridge_enable,
Now that we have a callback to check if bridge supports a given mode we can use it in Synopsys Designware HDMI bridge so that we restrict the number of probbed modes to the ones we can actually display.
Also, there is no need to use mode_fixup() callback as mode_valid() will handle the mode validation.
NOTE: Only compile tested NOTE 2: I also had to change the pdata declaration of mode_valid custom callback so that the passed modes are const. I also changed in the platforms I found. Not even compiled it though.
Signed-off-by: Jose Abreu joabreu@synopsys.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 40 +++++++++-------------------- drivers/gpu/drm/imx/dw_hdmi-imx.c | 4 +-- drivers/gpu/drm/meson/meson_dw_hdmi.c | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- include/drm/bridge/dw_hdmi.h | 2 +- 5 files changed, 17 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 4e1f54a..864e946 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1881,24 +1881,6 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) return ret; }
-static enum drm_mode_status -dw_hdmi_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct dw_hdmi *hdmi = container_of(connector, - struct dw_hdmi, connector); - enum drm_mode_status mode_status = MODE_OK; - - /* We don't support double-clocked modes */ - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - return MODE_BAD; - - if (hdmi->plat_data->mode_valid) - mode_status = hdmi->plat_data->mode_valid(connector, mode); - - return mode_status; -} - static void dw_hdmi_connector_force(struct drm_connector *connector) { struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, @@ -1924,7 +1906,6 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = { .get_modes = dw_hdmi_connector_get_modes, - .mode_valid = dw_hdmi_connector_mode_valid, .best_encoder = drm_atomic_helper_best_encoder, };
@@ -1947,18 +1928,21 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) return 0; }
-static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge, - const struct drm_display_mode *orig_mode, - struct drm_display_mode *mode) +static enum drm_mode_status dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_mode *mode) { struct dw_hdmi *hdmi = bridge->driver_private; struct drm_connector *connector = &hdmi->connector; - enum drm_mode_status status; + enum drm_mode_status mode_status = MODE_OK;
- status = dw_hdmi_connector_mode_valid(connector, mode); - if (status != MODE_OK) - return false; - return true; + /* We don't support double-clocked modes */ + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + return MODE_BAD; + + if (hdmi->plat_data->mode_valid) + mode_status = hdmi->plat_data->mode_valid(connector, mode); + + return mode_status; }
static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, @@ -2002,7 +1986,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) .enable = dw_hdmi_bridge_enable, .disable = dw_hdmi_bridge_disable, .mode_set = dw_hdmi_bridge_mode_set, - .mode_fixup = dw_hdmi_bridge_mode_fixup, + .mode_valid = dw_hdmi_bridge_mode_valid, };
static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi) diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index f039641..5f561c8 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -148,7 +148,7 @@ static int dw_hdmi_imx_atomic_check(struct drm_encoder *encoder, };
static enum drm_mode_status imx6q_hdmi_mode_valid(struct drm_connector *con, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { if (mode->clock < 13500) return MODE_CLOCK_LOW; @@ -160,7 +160,7 @@ static enum drm_mode_status imx6q_hdmi_mode_valid(struct drm_connector *con, }
static enum drm_mode_status imx6dl_hdmi_mode_valid(struct drm_connector *con, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { if (mode->clock < 13500) return MODE_CLOCK_LOW; diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 7b86eb7..f043904 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -537,7 +537,7 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
/* TOFIX Enable support for non-vic modes */ static enum drm_mode_status dw_hdmi_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { unsigned int vclk_freq; unsigned int venc_freq; diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 63dab6f..f820848 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -155,7 +155,7 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
static enum drm_mode_status dw_hdmi_rockchip_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) + const struct drm_display_mode *mode) { const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg; int pclk = mode->clock * 1000; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index ed599be..4c8d4c8 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -125,7 +125,7 @@ struct dw_hdmi_phy_ops { struct dw_hdmi_plat_data { struct regmap *regm; enum drm_mode_status (*mode_valid)(struct drm_connector *connector, - struct drm_display_mode *mode); + const struct drm_display_mode *mode); unsigned long input_bus_format; unsigned long input_bus_encoding;
Hi Jose,
On 05/19/2017 02:52 AM, Jose Abreu wrote:
Now that we have a callback to check if bridge supports a given mode we can use it in Synopsys Designware HDMI bridge so that we restrict the number of probbed modes to the ones we can actually display.
Also, there is no need to use mode_fixup() callback as mode_valid() will handle the mode validation.
NOTE: Only compile tested NOTE 2: I also had to change the pdata declaration of mode_valid custom callback so that the passed modes are const. I also changed in the platforms I found. Not even compiled it though.
Signed-off-by: Jose Abreu joabreu@synopsys.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 40 +++++++++-------------------- drivers/gpu/drm/imx/dw_hdmi-imx.c | 4 +-- drivers/gpu/drm/meson/meson_dw_hdmi.c | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- include/drm/bridge/dw_hdmi.h | 2 +- 5 files changed, 17 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 4e1f54a..864e946 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1881,24 +1881,6 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) return ret; }
-static enum drm_mode_status -dw_hdmi_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
-{
- struct dw_hdmi *hdmi = container_of(connector,
struct dw_hdmi, connector);
- enum drm_mode_status mode_status = MODE_OK;
- /* We don't support double-clocked modes */
- if (mode->flags & DRM_MODE_FLAG_DBLCLK)
return MODE_BAD;
- if (hdmi->plat_data->mode_valid)
mode_status = hdmi->plat_data->mode_valid(connector, mode);
- return mode_status;
-}
static void dw_hdmi_connector_force(struct drm_connector *connector) { struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, @@ -1924,7 +1906,6 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = { .get_modes = dw_hdmi_connector_get_modes,
- .mode_valid = dw_hdmi_connector_mode_valid, .best_encoder = drm_atomic_helper_best_encoder,
};
@@ -1947,18 +1928,21 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) return 0; }
-static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *orig_mode,
struct drm_display_mode *mode)
+static enum drm_mode_status dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_mode *mode)
{ struct dw_hdmi *hdmi = bridge->driver_private; struct drm_connector *connector = &hdmi->connector;
- enum drm_mode_status status;
- enum drm_mode_status mode_status = MODE_OK;
- status = dw_hdmi_connector_mode_valid(connector, mode);
- if (status != MODE_OK)
return false;
- return true;
- /* We don't support double-clocked modes */
- if (mode->flags & DRM_MODE_FLAG_DBLCLK)
return MODE_BAD;
- if (hdmi->plat_data->mode_valid)
mode_status = hdmi->plat_data->mode_valid(connector, mode);
- return mode_status;
}
static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, @@ -2002,7 +1986,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) .enable = dw_hdmi_bridge_enable, .disable = dw_hdmi_bridge_disable, .mode_set = dw_hdmi_bridge_mode_set,
- .mode_fixup = dw_hdmi_bridge_mode_fixup,
- .mode_valid = dw_hdmi_bridge_mode_valid,
};
static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi) diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index f039641..5f561c8 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -148,7 +148,7 @@ static int dw_hdmi_imx_atomic_check(struct drm_encoder *encoder, };
static enum drm_mode_status imx6q_hdmi_mode_valid(struct drm_connector *con,
struct drm_display_mode *mode)
const struct drm_display_mode *mode)
{ if (mode->clock < 13500) return MODE_CLOCK_LOW; @@ -160,7 +160,7 @@ static enum drm_mode_status imx6q_hdmi_mode_valid(struct drm_connector *con, }
static enum drm_mode_status imx6dl_hdmi_mode_valid(struct drm_connector *con,
struct drm_display_mode *mode)
const struct drm_display_mode *mode)
{ if (mode->clock < 13500) return MODE_CLOCK_LOW; diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index 7b86eb7..f043904 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -537,7 +537,7 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
/* TOFIX Enable support for non-vic modes */ static enum drm_mode_status dw_hdmi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
const struct drm_display_mode *mode)
{ unsigned int vclk_freq; unsigned int venc_freq;
For the meson/meson_dw_hdmi.c file :
Acked-by: Neil Armstrong narmstrong@baylibre.com
I can have a try in meson if you have a tree I can pull the full patchset from.
Neil
Now that we have a callback to check if crtc supports a given mode we can use it in malidp so that we restrict the number of probbed modes to the ones we can actually display.
Also, remove the mode_fixup() callback as this is no longer needed because mode_valid() will be called before.
NOTE: Not even compiled tested
Signed-off-by: Jose Abreu joabreu@synopsys.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/arm/malidp_crtc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 9446a67..4bb38a2 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -22,9 +22,8 @@ #include "malidp_drv.h" #include "malidp_hw.h"
-static bool malidp_crtc_mode_fixup(struct drm_crtc *crtc, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +static enum drm_mode_status malidp_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) { struct malidp_drm *malidp = crtc_to_malidp_device(crtc); struct malidp_hw_device *hwdev = malidp->dev; @@ -40,11 +39,11 @@ static bool malidp_crtc_mode_fixup(struct drm_crtc *crtc, if (rate != req_rate) { DRM_DEBUG_DRIVER("pxlclk doesn't support %ld Hz\n", req_rate); - return false; + return MODE_NOCLOCK; } }
- return true; + return MODE_OK; }
static void malidp_crtc_enable(struct drm_crtc *crtc) @@ -408,7 +407,7 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc, }
static const struct drm_crtc_helper_funcs malidp_crtc_helper_funcs = { - .mode_fixup = malidp_crtc_mode_fixup, + .mode_valid = malidp_crtc_mode_valid, .enable = malidp_crtc_enable, .disable = malidp_crtc_disable, .atomic_check = malidp_crtc_atomic_check,
Now that we have a callback to check if crtc supports a given mode we can use it in atmel-hlcdc so that we restrict the number of probbed modes to the ones we can actually display.
Also, remove the mode_fixup() callback as this is no longer needed because mode_valid() will be called before.
NOTE: Not even compiled tested
Signed-off-by: Jose Abreu joabreu@synopsys.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index 53bfa56..bdfe74e 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -140,13 +140,12 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c) cfg); }
-static bool atmel_hlcdc_crtc_mode_fixup(struct drm_crtc *c, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +static enum drm_mode_status atmel_hlcdc_crtc_mode_valid(struct drm_crtc *c, + const struct drm_display_mode *mode) { struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
- return atmel_hlcdc_dc_mode_valid(crtc->dc, adjusted_mode) == MODE_OK; + return atmel_hlcdc_dc_mode_valid(crtc->dc, mode); }
static void atmel_hlcdc_crtc_disable(struct drm_crtc *c) @@ -315,7 +314,7 @@ static void atmel_hlcdc_crtc_atomic_flush(struct drm_crtc *crtc, }
static const struct drm_crtc_helper_funcs lcdc_crtc_helper_funcs = { - .mode_fixup = atmel_hlcdc_crtc_mode_fixup, + .mode_valid = atmel_hlcdc_crtc_mode_valid, .mode_set = drm_helper_crtc_mode_set, .mode_set_nofb = atmel_hlcdc_crtc_mode_set_nofb, .mode_set_base = drm_helper_crtc_mode_set_base,
Now that we have a callback to check if crtc and encoder supports a given mode we can use it in vc4 so that we restrict the number of probbed modes to the ones we can actually display.
Also, remove the mode_fixup() calls as these are no longer needed because mode_valid() will be called before.
NOTE: Not even compiled tested
Signed-off-by: Jose Abreu joabreu@synopsys.com Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com --- drivers/gpu/drm/vc4/vc4_crtc.c | 13 ++++++------- drivers/gpu/drm/vc4/vc4_dpi.c | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index d86c8cc..aae8c56 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -556,18 +556,17 @@ static void vc4_crtc_enable(struct drm_crtc *crtc) drm_crtc_vblank_on(crtc); }
-static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) { /* Do not allow doublescan modes from user space */ - if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) { + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n", crtc->base.id); - return false; + return MODE_NO_DBLESCAN; }
- return true; + return MODE_OK; }
static int vc4_crtc_atomic_check(struct drm_crtc *crtc, @@ -877,7 +876,7 @@ static void vc4_crtc_destroy_state(struct drm_crtc *crtc, .mode_set_nofb = vc4_crtc_mode_set_nofb, .disable = vc4_crtc_disable, .enable = vc4_crtc_enable, - .mode_fixup = vc4_crtc_mode_fixup, + .mode_valid = vc4_crtc_mode_valid, .atomic_check = vc4_crtc_atomic_check, .atomic_flush = vc4_crtc_atomic_flush, }; diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c index c6d7039..61958ab 100644 --- a/drivers/gpu/drm/vc4/vc4_dpi.c +++ b/drivers/gpu/drm/vc4/vc4_dpi.c @@ -330,20 +330,19 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) } }
-static bool vc4_dpi_encoder_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +static enum drm_mode_status vc4_dpi_encoder_mode_valid(struct drm_encoder *encoder, + const struct drm_display_mode *mode) { - if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) - return false; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + return MODE_NO_INTERLACE;
- return true; + return MODE_OK; }
static const struct drm_encoder_helper_funcs vc4_dpi_encoder_helper_funcs = { .disable = vc4_dpi_encoder_disable, .enable = vc4_dpi_encoder_enable, - .mode_fixup = vc4_dpi_encoder_mode_fixup, + .mode_valid = vc4_dpi_encoder_mode_valid, };
static const struct of_device_id vc4_dpi_dt_match[] = {
On Fri, May 19, 2017 at 01:52:09AM +0100, Jose Abreu wrote:
This series is a follow up from the discussion at [1]. We start by introducing crtc->mode_valid(), encoder->mode_valid() and bridge->mode_valid() callbacks which will be used in followup patches and also by cleaning the documentation a little bit. This patch is available at [2] and the series depends on it.
We proceed by introducing new helpers to call this new callbacks at 1/10.
At 2/10 a helper function is introduced that calls all mode_valid() from a set of bridges.
Next, at 3/10 we modify the connector probe helper so that only modes which are supported by a given bridge+encoder+crtc combination are probbed.
At 4/10 we call all the mode_valid() callbacks for a given pipeline, except the connector->mode_valid one, so that the mode is validated. This is done before calling mode_fixup().
Finally, from 5/10 to 10/10 we use the new callbacks in drivers that can implement it.
[1] https://patchwork.kernel.org/patch/9702233/ [2] https://lists.freedesktop.org/archives/dri-devel/2017-May/141761.html
Jose Abreu (10): drm: Add drm_{crtc/encoder/connector}_mode_valid() drm: Introduce drm_bridge_mode_valid() drm: Use new mode_valid() helpers in connector probe helper drm: Use mode_valid() in atomic modeset drm: arc: Use crtc->mode_valid() callback drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback drm/arm: malidp: Use crtc->mode_valid() callback drm/atmel-hlcdc: Use crtc->mode_valid() callback drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks
Looks all real nice, I think a bit more time to get acks/reviews/tested-by for the driver conversions and I'll go and vacuum this all up.
Thanks a lot for doing this. -Daniel
Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com
drivers/gpu/drm/arc/arcpgu_crtc.c | 29 ++++--- drivers/gpu/drm/arm/malidp_crtc.c | 11 ++- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 9 +-- drivers/gpu/drm/bridge/analogix-anx78xx.c | 13 ++- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 40 +++------- drivers/gpu/drm/drm_atomic_helper.c | 76 +++++++++++++++++- drivers/gpu/drm/drm_bridge.c | 33 ++++++++ drivers/gpu/drm/drm_crtc_helper_internal.h | 13 +++ drivers/gpu/drm/drm_probe_helper.c | 105 ++++++++++++++++++++++++- drivers/gpu/drm/imx/dw_hdmi-imx.c | 4 +- drivers/gpu/drm/meson/meson_dw_hdmi.c | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- drivers/gpu/drm/vc4/vc4_crtc.c | 13 ++- drivers/gpu/drm/vc4/vc4_dpi.c | 13 ++- include/drm/bridge/dw_hdmi.h | 2 +- include/drm/drm_bridge.h | 2 + 16 files changed, 280 insertions(+), 87 deletions(-)
-- 1.9.1
Hi Daniel,
On 22-05-2017 08:56, Daniel Vetter wrote:
On Fri, May 19, 2017 at 01:52:09AM +0100, Jose Abreu wrote:
This series is a follow up from the discussion at [1]. We start by introducing crtc->mode_valid(), encoder->mode_valid() and bridge->mode_valid() callbacks which will be used in followup patches and also by cleaning the documentation a little bit. This patch is available at [2] and the series depends on it.
We proceed by introducing new helpers to call this new callbacks at 1/10.
At 2/10 a helper function is introduced that calls all mode_valid() from a set of bridges.
Next, at 3/10 we modify the connector probe helper so that only modes which are supported by a given bridge+encoder+crtc combination are probbed.
At 4/10 we call all the mode_valid() callbacks for a given pipeline, except the connector->mode_valid one, so that the mode is validated. This is done before calling mode_fixup().
Finally, from 5/10 to 10/10 we use the new callbacks in drivers that can implement it.
[1] https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.kernel.org_pa... [2] https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.freedesktop.org_a...
Jose Abreu (10): drm: Add drm_{crtc/encoder/connector}_mode_valid() drm: Introduce drm_bridge_mode_valid() drm: Use new mode_valid() helpers in connector probe helper drm: Use mode_valid() in atomic modeset drm: arc: Use crtc->mode_valid() callback drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback drm/arm: malidp: Use crtc->mode_valid() callback drm/atmel-hlcdc: Use crtc->mode_valid() callback drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks
Looks all real nice, I think a bit more time to get acks/reviews/tested-by for the driver conversions and I'll go and vacuum this all up.
Yeah, I would really like someone to test these, especially the drivers part.
Thanks a lot for doing this.
No problem :) Thanks!
Best regards, Jose Miguel Abreu
-Daniel
Cc: Carlos Palminha palminha@synopsys.com Cc: Alexey Brodkin abrodkin@synopsys.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Dave Airlie airlied@linux.ie Cc: Andrzej Hajda a.hajda@samsung.com Cc: Archit Taneja architt@codeaurora.org Cc: Laurent Pinchart laurent.pinchart@ideasonboard.com
drivers/gpu/drm/arc/arcpgu_crtc.c | 29 ++++--- drivers/gpu/drm/arm/malidp_crtc.c | 11 ++- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 9 +-- drivers/gpu/drm/bridge/analogix-anx78xx.c | 13 ++- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 40 +++------- drivers/gpu/drm/drm_atomic_helper.c | 76 +++++++++++++++++- drivers/gpu/drm/drm_bridge.c | 33 ++++++++ drivers/gpu/drm/drm_crtc_helper_internal.h | 13 +++ drivers/gpu/drm/drm_probe_helper.c | 105 ++++++++++++++++++++++++- drivers/gpu/drm/imx/dw_hdmi-imx.c | 4 +- drivers/gpu/drm/meson/meson_dw_hdmi.c | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +- drivers/gpu/drm/vc4/vc4_crtc.c | 13 ++- drivers/gpu/drm/vc4/vc4_dpi.c | 13 ++- include/drm/bridge/dw_hdmi.h | 2 +- include/drm/drm_bridge.h | 2 + 16 files changed, 280 insertions(+), 87 deletions(-)
-- 1.9.1
On Mon, May 22, 2017 at 09:56:00AM +0200, Daniel Vetter wrote:
On Fri, May 19, 2017 at 01:52:09AM +0100, Jose Abreu wrote:
This series is a follow up from the discussion at [1]. We start by introducing crtc->mode_valid(), encoder->mode_valid() and bridge->mode_valid() callbacks which will be used in followup patches and also by cleaning the documentation a little bit. This patch is available at [2] and the series depends on it.
We proceed by introducing new helpers to call this new callbacks at 1/10.
At 2/10 a helper function is introduced that calls all mode_valid() from a set of bridges.
Next, at 3/10 we modify the connector probe helper so that only modes which are supported by a given bridge+encoder+crtc combination are probbed.
At 4/10 we call all the mode_valid() callbacks for a given pipeline, except the connector->mode_valid one, so that the mode is validated. This is done before calling mode_fixup().
Finally, from 5/10 to 10/10 we use the new callbacks in drivers that can implement it.
[1] https://patchwork.kernel.org/patch/9702233/ [2] https://lists.freedesktop.org/archives/dri-devel/2017-May/141761.html
Jose Abreu (10): drm: Add drm_{crtc/encoder/connector}_mode_valid() drm: Introduce drm_bridge_mode_valid() drm: Use new mode_valid() helpers in connector probe helper drm: Use mode_valid() in atomic modeset drm: arc: Use crtc->mode_valid() callback drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback drm/arm: malidp: Use crtc->mode_valid() callback drm/atmel-hlcdc: Use crtc->mode_valid() callback drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks
Looks all real nice, I think a bit more time to get acks/reviews/tested-by for the driver conversions and I'll go and vacuum this all up.
On that: You didn't cc driver maintainers on the driver conversion patches (not all are bridge drivers maintainer by Archit&co), without that they might miss it. Please remember to do that (you might need to resend to get their attention), scripts/get_maintainers.pl helps with that.
Thanks, Daniel
Hi Daniel,
On 22-05-2017 16:31, Daniel Vetter wrote:
On Mon, May 22, 2017 at 09:56:00AM +0200, Daniel Vetter wrote:
On Fri, May 19, 2017 at 01:52:09AM +0100, Jose Abreu wrote:
This series is a follow up from the discussion at [1]. We start by introducing crtc->mode_valid(), encoder->mode_valid() and bridge->mode_valid() callbacks which will be used in followup patches and also by cleaning the documentation a little bit. This patch is available at [2] and the series depends on it.
We proceed by introducing new helpers to call this new callbacks at 1/10.
At 2/10 a helper function is introduced that calls all mode_valid() from a set of bridges.
Next, at 3/10 we modify the connector probe helper so that only modes which are supported by a given bridge+encoder+crtc combination are probbed.
At 4/10 we call all the mode_valid() callbacks for a given pipeline, except the connector->mode_valid one, so that the mode is validated. This is done before calling mode_fixup().
Finally, from 5/10 to 10/10 we use the new callbacks in drivers that can implement it.
[1] https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.kernel.org_pa... [2] https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.freedesktop.org_a...
Jose Abreu (10): drm: Add drm_{crtc/encoder/connector}_mode_valid() drm: Introduce drm_bridge_mode_valid() drm: Use new mode_valid() helpers in connector probe helper drm: Use mode_valid() in atomic modeset drm: arc: Use crtc->mode_valid() callback drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback drm/arm: malidp: Use crtc->mode_valid() callback drm/atmel-hlcdc: Use crtc->mode_valid() callback drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks
Looks all real nice, I think a bit more time to get acks/reviews/tested-by for the driver conversions and I'll go and vacuum this all up.
On that: You didn't cc driver maintainers on the driver conversion patches (not all are bridge drivers maintainer by Archit&co), without that they might miss it. Please remember to do that (you might need to resend to get their attention), scripts/get_maintainers.pl helps with that.
Yeah, I'm really sorry about that. I was in a different time zone with all my head messed up with jetlag so I missed this and maybe more :/ Lets wait for some input and I will resend the series if needed.
Thanks!
Best regards, Jose Miguel Abreu
Thanks, Daniel
On Tue, May 23, 2017 at 03:40:24PM +0100, Jose Abreu wrote:
Hi Daniel,
On 22-05-2017 16:31, Daniel Vetter wrote:
On Mon, May 22, 2017 at 09:56:00AM +0200, Daniel Vetter wrote:
On Fri, May 19, 2017 at 01:52:09AM +0100, Jose Abreu wrote:
This series is a follow up from the discussion at [1]. We start by introducing crtc->mode_valid(), encoder->mode_valid() and bridge->mode_valid() callbacks which will be used in followup patches and also by cleaning the documentation a little bit. This patch is available at [2] and the series depends on it.
We proceed by introducing new helpers to call this new callbacks at 1/10.
At 2/10 a helper function is introduced that calls all mode_valid() from a set of bridges.
Next, at 3/10 we modify the connector probe helper so that only modes which are supported by a given bridge+encoder+crtc combination are probbed.
At 4/10 we call all the mode_valid() callbacks for a given pipeline, except the connector->mode_valid one, so that the mode is validated. This is done before calling mode_fixup().
Finally, from 5/10 to 10/10 we use the new callbacks in drivers that can implement it.
[1] https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.kernel.org_pa... [2] https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.freedesktop.org_a...
Jose Abreu (10): drm: Add drm_{crtc/encoder/connector}_mode_valid() drm: Introduce drm_bridge_mode_valid() drm: Use new mode_valid() helpers in connector probe helper drm: Use mode_valid() in atomic modeset drm: arc: Use crtc->mode_valid() callback drm/bridge: analogix-anx78xx: Use bridge->mode_valid() callback drm/bridge/synopsys: dw-hdmi: Use bridge->mode_valid() callback drm/arm: malidp: Use crtc->mode_valid() callback drm/atmel-hlcdc: Use crtc->mode_valid() callback drm: vc4: Use crtc->mode_valid() and encoder->mode_valid() callbacks
Looks all real nice, I think a bit more time to get acks/reviews/tested-by for the driver conversions and I'll go and vacuum this all up.
On that: You didn't cc driver maintainers on the driver conversion patches (not all are bridge drivers maintainer by Archit&co), without that they might miss it. Please remember to do that (you might need to resend to get their attention), scripts/get_maintainers.pl helps with that.
Yeah, I'm really sorry about that. I was in a different time zone with all my head messed up with jetlag so I missed this and maybe more :/ Lets wait for some input and I will resend the series if needed.
No worries. btw I've applied the 3 kernel-doc patches now, that should also make it easier to get the driver patches reviewed (since now they apply directly on linux-next). -Daniel
Thanks!
Best regards, Jose Miguel Abreu
Thanks, Daniel
dri-devel@lists.freedesktop.org