summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_probe_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_probe_helper.c')
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c74
1 files changed, 35 insertions, 39 deletions
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 4f75a1cfd820..09b12c30df69 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -33,7 +33,7 @@
#include <linux/moduleparam.h>
#include <drm/drm_bridge.h>
-#include <drm/drm_client.h>
+#include <drm/drm_client_event.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_fourcc.h>
@@ -119,6 +119,7 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
*status = drm_bridge_chain_mode_valid(bridge,
&connector->display_info,
mode);
+ drm_bridge_put(bridge);
if (*status != MODE_OK) {
/* There is also no point in continuing for crtc check
* here. */
@@ -202,7 +203,7 @@ enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
int
drm_connector_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode,
+ const struct drm_display_mode *mode,
struct drm_modeset_acquire_ctx *ctx,
enum drm_mode_status *status)
{
@@ -338,10 +339,23 @@ void drm_kms_helper_poll_reschedule(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_kms_helper_poll_reschedule);
+static int detect_connector_status(struct drm_connector *connector,
+ struct drm_modeset_acquire_ctx *ctx,
+ bool force)
+{
+ const struct drm_connector_helper_funcs *funcs = connector->helper_private;
+
+ if (funcs->detect_ctx)
+ return funcs->detect_ctx(connector, ctx, force);
+ else if (connector->funcs->detect)
+ return connector->funcs->detect(connector, force);
+
+ return connector_status_connected;
+}
+
static enum drm_connector_status
drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force)
{
- const struct drm_connector_helper_funcs *funcs = connector->helper_private;
struct drm_modeset_acquire_ctx ctx;
int ret;
@@ -349,14 +363,8 @@ drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force)
retry:
ret = drm_modeset_lock(&connector->dev->mode_config.connection_mutex, &ctx);
- if (!ret) {
- if (funcs->detect_ctx)
- ret = funcs->detect_ctx(connector, &ctx, force);
- else if (connector->funcs->detect)
- ret = connector->funcs->detect(connector, force);
- else
- ret = connector_status_connected;
- }
+ if (!ret)
+ ret = detect_connector_status(connector, &ctx, force);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
@@ -390,7 +398,6 @@ drm_helper_probe_detect(struct drm_connector *connector,
struct drm_modeset_acquire_ctx *ctx,
bool force)
{
- const struct drm_connector_helper_funcs *funcs = connector->helper_private;
struct drm_device *dev = connector->dev;
int ret;
@@ -401,12 +408,7 @@ drm_helper_probe_detect(struct drm_connector *connector,
if (ret)
return ret;
- if (funcs->detect_ctx)
- ret = funcs->detect_ctx(connector, ctx, force);
- else if (connector->funcs->detect)
- ret = connector->funcs->detect(connector, force);
- else
- ret = connector_status_connected;
+ ret = detect_connector_status(connector, ctx, force);
if (ret != connector->status)
connector->epoch_counter += 1;
@@ -474,6 +476,10 @@ static int __drm_helper_update_and_validate(struct drm_connector *connector,
if (mode->status != MODE_OK)
continue;
+ mode->status = drm_mode_validate_ycbcr420(mode, connector);
+ if (mode->status != MODE_OK)
+ continue;
+
ret = drm_mode_validate_pipeline(mode, connector, ctx,
&mode->status);
if (ret) {
@@ -486,10 +492,6 @@ static int __drm_helper_update_and_validate(struct drm_connector *connector,
else
return -EDEADLK;
}
-
- if (mode->status != MODE_OK)
- continue;
- mode->status = drm_mode_validate_ycbcr420(mode, connector);
}
return 0;
@@ -714,7 +716,7 @@ EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
* @dev: drm_device whose connector state changed
*
* This function fires off the uevent for userspace and also calls the
- * output_poll_changed function, which is most commonly used to inform the fbdev
+ * client hotplug function, which is most commonly used to inform the fbdev
* emulation code and allow it to update the fbcon output configuration.
*
* Drivers should call this from their hotplug handling code when a change is
@@ -730,11 +732,7 @@ EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
*/
void drm_kms_helper_hotplug_event(struct drm_device *dev)
{
- /* send a uevent + call fbdev */
drm_sysfs_hotplug_event(dev);
- if (dev->mode_config.funcs->output_poll_changed)
- dev->mode_config.funcs->output_poll_changed(dev);
-
drm_client_dev_hotplug(dev);
}
EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
@@ -750,11 +748,7 @@ void drm_kms_helper_connector_hotplug_event(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- /* send a uevent + call fbdev */
drm_sysfs_connector_hotplug_event(connector);
- if (dev->mode_config.funcs->output_poll_changed)
- dev->mode_config.funcs->output_poll_changed(dev);
-
drm_client_dev_hotplug(dev);
}
EXPORT_SYMBOL(drm_kms_helper_connector_hotplug_event);
@@ -888,7 +882,7 @@ EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
* disabled. Polling is re-enabled by calling drm_kms_helper_poll_enable().
*
* If however, the polling was never initialized, this call will trigger a
- * warning and return
+ * warning and return.
*
* Note that calls to enable and disable polling must be strictly ordered, which
* is automatically the case when they're only call from suspend/resume
@@ -965,15 +959,16 @@ static void drm_kms_helper_poll_init_release(struct drm_device *dev, void *res)
* cleaned up when the DRM device goes away.
*
* See drm_kms_helper_poll_init() for more information.
- *
- * Returns:
- * 0 on success, or a negative errno code otherwise.
*/
-int drmm_kms_helper_poll_init(struct drm_device *dev)
+void drmm_kms_helper_poll_init(struct drm_device *dev)
{
+ int ret;
+
drm_kms_helper_poll_init(dev);
- return drmm_add_action_or_reset(dev, drm_kms_helper_poll_init_release, dev);
+ ret = drmm_add_action_or_reset(dev, drm_kms_helper_poll_init_release, dev);
+ if (ret)
+ drm_warn(dev, "Connector status will not be updated, error %d\n", ret);
}
EXPORT_SYMBOL(drmm_kms_helper_poll_init);
@@ -1259,8 +1254,9 @@ int drm_connector_helper_tv_get_modes(struct drm_connector *connector)
for (i = 0; i < tv_mode_property->num_values; i++)
supported_tv_modes |= BIT(tv_mode_property->values[i]);
- if ((supported_tv_modes & ntsc_modes) &&
- (supported_tv_modes & pal_modes)) {
+ if (((supported_tv_modes & ntsc_modes) &&
+ (supported_tv_modes & pal_modes)) ||
+ (supported_tv_modes & BIT(DRM_MODE_TV_MODE_MONOCHROME))) {
uint64_t default_mode;
if (drm_object_property_get_default_value(&connector->base,