[PATCH] drm/fbdev: rework output polling to be back in the core. (v3)

2010-05-06 Thread Dave Airlie
From: Dave Airlie airl...@redhat.com

After thinking it over a lot it made more sense for the core to deal with
the output polling especially so it can notify X.

v2: drop plans for fake connector - per Michel's comments - fix X patch sent to 
xorg-devel, add intel polled/hpd setting, add initial nouveau polled/hpd 
settings.

v3: add config lock take inside polling, add intel/nouveau poll init/fini calls
Signed-off-by: Dave Airlie airl...@redhat.com
---
 drivers/gpu/drm/Kconfig |2 +-
 drivers/gpu/drm/drm_crtc_helper.c   |   93 
 drivers/gpu/drm/drm_fb_helper.c |  123 ---
 drivers/gpu/drm/i915/i915_dma.c |2 +-
 drivers/gpu/drm/i915/i915_irq.c |3 +-
 drivers/gpu/drm/i915/intel_crt.c|5 +
 drivers/gpu/drm/i915/intel_display.c|2 +
 drivers/gpu/drm/i915/intel_dp.c |2 +
 drivers/gpu/drm/i915/intel_drv.h|2 +-
 drivers/gpu/drm/i915/intel_fb.c |   14 ++--
 drivers/gpu/drm/i915/intel_hdmi.c   |1 +
 drivers/gpu/drm/i915/intel_sdvo.c   |2 +
 drivers/gpu/drm/nouveau/nouveau_connector.c |   12 +++
 drivers/gpu/drm/nouveau/nouveau_display.c   |1 +
 drivers/gpu/drm/nouveau/nouveau_fbcon.c |   14 +--
 drivers/gpu/drm/nouveau/nouveau_fbcon.h |2 +-
 drivers/gpu/drm/nouveau/nouveau_state.c |5 +-
 drivers/gpu/drm/nouveau/nv50_display.c  |2 +-
 drivers/gpu/drm/radeon/radeon_connectors.c  |   13 +++
 drivers/gpu/drm/radeon/radeon_display.c |   10 ++
 drivers/gpu/drm/radeon/radeon_fb.c  |   15 +---
 drivers/gpu/drm/radeon/radeon_irq_kms.c |5 +-
 drivers/gpu/drm/radeon/radeon_mode.h|3 +-
 include/drm/drm_crtc.h  |   17 
 include/drm/drm_crtc_helper.h   |3 +
 include/drm/drm_fb_helper.h |   13 +---
 26 files changed, 209 insertions(+), 157 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index be5aa7d..2583ddf 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -9,6 +9,7 @@ menuconfig DRM
depends on (AGP || AGP=n)  PCI  !EMULATED_CMPXCHG  MMU
select I2C
select I2C_ALGOBIT
+   select SLOW_WORK
help
  Kernel-level support for the Direct Rendering Infrastructure (DRI)
  introduced in XFree86 4.0. If you say Y here, you need to select
@@ -23,7 +24,6 @@ config DRM_KMS_HELPER
depends on DRM
select FB
select FRAMEBUFFER_CONSOLE if !EMBEDDED
-   select SLOW_WORK
help
  FB and CRTC helpers for KMS drivers.
 
diff --git a/drivers/gpu/drm/drm_crtc_helper.c 
b/drivers/gpu/drm/drm_crtc_helper.c
index b142ac2..13574b1 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -807,3 +807,96 @@ int drm_helper_resume_force_mode(struct drm_device *dev)
return 0;
 }
 EXPORT_SYMBOL(drm_helper_resume_force_mode);
+
+static struct slow_work_ops output_poll_ops;
+
+#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
+static void output_poll_execute(struct slow_work *work)
+{
+   struct delayed_slow_work *delayed_work = container_of(work, struct 
delayed_slow_work, work);
+   struct drm_device *dev = container_of(delayed_work, struct drm_device, 
mode_config.output_poll_slow_work);
+   struct drm_connector *connector;
+   enum drm_connector_status old_status, status;
+   bool repoll = false, changed = false;
+   int ret;
+
+   mutex_lock(dev-mode_config.mutex);
+   list_for_each_entry(connector, dev-mode_config.connector_list, head) {
+
+   /* if this is HPD or polled don't check it -
+  TV out for instance */
+   if (!connector-polled)
+   continue;
+
+   else if (connector-polled  (DRM_CONNECTOR_POLL_CONNECT | 
DRM_CONNECTOR_POLL_DISCONNECT))
+   repoll = true;
+
+   old_status = connector-status;
+   /* if we are connected and don't want to poll for disconnect
+  skip it */
+   if (old_status == connector_status_connected 
+   !(connector-polled  DRM_CONNECTOR_POLL_DISCONNECT) 
+   !(connector-polled  DRM_CONNECTOR_POLL_HPD))
+   continue;
+
+   status = connector-funcs-detect(connector);
+   if (old_status != status)
+   changed = true;
+   }
+
+   if (changed) {
+   /* 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);
+   }
+
+   mutex_unlock(dev-mode_config.mutex);
+
+   if (repoll) {
+   ret = delayed_slow_work_enqueue(delayed_work, 
DRM_OUTPUT_POLL_PERIOD);
+   if (ret)
+ 

Re: [PATCH 09/14] drm/edid: Add test for monitor reduced blanking support.

2010-05-06 Thread Mark Marshall
Adam Jackson wrote:
 The generic block walk callback looks like overkill, but we'll need it
 for other detailed block walks in the future.
 
 Signed-off-by: Adam Jackson a...@redhat.com
 ---
  drivers/gpu/drm/drm_edid.c |   47 ---
  1 files changed, 43 insertions(+), 4 deletions(-)
 
 diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
 index fb7c2fc..ead57ab 100644
 --- a/drivers/gpu/drm/drm_edid.c
 +++ b/drivers/gpu/drm/drm_edid.c
 @@ -33,6 +33,10 @@
  #include drmP.h
  #include drm_edid.h
  
 +#define EDID_EST_TIMINGS 16
 +#define EDID_STD_TIMINGS 8
 +#define EDID_DETAILED_TIMINGS 4
 +
  /*
   * EDID blocks out in the wild have a variety of bugs, try to collect
   * them here (note that userspace may work around broken monitors first,
 @@ -673,6 +677,45 @@ static struct drm_display_mode *drm_find_dmt(struct 
 drm_device *dev,
   return mode;
  }
  
 +typedef void detailed_cb(struct detailed_timing *timing, void *closure);
 +
 +static void
 +drm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure)
 +{
 + int i;
 + struct edid *edid = (struct edid *)raw_edid;
 +
 + if (edid == NULL)
 + return;
 +
 + for (i = 0; i  EDID_DETAILED_TIMINGS; i++)
 + cb((edid-detailed_timings[i]), closure);
 +
 + /* XXX extension block walk */
 +}
 +
 +static void
 +is_rb(struct detailed_timing *t, void *data)
 +{
 + u8 *r = (u8 *)t;
 + if (r[3] == EDID_DETAIL_MONITOR_RANGE)
 + if (r[15]  0x10)
 + *(bool *)data = true;
 +}
 +
 +/* EDID 1.4 defines this explicitly.  For EDID 1.3, we guess, badly. */
 +static bool
 +drm_monitor_supports_rb(struct edid *edid)
 +{
 + if (edid-revision = 4) {
 + bool ret;

You need to initialize ret here (bool ret = false;).

 + drm_for_each_detailed_block((u8 *)edid, is_rb, ret);
 + return ret;
 + }
 +
 + return ((edid-input  DRM_EDID_INPUT_DIGITAL) != 0);
 +}
 +
  /*
   * 0 is reserved.  The spec says 0x01 fill for unused timings.  Some old
   * monitors fill with ascii space (0x20) instead.
 @@ -964,10 +1007,6 @@ static struct drm_display_mode edid_est_modes[] = {
  DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 
 1152x...@75hz */
  };
  
 -#define EDID_EST_TIMINGS 16
 -#define EDID_STD_TIMINGS 8
 -#define EDID_DETAILED_TIMINGS 4
 -
  /**
   * add_established_modes - get est. modes from EDID and add them
   * @edid: EDID block to scan

MM


--
--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


Re: [PATCH] drm/fbdev: rework output polling to be back in the core. (v3)

2010-05-06 Thread Michel Dänzer
On Don, 2010-05-06 at 16:15 +1000, Dave Airlie wrote: 
 From: Dave Airlie airl...@redhat.com
 
 After thinking it over a lot it made more sense for the core to deal with
 the output polling especially so it can notify X.
 
 v2: drop plans for fake connector - per Michel's comments - fix X patch sent 
 to xorg-devel, add intel polled/hpd setting, add initial nouveau polled/hpd 
 settings.
 
 v3: add config lock take inside polling, add intel/nouveau poll init/fini 
 calls
 Signed-off-by: Dave Airlie airl...@redhat.com

Core and radeon parts

Reviewed-by: Michel Dänzer mic...@daenzer.net

Thanks Dave, looks like the X patch isn't exactly a hard sell either. :)


-- 
Earthling Michel Dänzer   |http://www.vmware.com
Libre software enthusiast |  Debian, X and DRI developer

--
--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


[PATCH] drm/fbdev: fix cloning on fbcon

2010-05-06 Thread Dave Airlie
From: Dave Airlie airl...@redhat.com

Simple cloning rules compared to server:
(a) single crtc
(b)  1 connector active
(c) check command line mode
(d) try and find 1024x768 DMT mode if no command line.
(e) fail to clone

Signed-off-by: Dave Airlie airl...@redhat.com
---
 drivers/gpu/drm/drm_edid.c  |   17 ---
 drivers/gpu/drm/drm_fb_helper.c |   90 --
 include/drm/drm_crtc.h  |2 +
 3 files changed, 96 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 7188674..fe68915 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -658,8 +658,8 @@ static struct drm_display_mode drm_dmt_modes[] = {
 static const int drm_num_dmt_modes =
sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
 
-static struct drm_display_mode *drm_find_dmt(struct drm_device *dev,
-   int hsize, int vsize, int fresh)
+struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
+  int hsize, int vsize, int fresh)
 {
int i;
struct drm_display_mode *ptr, *mode;
@@ -677,6 +677,7 @@ static struct drm_display_mode *drm_find_dmt(struct 
drm_device *dev,
}
return mode;
 }
+EXPORT_SYMBOL(drm_mode_find_dmt);
 
 typedef void detailed_cb(struct detailed_timing *timing, void *closure);
 
@@ -866,7 +867,7 @@ drm_mode_std(struct drm_connector *connector, struct edid 
*edid,
}
 
/* check whether it can be found in default mode table */
-   mode = drm_find_dmt(dev, hsize, vsize, vrefresh_rate);
+   mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate);
if (mode)
return mode;
 
@@ -1386,11 +1387,11 @@ drm_est3_modes(struct drm_connector *connector, struct 
detailed_timing *timing)
if (m  num_est3_modes)
break;
if (est[i]  (1  j)) {
-   mode = drm_find_dmt(connector-dev,
-   est3_modes[m].w,
-   est3_modes[m].h,
-   est3_modes[m].r
-   /*, est3_modes[m].rb */);
+   mode = drm_mode_find_dmt(connector-dev,
+est3_modes[m].w,
+est3_modes[m].h,
+est3_modes[m].r
+/*, est3_modes[m].rb 
*/);
if (mode) {
drm_mode_probed_add(connector, mode);
modes++;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index d198b82..38728c4 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1070,6 +1070,79 @@ static void drm_enable_connectors(struct drm_fb_helper 
*fb_helper,
}
 }
 
+static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
+ struct drm_display_mode **modes,
+ bool *enabled, int width, int height)
+{
+   int count, i, j;
+   bool can_clone = false;
+   struct drm_fb_helper_connector *fb_helper_conn;
+   struct drm_display_mode *dmt_mode, *mode;
+
+   /* only contemplate cloning in the single crtc case */
+   if (fb_helper-crtc_count  1)
+   return false;
+
+   count = 0;
+   for (i = 0; i  fb_helper-connector_count; i++) {
+   if (enabled[i])
+   count++;
+   }
+
+   /* only contemplate cloning if more than one connector is enabled */
+   if (count = 1)
+   return false;
+
+   /* check the command line or if nothing common pick 1024x768 */
+   can_clone = true;
+   for (i = 0; i  fb_helper-connector_count; i++) {
+   if (!enabled[i])
+   continue;
+   fb_helper_conn = fb_helper-connector_info[i];
+   modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height);
+   if (!modes[i]) {
+   can_clone = false;
+   break;
+   }
+   for (j = 0; j  i; j++) {
+   if (!enabled[j])
+   continue;
+   if (!drm_mode_equal(modes[j], modes[i]))
+   can_clone = false;
+   }
+   }
+
+   if (can_clone) {
+   DRM_DEBUG_KMS(can clone using command line\n);
+   return true;
+   }
+
+   /* try and find a 1024x768 mode on each connector */
+   can_clone = true;
+   dmt_mode = drm_mode_find_dmt(fb_helper-dev, 1024, 768,