<div dir="ltr">When getting this patch for -collector I noticed it conflicts with mgag200 and break its compilation.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jun 11, 2014 at 3:55 AM, Chris Wilson <span dir="ltr"><<a href="mailto:chris@chris-wilson.co.uk" target="_blank">chris@chris-wilson.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">i915.ko has a custom fbdev initialisation routine that aims to preserve<br>
the current mode set by the BIOS, unless overruled by the user. The<br>
user's wishes are determined by what, if any, mode is specified on the<br>
command line (via the video= parameter). However, that command line mode<br>
is first parsed by drm_fb_helper_initial_config() which is called after<br>
i915.ko's custom initial_config() as a fallback method. So in order for<br>
us to honour it, we need to move the cmdline parser earlier. If we<br>
perform the connector cmdline parsing as soon as we initialise the<br>
connector, that cmdline mode and forced status is then available even if<br>
the fbdev helper is not compiled in or never called.<br>
<br>
We also then expose the cmdline user mode in the connector mode lists.<br>
<br>
v2: Rebase after connector->name upheaval.<br>
<br>
Bugzilla: <a href="https://bugs.freedesktop.org/show_bug.cgi?id=73154" target="_blank">https://bugs.freedesktop.org/show_bug.cgi?id=73154</a><br>
Signed-off-by: Chris Wilson <<a href="mailto:chris@chris-wilson.co.uk">chris@chris-wilson.co.uk</a>><br>
Cc: Jesse Barnes <<a href="mailto:jbarnes@virtuousgeek.org">jbarnes@virtuousgeek.org</a>><br>
Cc: Ville Syrjälä <<a href="mailto:ville.syrjala@linux.intel.com">ville.syrjala@linux.intel.com</a>><br>
Cc: Daniel Vetter <<a href="mailto:daniel.vetter@ffwll.ch">daniel.vetter@ffwll.ch</a>><br>
Reviewed-by: Jesse Barnes <<a href="mailto:jbarnes@virtuousgeek.org">jbarnes@virtuousgeek.org</a>><br>
Cc: <a href="mailto:dri-devel@lists.freedesktop.org">dri-devel@lists.freedesktop.org</a><br>
---<br>
drivers/gpu/drm/drm_crtc.c | 55 ++++++++++++++++++++++++++++++++<br>
drivers/gpu/drm/drm_fb_helper.c | 64 ++------------------------------------<br>
drivers/gpu/drm/drm_modes.c | 1 +<br>
drivers/gpu/drm/drm_probe_helper.c | 17 ++++++++++<br>
include/drm/drm_crtc.h | 1 +<br>
include/drm/drm_fb_helper.h | 1 -<br>
6 files changed, 77 insertions(+), 62 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c<br>
index fe94cc10cd35..b9de156515b6 100644<br>
--- a/drivers/gpu/drm/drm_crtc.c<br>
+++ b/drivers/gpu/drm/drm_crtc.c<br>
@@ -819,6 +819,59 @@ static void drm_mode_remove(struct drm_connector *connector,<br>
}<br>
<br>
/**<br>
+ * drm_connector_get_cmdline_mode - reads the user's cmdline mode<br>
+ * @connector: connector to quwery<br>
+ * @mode: returned mode<br>
+ *<br>
+ * The kernel supports per-connector configration of its consoles through<br>
+ * use of the video= parameter. This function parses that option and<br>
+ * extracts the user's specified mode (or enable/disable status) for a<br>
+ * particular connector. This is typically only used during the early fbdev<br>
+ * setup.<br>
+ */<br>
+static void drm_connector_get_cmdline_mode(struct drm_connector *connector)<br>
+{<br>
+ struct drm_cmdline_mode *mode = &connector->cmdline_mode;<br>
+ char *option = NULL;<br>
+<br>
+ if (fb_get_options(connector->name, &option))<br>
+ return;<br>
+<br>
+ if (!drm_mode_parse_command_line_for_connector(option,<br>
+ connector,<br>
+ mode))<br>
+ return;<br>
+<br>
+ if (mode->force) {<br>
+ const char *s;<br>
+<br>
+ switch (mode->force) {<br>
+ case DRM_FORCE_OFF:<br>
+ s = "OFF";<br>
+ break;<br>
+ case DRM_FORCE_ON_DIGITAL:<br>
+ s = "ON - dig";<br>
+ break;<br>
+ default:<br>
+ case DRM_FORCE_ON:<br>
+ s = "ON";<br>
+ break;<br>
+ }<br>
+<br>
+ DRM_INFO("forcing %s connector %s\n", connector->name, s);<br>
+ connector->force = mode->force;<br>
+ }<br>
+<br>
+ DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",<br>
+ connector->name,<br>
+ mode->xres, mode->yres,<br>
+ mode->refresh_specified ? mode->refresh : 60,<br>
+ mode->rb ? " reduced blanking" : "",<br>
+ mode->margins ? " with margins" : "",<br>
+ mode->interlace ? " interlaced" : "");<br>
+}<br>
+<br>
+/**<br>
* drm_connector_init - Init a preallocated connector<br>
* @dev: DRM device<br>
* @connector: the connector to init<br>
@@ -870,6 +923,8 @@ int drm_connector_init(struct drm_device *dev,<br>
connector->edid_blob_ptr = NULL;<br>
connector->status = connector_status_unknown;<br>
<br>
+ drm_connector_get_cmdline_mode(connector);<br>
+<br>
list_add_tail(&connector->head, &dev->mode_config.connector_list);<br>
dev->mode_config.num_connector++;<br>
<br>
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c<br>
index d5d8cea1a679..18988dc3de91 100644<br>
--- a/drivers/gpu/drm/drm_fb_helper.c<br>
+++ b/drivers/gpu/drm/drm_fb_helper.c<br>
@@ -105,60 +105,6 @@ fail:<br>
}<br>
EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);<br>
<br>
-static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)<br>
-{<br>
- struct drm_fb_helper_connector *fb_helper_conn;<br>
- int i;<br>
-<br>
- for (i = 0; i < fb_helper->connector_count; i++) {<br>
- struct drm_cmdline_mode *mode;<br>
- struct drm_connector *connector;<br>
- char *option = NULL;<br>
-<br>
- fb_helper_conn = fb_helper->connector_info[i];<br>
- connector = fb_helper_conn->connector;<br>
- mode = &fb_helper_conn->cmdline_mode;<br>
-<br>
- /* do something on return - turn off connector maybe */<br>
- if (fb_get_options(connector->name, &option))<br>
- continue;<br>
-<br>
- if (drm_mode_parse_command_line_for_connector(option,<br>
- connector,<br>
- mode)) {<br>
- if (mode->force) {<br>
- const char *s;<br>
- switch (mode->force) {<br>
- case DRM_FORCE_OFF:<br>
- s = "OFF";<br>
- break;<br>
- case DRM_FORCE_ON_DIGITAL:<br>
- s = "ON - dig";<br>
- break;<br>
- default:<br>
- case DRM_FORCE_ON:<br>
- s = "ON";<br>
- break;<br>
- }<br>
-<br>
- DRM_INFO("forcing %s connector %s\n",<br>
- connector->name, s);<br>
- connector->force = mode->force;<br>
- }<br>
-<br>
- DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",<br>
- connector->name,<br>
- mode->xres, mode->yres,<br>
- mode->refresh_specified ? mode->refresh : 60,<br>
- mode->rb ? " reduced blanking" : "",<br>
- mode->margins ? " with margins" : "",<br>
- mode->interlace ? " interlaced" : "");<br>
- }<br>
-<br>
- }<br>
- return 0;<br>
-}<br>
-<br>
static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct drm_fb_helper *helper)<br>
{<br>
uint16_t *r_base, *g_base, *b_base;<br>
@@ -936,7 +882,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,<br>
struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];<br>
struct drm_cmdline_mode *cmdline_mode;<br>
<br>
- cmdline_mode = &fb_helper_conn->cmdline_mode;<br>
+ cmdline_mode = &fb_helper_conn->connector->cmdline_mode;<br>
<br>
if (cmdline_mode->bpp_specified) {<br>
switch (cmdline_mode->bpp) {<br>
@@ -1184,9 +1130,7 @@ EXPORT_SYMBOL(drm_has_preferred_mode);<br>
<br>
static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)<br>
{<br>
- struct drm_cmdline_mode *cmdline_mode;<br>
- cmdline_mode = &fb_connector->cmdline_mode;<br>
- return cmdline_mode->specified;<br>
+ return fb_connector->connector->cmdline_mode.specified;<br>
}<br>
<br>
struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,<br>
@@ -1196,7 +1140,7 @@ struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f<br>
struct drm_display_mode *mode = NULL;<br>
bool prefer_non_interlace;<br>
<br>
- cmdline_mode = &fb_helper_conn->cmdline_mode;<br>
+ cmdline_mode = &fb_helper_conn->connector->cmdline_mode;<br>
if (cmdline_mode->specified == false)<br>
return mode;<br>
<br>
@@ -1581,8 +1525,6 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)<br>
struct drm_device *dev = fb_helper->dev;<br>
int count = 0;<br>
<br>
- drm_fb_helper_parse_command_line(fb_helper);<br>
-<br>
mutex_lock(&dev->mode_config.mutex);<br>
count = drm_fb_helper_probe_connector_modes(fb_helper,<br>
dev->mode_config.max_width,<br>
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c<br>
index bedf1894e17e..d1b7d2006529 100644<br>
--- a/drivers/gpu/drm/drm_modes.c<br>
+++ b/drivers/gpu/drm/drm_modes.c<br>
@@ -1259,6 +1259,7 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev,<br>
if (!mode)<br>
return NULL;<br>
<br>
+ mode->type |= DRM_MODE_TYPE_USERDEF;<br>
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);<br>
return mode;<br>
}<br>
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c<br>
index d22676b89cbb..59f663879fd4 100644<br>
--- a/drivers/gpu/drm/drm_probe_helper.c<br>
+++ b/drivers/gpu/drm/drm_probe_helper.c<br>
@@ -82,6 +82,22 @@ static void drm_mode_validate_flag(struct drm_connector *connector,<br>
return;<br>
}<br>
<br>
+static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)<br>
+{<br>
+ struct drm_display_mode *mode;<br>
+<br>
+ if (!connector->cmdline_mode.specified)<br>
+ return 0;<br>
+<br>
+ mode = drm_mode_create_from_cmdline_mode(connector->dev,<br>
+ &connector->cmdline_mode);<br>
+ if (mode == NULL)<br>
+ return 0;<br>
+<br>
+ drm_mode_probed_add(connector, mode);<br>
+ return 1;<br>
+}<br>
+<br>
static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,<br>
uint32_t maxX, uint32_t maxY, bool merge_type_bits)<br>
{<br>
@@ -134,6 +150,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect<br>
<br>
if (count == 0 && connector->status == connector_status_connected)<br>
count = drm_add_modes_noedid(connector, 1024, 768);<br>
+ count += drm_helper_probe_add_cmdline_mode(connector);<br>
if (count == 0)<br>
goto prune;<br>
<br>
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h<br>
index 251b75e6bf7a..abaed07a4b3b 100644<br>
--- a/include/drm/drm_crtc.h<br>
+++ b/include/drm/drm_crtc.h<br>
@@ -532,6 +532,7 @@ struct drm_connector {<br>
void *helper_private;<br>
<br>
/* forced on connector */<br>
+ struct drm_cmdline_mode cmdline_mode;<br>
enum drm_connector_force force;<br>
uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];<br>
struct drm_encoder *encoder; /* currently active encoder */<br>
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h<br>
index 7997246d4039..28ead2b6f59b 100644<br>
--- a/include/drm/drm_fb_helper.h<br>
+++ b/include/drm/drm_fb_helper.h<br>
@@ -77,7 +77,6 @@ struct drm_fb_helper_funcs {<br>
<br>
struct drm_fb_helper_connector {<br>
struct drm_connector *connector;<br>
- struct drm_cmdline_mode cmdline_mode;<br>
};<br>
<br>
struct drm_fb_helper {<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.0.0<br>
<br>
_______________________________________________<br>
Intel-gfx mailing list<br>
<a href="mailto:Intel-gfx@lists.freedesktop.org">Intel-gfx@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/intel-gfx" target="_blank">http://lists.freedesktop.org/mailman/listinfo/intel-gfx</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div>Rodrigo Vivi</div><div>Blog: <a href="http://blog.vivi.eng.br" target="_blank">http://blog.vivi.eng.br</a></div><div> </div>
</div>