* [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client
@ 2019-06-08 15:26 Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 1/5] drm/fb-helper: Remove drm_fb_helper_connector Noralf Trønnes
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Noralf Trønnes @ 2019-06-08 15:26 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx, Noralf Trønnes, sam
This moves the modesetting code from drm_fb_helper to drm_client so it
can be shared by all internal clients.
Let's see what the CI says about the remaining patches. I have added the
bootsplash todo entry patch adding Sam as contact.
Noralf.
Noralf Trønnes (5):
drm/fb-helper: Remove drm_fb_helper_connector
drm/fb-helper: Prepare to move out modeset config code
drm/fb-helper: Move out modeset config code
drm/client: Hack: Add bootsplash example
drm/todo: Add bootsplash entry
Documentation/gpu/todo.rst | 19 +
drivers/gpu/drm/Kconfig | 5 +
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/drm_bootsplash.c | 358 +++++++++++
drivers/gpu/drm/drm_client.c | 7 +
drivers/gpu/drm/drm_client_modeset.c | 707 ++++++++++++++++++++-
drivers/gpu/drm/drm_drv.c | 4 +
drivers/gpu/drm/drm_fb_helper.c | 886 +--------------------------
include/drm/drm_client.h | 23 +-
include/drm/drm_fb_helper.h | 84 +--
10 files changed, 1149 insertions(+), 945 deletions(-)
create mode 100644 drivers/gpu/drm/drm_bootsplash.c
--
2.20.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v8 1/5] drm/fb-helper: Remove drm_fb_helper_connector
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
@ 2019-06-08 15:26 ` Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 2/5] drm/fb-helper: Prepare to move out modeset config code Noralf Trønnes
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Noralf Trønnes @ 2019-06-08 15:26 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx, Noralf Trønnes, sam
All drivers add all their connectors so there's no need to keep around an
array of available connectors. Instead we just put the useable (not
writeback) connectors in a temporary array using
drm_client_for_each_connector_iter() everytime we probe the outputs.
Other places where it's necessary to look at the connectors, we just
iterate over them using the same iterator function.
Rename functions which signature is changed since they will be moved to
drm_client in a later patch.
v6: Improve commit message (Sam Ravnborg)
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
---
Documentation/gpu/todo.rst | 4 +
drivers/gpu/drm/drm_fb_helper.c | 498 ++++++++++----------------------
include/drm/drm_client.h | 15 +
include/drm/drm_fb_helper.h | 80 ++---
4 files changed, 193 insertions(+), 404 deletions(-)
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 9d4038c50013..ab96ba0600a9 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -292,6 +292,10 @@ drm_fb_helper tasks
- The max connector argument for drm_fb_helper_init() and
drm_fb_helper_fbdev_setup() isn't used anymore and can be removed.
+- The helper doesn't keep an array of connectors anymore so these can be
+ removed: drm_fb_helper_single_add_all_connectors(),
+ drm_fb_helper_add_one_connector() and drm_fb_helper_remove_one_connector().
+
Core refactorings
=================
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 7b388674a456..b936db6280ac 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -95,12 +95,6 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
* Setup fbdev emulation by calling drm_fb_helper_fbdev_setup() and tear it
* down by calling drm_fb_helper_fbdev_teardown().
*
- * Drivers that need to handle connector hotplugging (e.g. dp mst) can't use
- * the setup helper and will need to do the whole four-step setup process with
- * drm_fb_helper_prepare(), drm_fb_helper_init(),
- * drm_fb_helper_single_add_all_connectors(), enable hotplugging and
- * drm_fb_helper_initial_config() to avoid a possible race window.
- *
* At runtime drivers should restore the fbdev console by using
* drm_fb_helper_lastclose() as their &drm_driver.lastclose callback.
* They should also notify the fb helper code from updates to the output
@@ -123,8 +117,7 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
* encoders and connectors. To finish up the fbdev helper initialization, the
* drm_fb_helper_init() function is called. To probe for all attached displays
* and set up an initial configuration using the detected hardware, drivers
- * should call drm_fb_helper_single_add_all_connectors() followed by
- * drm_fb_helper_initial_config().
+ * should call drm_fb_helper_initial_config().
*
* If &drm_framebuffer_funcs.dirty is set, the
* drm_fb_helper_{cfb,sys}_{write,fillrect,copyarea,imageblit} functions will
@@ -137,165 +130,6 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
* deferred I/O (coupled with drm_fb_helper_fbdev_teardown()).
*/
-#define drm_fb_helper_for_each_connector(fbh, i__) \
- for (({ lockdep_assert_held(&(fbh)->lock); }), \
- i__ = 0; i__ < (fbh)->connector_count; i__++)
-
-static int __drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector)
-{
- struct drm_fb_helper_connector *fb_conn;
- struct drm_fb_helper_connector **temp;
- unsigned int count;
-
- if (!drm_fbdev_emulation)
- return 0;
-
- lockdep_assert_held(&fb_helper->lock);
-
- count = fb_helper->connector_count + 1;
-
- if (count > fb_helper->connector_info_alloc_count) {
- size_t size = count * sizeof(fb_conn);
-
- temp = krealloc(fb_helper->connector_info, size, GFP_KERNEL);
- if (!temp)
- return -ENOMEM;
-
- fb_helper->connector_info_alloc_count = count;
- fb_helper->connector_info = temp;
- }
-
- fb_conn = kzalloc(sizeof(*fb_conn), GFP_KERNEL);
- if (!fb_conn)
- return -ENOMEM;
-
- drm_connector_get(connector);
- fb_conn->connector = connector;
- fb_helper->connector_info[fb_helper->connector_count++] = fb_conn;
-
- return 0;
-}
-
-int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector)
-{
- int err;
-
- if (!fb_helper)
- return 0;
-
- mutex_lock(&fb_helper->lock);
- err = __drm_fb_helper_add_one_connector(fb_helper, connector);
- mutex_unlock(&fb_helper->lock);
-
- return err;
-}
-EXPORT_SYMBOL(drm_fb_helper_add_one_connector);
-
-/**
- * drm_fb_helper_single_add_all_connectors() - add all connectors to fbdev
- * emulation helper
- * @fb_helper: fbdev initialized with drm_fb_helper_init, can be NULL
- *
- * This functions adds all the available connectors for use with the given
- * fb_helper. This is a separate step to allow drivers to freely assign
- * connectors to the fbdev, e.g. if some are reserved for special purposes or
- * not adequate to be used for the fbcon.
- *
- * This function is protected against concurrent connector hotadds/removals
- * using drm_fb_helper_add_one_connector() and
- * drm_fb_helper_remove_one_connector().
- */
-int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
-{
- struct drm_device *dev;
- struct drm_connector *connector;
- struct drm_connector_list_iter conn_iter;
- int i, ret = 0;
-
- if (!drm_fbdev_emulation || !fb_helper)
- return 0;
-
- dev = fb_helper->dev;
-
- mutex_lock(&fb_helper->lock);
- drm_connector_list_iter_begin(dev, &conn_iter);
- drm_for_each_connector_iter(connector, &conn_iter) {
- if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
- continue;
-
- ret = __drm_fb_helper_add_one_connector(fb_helper, connector);
- if (ret)
- goto fail;
- }
- goto out;
-
-fail:
- drm_fb_helper_for_each_connector(fb_helper, i) {
- struct drm_fb_helper_connector *fb_helper_connector =
- fb_helper->connector_info[i];
-
- drm_connector_put(fb_helper_connector->connector);
-
- kfree(fb_helper_connector);
- fb_helper->connector_info[i] = NULL;
- }
- fb_helper->connector_count = 0;
-out:
- drm_connector_list_iter_end(&conn_iter);
- mutex_unlock(&fb_helper->lock);
-
- return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
-
-static int __drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector)
-{
- struct drm_fb_helper_connector *fb_helper_connector;
- int i, j;
-
- if (!drm_fbdev_emulation)
- return 0;
-
- lockdep_assert_held(&fb_helper->lock);
-
- drm_fb_helper_for_each_connector(fb_helper, i) {
- if (fb_helper->connector_info[i]->connector == connector)
- break;
- }
-
- if (i == fb_helper->connector_count)
- return -EINVAL;
- fb_helper_connector = fb_helper->connector_info[i];
- drm_connector_put(fb_helper_connector->connector);
-
- for (j = i + 1; j < fb_helper->connector_count; j++)
- fb_helper->connector_info[j - 1] = fb_helper->connector_info[j];
-
- fb_helper->connector_count--;
- kfree(fb_helper_connector);
-
- return 0;
-}
-
-int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector)
-{
- int err;
-
- if (!fb_helper)
- return 0;
-
- mutex_lock(&fb_helper->lock);
- err = __drm_fb_helper_remove_one_connector(fb_helper, connector);
- mutex_unlock(&fb_helper->lock);
-
- return err;
-}
-EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
-
static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc)
{
uint16_t *r_base, *g_base, *b_base;
@@ -645,20 +479,9 @@ int drm_fb_helper_init(struct drm_device *dev,
return ret;
}
- fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL);
- if (!fb_helper->connector_info)
- goto out_free;
-
- fb_helper->connector_info_alloc_count = dev->mode_config.num_connector;
- fb_helper->connector_count = 0;
-
dev->fb_helper = fb_helper;
return 0;
-out_free:
- drm_client_release(&fb_helper->client);
-
- return -ENOMEM;
}
EXPORT_SYMBOL(drm_fb_helper_init);
@@ -733,7 +556,6 @@ EXPORT_SYMBOL(drm_fb_helper_unregister_fbi);
void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
{
struct fb_info *info;
- int i;
if (!fb_helper)
return;
@@ -766,12 +588,6 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
if (!fb_helper->client.funcs)
drm_client_release(&fb_helper->client);
-
- for (i = 0; i < fb_helper->connector_count; i++) {
- drm_connector_put(fb_helper->connector_info[i]->connector);
- kfree(fb_helper->connector_info[i]);
- }
- kfree(fb_helper->connector_info);
}
EXPORT_SYMBOL(drm_fb_helper_fini);
@@ -1650,8 +1466,9 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
struct drm_client_dev *client = &fb_helper->client;
int ret = 0;
int crtc_count = 0;
- int i;
+ struct drm_connector_list_iter conn_iter;
struct drm_fb_helper_surface_size sizes;
+ struct drm_connector *connector;
struct drm_mode_set *mode_set;
int best_depth = 0;
@@ -1668,11 +1485,11 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
if (preferred_bpp != sizes.surface_bpp)
sizes.surface_depth = sizes.surface_bpp = preferred_bpp;
- drm_fb_helper_for_each_connector(fb_helper, i) {
- struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];
+ drm_connector_list_iter_begin(fb_helper->dev, &conn_iter);
+ drm_client_for_each_connector_iter(connector, &conn_iter) {
struct drm_cmdline_mode *cmdline_mode;
- cmdline_mode = &fb_helper_conn->connector->cmdline_mode;
+ cmdline_mode = &connector->cmdline_mode;
if (cmdline_mode->bpp_specified) {
switch (cmdline_mode->bpp) {
@@ -1697,6 +1514,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
break;
}
}
+ drm_connector_list_iter_end(&conn_iter);
/*
* If we run into a situation where, for example, the primary plane
@@ -1881,26 +1699,12 @@ void drm_fb_helper_fill_info(struct fb_info *info,
}
EXPORT_SYMBOL(drm_fb_helper_fill_info);
-static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper,
- uint32_t maxX,
- uint32_t maxY)
-{
- struct drm_connector *connector;
- int i, count = 0;
-
- drm_fb_helper_for_each_connector(fb_helper, i) {
- connector = fb_helper->connector_info[i]->connector;
- count += connector->funcs->fill_modes(connector, maxX, maxY);
- }
-
- return count;
-}
-
-struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector, int width, int height)
+static struct drm_display_mode *
+drm_connector_has_preferred_mode(struct drm_connector *connector, int width, int height)
{
struct drm_display_mode *mode;
- list_for_each_entry(mode, &fb_connector->connector->modes, head) {
+ list_for_each_entry(mode, &connector->modes, head) {
if (mode->hdisplay > width ||
mode->vdisplay > height)
continue;
@@ -1909,20 +1713,15 @@ struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector *
}
return NULL;
}
-EXPORT_SYMBOL(drm_has_preferred_mode);
-static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
-{
- return fb_connector->connector->cmdline_mode.specified;
-}
-
-struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn)
+static struct drm_display_mode *
+drm_connector_pick_cmdline_mode(struct drm_connector *connector)
{
struct drm_cmdline_mode *cmdline_mode;
struct drm_display_mode *mode;
bool prefer_non_interlace;
- cmdline_mode = &fb_helper_conn->connector->cmdline_mode;
+ cmdline_mode = &connector->cmdline_mode;
if (cmdline_mode->specified == false)
return NULL;
@@ -1934,7 +1733,7 @@ struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f
prefer_non_interlace = !cmdline_mode->interlace;
again:
- list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) {
+ list_for_each_entry(mode, &connector->modes, head) {
/* check width/height */
if (mode->hdisplay != cmdline_mode->xres ||
mode->vdisplay != cmdline_mode->yres)
@@ -1961,12 +1760,11 @@ struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f
}
create_mode:
- mode = drm_mode_create_from_cmdline_mode(fb_helper_conn->connector->dev,
- cmdline_mode);
- list_add(&mode->head, &fb_helper_conn->connector->modes);
+ mode = drm_mode_create_from_cmdline_mode(connector->dev, cmdline_mode);
+ list_add(&mode->head, &connector->modes);
+
return mode;
}
-EXPORT_SYMBOL(drm_pick_cmdline_mode);
static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
{
@@ -1983,15 +1781,16 @@ static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
return enable;
}
-static void drm_enable_connectors(struct drm_fb_helper *fb_helper,
- bool *enabled)
+static void drm_client_connectors_enabled(struct drm_connector **connectors,
+ unsigned int connector_count,
+ bool *enabled)
{
bool any_enabled = false;
struct drm_connector *connector;
int i = 0;
- drm_fb_helper_for_each_connector(fb_helper, i) {
- connector = fb_helper->connector_info[i]->connector;
+ for (i = 0; i < connector_count; i++) {
+ connector = connectors[i];
enabled[i] = drm_connector_enabled(connector, true);
DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
connector->display_info.non_desktop ? "non desktop" : enabled[i] ? "yes" : "no");
@@ -2002,28 +1801,27 @@ static void drm_enable_connectors(struct drm_fb_helper *fb_helper,
if (any_enabled)
return;
- drm_fb_helper_for_each_connector(fb_helper, i) {
- connector = fb_helper->connector_info[i]->connector;
- enabled[i] = drm_connector_enabled(connector, false);
- }
+ for (i = 0; i < connector_count; i++)
+ enabled[i] = drm_connector_enabled(connectors[i], false);
}
-static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
- struct drm_display_mode **modes,
- struct drm_fb_offset *offsets,
- bool *enabled, int width, int height)
+static bool drm_client_target_cloned(struct drm_device *dev,
+ struct drm_connector **connectors,
+ unsigned int connector_count,
+ struct drm_display_mode **modes,
+ struct drm_fb_offset *offsets,
+ 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->dev->mode_config.num_crtc > 1)
+ if (dev->mode_config.num_crtc > 1)
return false;
count = 0;
- drm_fb_helper_for_each_connector(fb_helper, i) {
+ for (i = 0; i < connector_count; i++) {
if (enabled[i])
count++;
}
@@ -2034,11 +1832,10 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
/* check the command line or if nothing common pick 1024x768 */
can_clone = true;
- drm_fb_helper_for_each_connector(fb_helper, i) {
+ for (i = 0; i < connector_count; i++) {
if (!enabled[i])
continue;
- fb_helper_conn = fb_helper->connector_info[i];
- modes[i] = drm_pick_cmdline_mode(fb_helper_conn);
+ modes[i] = drm_connector_pick_cmdline_mode(connectors[i]);
if (!modes[i]) {
can_clone = false;
break;
@@ -2062,14 +1859,13 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
/* try and find a 1024x768 mode on each connector */
can_clone = true;
- dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false);
+ dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false);
- drm_fb_helper_for_each_connector(fb_helper, i) {
+ for (i = 0; i < connector_count; i++) {
if (!enabled[i])
continue;
- fb_helper_conn = fb_helper->connector_info[i];
- list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) {
+ list_for_each_entry(mode, &connectors[i]->modes, head) {
if (drm_mode_match(mode, dmt_mode,
DRM_MODE_MATCH_TIMINGS |
DRM_MODE_MATCH_CLOCK |
@@ -2089,30 +1885,31 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
return false;
}
-static int drm_get_tile_offsets(struct drm_fb_helper *fb_helper,
- struct drm_display_mode **modes,
- struct drm_fb_offset *offsets,
- int idx,
- int h_idx, int v_idx)
+static int drm_client_get_tile_offsets(struct drm_connector **connectors,
+ unsigned int connector_count,
+ struct drm_display_mode **modes,
+ struct drm_fb_offset *offsets,
+ int idx,
+ int h_idx, int v_idx)
{
- struct drm_fb_helper_connector *fb_helper_conn;
+ struct drm_connector *connector;
int i;
int hoffset = 0, voffset = 0;
- drm_fb_helper_for_each_connector(fb_helper, i) {
- fb_helper_conn = fb_helper->connector_info[i];
- if (!fb_helper_conn->connector->has_tile)
+ for (i = 0; i < connector_count; i++) {
+ connector = connectors[i];
+ if (!connector->has_tile)
continue;
if (!modes[i] && (h_idx || v_idx)) {
DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i,
- fb_helper_conn->connector->base.id);
+ connector->base.id);
continue;
}
- if (fb_helper_conn->connector->tile_h_loc < h_idx)
+ if (connector->tile_h_loc < h_idx)
hoffset += modes[i]->hdisplay;
- if (fb_helper_conn->connector->tile_v_loc < v_idx)
+ if (connector->tile_v_loc < v_idx)
voffset += modes[i]->vdisplay;
}
offsets[idx].x = hoffset;
@@ -2121,20 +1918,21 @@ static int drm_get_tile_offsets(struct drm_fb_helper *fb_helper,
return 0;
}
-static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
- struct drm_display_mode **modes,
- struct drm_fb_offset *offsets,
- bool *enabled, int width, int height)
+static bool drm_client_target_preferred(struct drm_connector **connectors,
+ unsigned int connector_count,
+ struct drm_display_mode **modes,
+ struct drm_fb_offset *offsets,
+ bool *enabled, int width, int height)
{
- struct drm_fb_helper_connector *fb_helper_conn;
- const u64 mask = BIT_ULL(fb_helper->connector_count) - 1;
+ const u64 mask = BIT_ULL(connector_count) - 1;
+ struct drm_connector *connector;
u64 conn_configured = 0;
int tile_pass = 0;
int i;
retry:
- drm_fb_helper_for_each_connector(fb_helper, i) {
- fb_helper_conn = fb_helper->connector_info[i];
+ for (i = 0; i < connector_count; i++) {
+ connector = connectors[i];
if (conn_configured & BIT_ULL(i))
continue;
@@ -2145,17 +1943,17 @@ static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
}
/* first pass over all the untiled connectors */
- if (tile_pass == 0 && fb_helper_conn->connector->has_tile)
+ if (tile_pass == 0 && connector->has_tile)
continue;
if (tile_pass == 1) {
- if (fb_helper_conn->connector->tile_h_loc != 0 ||
- fb_helper_conn->connector->tile_v_loc != 0)
+ if (connector->tile_h_loc != 0 ||
+ connector->tile_v_loc != 0)
continue;
} else {
- if (fb_helper_conn->connector->tile_h_loc != tile_pass - 1 &&
- fb_helper_conn->connector->tile_v_loc != tile_pass - 1)
+ if (connector->tile_h_loc != tile_pass - 1 &&
+ connector->tile_v_loc != tile_pass - 1)
/* if this tile_pass doesn't cover any of the tiles - keep going */
continue;
@@ -2163,22 +1961,22 @@ static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
* find the tile offsets for this pass - need to find
* all tiles left and above
*/
- drm_get_tile_offsets(fb_helper, modes, offsets,
- i, fb_helper_conn->connector->tile_h_loc, fb_helper_conn->connector->tile_v_loc);
+ drm_client_get_tile_offsets(connectors, connector_count, modes, offsets, i,
+ connector->tile_h_loc, connector->tile_v_loc);
}
DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
- fb_helper_conn->connector->base.id);
+ connector->base.id);
/* got for command line mode first */
- modes[i] = drm_pick_cmdline_mode(fb_helper_conn);
+ modes[i] = drm_connector_pick_cmdline_mode(connector);
if (!modes[i]) {
DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n",
- fb_helper_conn->connector->base.id, fb_helper_conn->connector->tile_group ? fb_helper_conn->connector->tile_group->id : 0);
- modes[i] = drm_has_preferred_mode(fb_helper_conn, width, height);
+ connector->base.id, connector->tile_group ? connector->tile_group->id : 0);
+ modes[i] = drm_connector_has_preferred_mode(connector, width, height);
}
/* No preferred modes, pick one off the list */
- if (!modes[i] && !list_empty(&fb_helper_conn->connector->modes)) {
- list_for_each_entry(modes[i], &fb_helper_conn->connector->modes, head)
+ if (!modes[i] && !list_empty(&connector->modes)) {
+ list_for_each_entry(modes[i], &connector->modes, head)
break;
}
DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
@@ -2207,40 +2005,41 @@ static bool connector_has_possible_crtc(struct drm_connector *connector,
return false;
}
-static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
- struct drm_crtc **best_crtcs,
- struct drm_display_mode **modes,
- int n, int width, int height)
+static int drm_client_pick_crtcs(struct drm_client_dev *client,
+ struct drm_connector **connectors,
+ unsigned int connector_count,
+ struct drm_crtc **best_crtcs,
+ struct drm_display_mode **modes,
+ int n, int width, int height)
{
- struct drm_client_dev *client = &fb_helper->client;
+ struct drm_device *dev = client->dev;
struct drm_connector *connector;
int my_score, best_score, score;
struct drm_crtc **crtcs, *crtc;
struct drm_mode_set *modeset;
- struct drm_fb_helper_connector *fb_helper_conn;
int o;
- if (n == fb_helper->connector_count)
+ if (n == connector_count)
return 0;
- fb_helper_conn = fb_helper->connector_info[n];
- connector = fb_helper_conn->connector;
+ connector = connectors[n];
best_crtcs[n] = NULL;
- best_score = drm_pick_crtcs(fb_helper, best_crtcs, modes, n+1, width, height);
+ best_score = drm_client_pick_crtcs(client, connectors, connector_count,
+ best_crtcs, modes, n + 1, width, height);
if (modes[n] == NULL)
return best_score;
- crtcs = kcalloc(fb_helper->connector_count, sizeof(*crtcs), GFP_KERNEL);
+ crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
if (!crtcs)
return best_score;
my_score = 1;
if (connector->status == connector_status_connected)
my_score++;
- if (drm_has_cmdline_mode(fb_helper_conn))
+ if (connector->cmdline_mode.specified)
my_score++;
- if (drm_has_preferred_mode(fb_helper_conn, width, height))
+ if (drm_connector_has_preferred_mode(connector, width, height))
my_score++;
/*
@@ -2259,7 +2058,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
if (o < n) {
/* ignore cloning unless only a single crtc */
- if (fb_helper->dev->mode_config.num_crtc > 1)
+ if (dev->mode_config.num_crtc > 1)
continue;
if (!drm_mode_equal(modes[o], modes[n]))
@@ -2268,12 +2067,11 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
crtcs[n] = crtc;
memcpy(crtcs, best_crtcs, n * sizeof(*crtcs));
- score = my_score + drm_pick_crtcs(fb_helper, crtcs, modes, n + 1,
- width, height);
+ score = my_score + drm_client_pick_crtcs(client, connectors, connector_count,
+ crtcs, modes, n + 1, width, height);
if (score > best_score) {
best_score = score;
- memcpy(best_crtcs, crtcs,
- fb_helper->connector_count * sizeof(*crtcs));
+ memcpy(best_crtcs, crtcs, connector_count * sizeof(*crtcs));
}
}
@@ -2282,15 +2080,17 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
}
/* Try to read the BIOS display configuration and use it for the initial config */
-static bool drm_fb_helper_firmware_config(struct drm_fb_helper *fb_helper,
- struct drm_crtc **crtcs,
- struct drm_display_mode **modes,
- struct drm_fb_offset *offsets,
- bool *enabled, int width, int height)
+static bool drm_client_firmware_config(struct drm_client_dev *client,
+ struct drm_connector **connectors,
+ unsigned int connector_count,
+ struct drm_crtc **crtcs,
+ struct drm_display_mode **modes,
+ struct drm_fb_offset *offsets,
+ bool *enabled, int width, int height)
{
- struct drm_device *dev = fb_helper->dev;
- unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG);
+ unsigned int count = min_t(unsigned int, connector_count, BITS_PER_LONG);
unsigned long conn_configured, conn_seq, mask;
+ struct drm_device *dev = client->dev;
int i, j;
bool *save_enabled;
bool fallback = true, ret = true;
@@ -2316,13 +2116,11 @@ static bool drm_fb_helper_firmware_config(struct drm_fb_helper *fb_helper,
retry:
conn_seq = conn_configured;
for (i = 0; i < count; i++) {
- struct drm_fb_helper_connector *fb_conn;
struct drm_connector *connector;
struct drm_encoder *encoder;
struct drm_crtc *new_crtc;
- fb_conn = fb_helper->connector_info[i];
- connector = fb_conn->connector;
+ connector = connectors[i];
if (conn_configured & BIT(i))
continue;
@@ -2379,14 +2177,13 @@ static bool drm_fb_helper_firmware_config(struct drm_fb_helper *fb_helper,
connector->name);
/* go for command line mode first */
- modes[i] = drm_pick_cmdline_mode(fb_conn);
+ modes[i] = drm_connector_pick_cmdline_mode(connector);
/* try for preferred next */
if (!modes[i]) {
DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
connector->name, connector->has_tile);
- modes[i] = drm_has_preferred_mode(fb_conn, width,
- height);
+ modes[i] = drm_connector_has_preferred_mode(connector, width, height);
}
/* No preferred mode marked by the EDID? Are there any modes? */
@@ -2461,8 +2258,12 @@ static bool drm_fb_helper_firmware_config(struct drm_fb_helper *fb_helper,
static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
u32 width, u32 height)
{
+ struct drm_connector *connector, **connectors = NULL;
struct drm_client_dev *client = &fb_helper->client;
+ struct drm_connector_list_iter conn_iter;
struct drm_device *dev = fb_helper->dev;
+ unsigned int total_modes_count = 0;
+ unsigned int connector_count = 0;
struct drm_display_mode **modes;
struct drm_fb_offset *offsets;
struct drm_crtc **crtcs;
@@ -2470,16 +2271,28 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
int i;
DRM_DEBUG_KMS("\n");
- /* prevent concurrent modification of connector_count by hotplug */
- lockdep_assert_held(&fb_helper->lock);
- crtcs = kcalloc(fb_helper->connector_count, sizeof(*crtcs), GFP_KERNEL);
- modes = kcalloc(fb_helper->connector_count,
- sizeof(struct drm_display_mode *), GFP_KERNEL);
- offsets = kcalloc(fb_helper->connector_count,
- sizeof(struct drm_fb_offset), GFP_KERNEL);
- enabled = kcalloc(fb_helper->connector_count,
- sizeof(bool), GFP_KERNEL);
+ drm_connector_list_iter_begin(dev, &conn_iter);
+ drm_client_for_each_connector_iter(connector, &conn_iter) {
+ struct drm_connector **tmp;
+
+ tmp = krealloc(connectors, (connector_count + 1) * sizeof(*connectors), GFP_KERNEL);
+ if (!tmp)
+ goto free_connectors;
+
+ connectors = tmp;
+ drm_connector_get(connector);
+ connectors[connector_count++] = connector;
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+ if (!connector_count)
+ return;
+
+ crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
+ modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL);
+ offsets = kcalloc(connector_count, sizeof(*offsets), GFP_KERNEL);
+ enabled = kcalloc(connector_count, sizeof(bool), GFP_KERNEL);
if (!crtcs || !modes || !enabled || !offsets) {
DRM_ERROR("Memory allocation failed\n");
goto out;
@@ -2488,40 +2301,42 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
mutex_lock(&client->modeset_mutex);
mutex_lock(&fb_helper->dev->mode_config.mutex);
- if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0)
+ for (i = 0; i < connector_count; i++)
+ total_modes_count += connectors[i]->funcs->fill_modes(connectors[i], width, height);
+ if (!total_modes_count)
DRM_DEBUG_KMS("No connectors reported connected with modes\n");
- drm_enable_connectors(fb_helper, enabled);
+ drm_client_connectors_enabled(connectors, connector_count, enabled);
- if (!drm_fb_helper_firmware_config(fb_helper, crtcs, modes, offsets,
- enabled, width, height)) {
- memset(modes, 0, fb_helper->connector_count*sizeof(modes[0]));
- memset(crtcs, 0, fb_helper->connector_count*sizeof(crtcs[0]));
- memset(offsets, 0, fb_helper->connector_count*sizeof(offsets[0]));
+ if (!drm_client_firmware_config(client, connectors, connector_count, crtcs,
+ modes, offsets, enabled, width, height)) {
+ memset(modes, 0, connector_count * sizeof(*modes));
+ memset(crtcs, 0, connector_count * sizeof(*crtcs));
+ memset(offsets, 0, connector_count * sizeof(*offsets));
- if (!drm_target_cloned(fb_helper, modes, offsets,
- enabled, width, height) &&
- !drm_target_preferred(fb_helper, modes, offsets,
- enabled, width, height))
+ if (!drm_client_target_cloned(dev, connectors, connector_count, modes,
+ offsets, enabled, width, height) &&
+ !drm_client_target_preferred(connectors, connector_count, modes,
+ offsets, enabled, width, height))
DRM_ERROR("Unable to find initial modes\n");
DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n",
width, height);
- drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height);
+ drm_client_pick_crtcs(client, connectors, connector_count,
+ crtcs, modes, 0, width, height);
}
mutex_unlock(&fb_helper->dev->mode_config.mutex);
drm_client_modeset_release(client);
- drm_fb_helper_for_each_connector(fb_helper, i) {
+ for (i = 0; i < connector_count; i++) {
struct drm_display_mode *mode = modes[i];
struct drm_crtc *crtc = crtcs[i];
struct drm_fb_offset *offset = &offsets[i];
if (mode && crtc) {
struct drm_mode_set *modeset = drm_client_find_modeset(client, crtc);
- struct drm_connector *connector =
- fb_helper->connector_info[i]->connector;
+ struct drm_connector *connector = connectors[i];
DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
mode->name, crtc->base.id, offset->x, offset->y);
@@ -2544,6 +2359,10 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
kfree(modes);
kfree(offsets);
kfree(enabled);
+free_connectors:
+ for (i = 0; i < connector_count; i++)
+ drm_connector_put(connectors[i]);
+ kfree(connectors);
}
/*
@@ -2556,10 +2375,11 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
{
struct drm_client_dev *client = &fb_helper->client;
+ struct drm_connector_list_iter conn_iter;
struct fb_info *info = fb_helper->fbdev;
unsigned int rotation, sw_rotations = 0;
+ struct drm_connector *connector;
struct drm_mode_set *modeset;
- int i;
mutex_lock(&client->modeset_mutex);
drm_client_for_each_modeset(modeset, client) {
@@ -2576,10 +2396,8 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
}
mutex_unlock(&client->modeset_mutex);
- mutex_lock(&fb_helper->dev->mode_config.mutex);
- drm_fb_helper_for_each_connector(fb_helper, i) {
- struct drm_connector *connector =
- fb_helper->connector_info[i]->connector;
+ drm_connector_list_iter_begin(fb_helper->dev, &conn_iter);
+ drm_client_for_each_connector_iter(connector, &conn_iter) {
/* use first connected connector for the physical dimensions */
if (connector->status == connector_status_connected) {
@@ -2588,7 +2406,7 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
break;
}
}
- mutex_unlock(&fb_helper->dev->mode_config.mutex);
+ drm_connector_list_iter_end(&conn_iter);
switch (sw_rotations) {
case DRM_MODE_ROTATE_0:
@@ -2826,12 +2644,6 @@ int drm_fb_helper_fbdev_setup(struct drm_device *dev,
return ret;
}
- ret = drm_fb_helper_single_add_all_connectors(fb_helper);
- if (ret < 0) {
- DRM_DEV_ERROR(dev->dev, "fbdev: Failed to add connectors (ret=%d)\n", ret);
- goto err_drm_fb_helper_fini;
- }
-
if (!drm_drv_uses_atomic_modeset(dev))
drm_helper_disable_unused_functions(dev);
@@ -3137,10 +2949,6 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client)
if (ret)
goto err;
- ret = drm_fb_helper_single_add_all_connectors(fb_helper);
- if (ret)
- goto err_cleanup;
-
if (!drm_drv_uses_atomic_modeset(dev))
drm_helper_disable_unused_functions(dev);
diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
index 6cf48419f77f..8d94880bbe25 100644
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -7,6 +7,7 @@
#include <linux/mutex.h>
#include <linux/types.h>
+#include <drm/drm_connector.h>
#include <drm/drm_crtc.h>
struct drm_client_dev;
@@ -169,6 +170,20 @@ int drm_client_modeset_dpms(struct drm_client_dev *client, int mode);
for (({ lockdep_assert_held(&(client)->modeset_mutex); }), \
modeset = (client)->modesets; modeset->crtc; modeset++)
+/**
+ * drm_client_for_each_connector_iter - connector_list iterator macro
+ * @connector: &struct drm_connector pointer used as cursor
+ * @iter: &struct drm_connector_list_iter
+ *
+ * This iterates the connectors that are useable for internal clients (excludes
+ * writeback connectors).
+ *
+ * For more info see drm_for_each_connector_iter().
+ */
+#define drm_client_for_each_connector_iter(connector, iter) \
+ drm_for_each_connector_iter(connector, iter) \
+ if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+
int drm_client_debugfs_init(struct drm_minor *minor);
#endif
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 6b334f4d8a22..e14d52ef9638 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -97,16 +97,10 @@ struct drm_fb_helper_funcs {
struct drm_fb_helper_surface_size *sizes);
};
-struct drm_fb_helper_connector {
- struct drm_connector *connector;
-};
-
/**
* struct drm_fb_helper - main structure to emulate fbdev on top of KMS
* @fb: Scanout framebuffer object
* @dev: DRM device
- * @connector_count: number of connected connectors
- * @connector_info_alloc_count: size of connector_info
* @funcs: driver callbacks for fb helper
* @fbdev: emulated fbdev device info struct
* @pseudo_palette: fake palette of 16 colors
@@ -138,15 +132,6 @@ struct drm_fb_helper {
struct drm_framebuffer *fb;
struct drm_device *dev;
- int connector_count;
- int connector_info_alloc_count;
- /**
- * @connector_info:
- *
- * Array of per-connector information. Do not iterate directly, but use
- * drm_fb_helper_for_each_connector.
- */
- struct drm_fb_helper_connector **connector_info;
const struct drm_fb_helper_funcs *funcs;
struct fb_info *fbdev;
u32 pseudo_palette[17];
@@ -286,18 +271,8 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
-int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
int drm_fb_helper_debug_enter(struct fb_info *info);
int drm_fb_helper_debug_leave(struct fb_info *info);
-struct drm_display_mode *
-drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
- int width, int height);
-struct drm_display_mode *
-drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn);
-
-int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector);
-int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector);
int drm_fb_helper_fbdev_setup(struct drm_device *dev,
struct drm_fb_helper *fb_helper,
@@ -472,12 +447,6 @@ static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper,
return 0;
}
-static inline int
-drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
-{
- return 0;
-}
-
static inline int drm_fb_helper_debug_enter(struct fb_info *info)
{
return 0;
@@ -488,34 +457,6 @@ static inline int drm_fb_helper_debug_leave(struct fb_info *info)
return 0;
}
-static inline struct drm_display_mode *
-drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
- int width, int height)
-{
- return NULL;
-}
-
-static inline struct drm_display_mode *
-drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
- int width, int height)
-{
- return NULL;
-}
-
-static inline int
-drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector)
-{
- return 0;
-}
-
-static inline int
-drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector)
-{
- return 0;
-}
-
static inline int
drm_fb_helper_fbdev_setup(struct drm_device *dev,
struct drm_fb_helper *fb_helper,
@@ -557,6 +498,27 @@ drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
#endif
+/* TODO: There's a todo entry to remove these three */
+static inline int
+drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
+{
+ return 0;
+}
+
+static inline int
+drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
+ struct drm_connector *connector)
+{
+ return 0;
+}
+
+static inline int
+drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
+ struct drm_connector *connector)
+{
+ return 0;
+}
+
/**
* drm_fb_helper_remove_conflicting_framebuffers - remove firmware-configured framebuffers
* @a: memory range, users of which are to be removed
--
2.20.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v8 2/5] drm/fb-helper: Prepare to move out modeset config code
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 1/5] drm/fb-helper: Remove drm_fb_helper_connector Noralf Trønnes
@ 2019-06-08 15:26 ` Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 3/5] drm/fb-helper: Move " Noralf Trønnes
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Noralf Trønnes @ 2019-06-08 15:26 UTC (permalink / raw)
To: dri-devel; +Cc: Maxime Ripard, intel-gfx, sam
This prepares the modeset code so it can be moved out as-is in the next
patch.
v3: Remove stray newline
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Reviewed-by: Maxime Ripard <maxime.ripard@bootlin.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
---
drivers/gpu/drm/drm_fb_helper.c | 62 +++++++++++++++++++++++----------
include/drm/drm_fb_helper.h | 4 ---
2 files changed, 44 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index b936db6280ac..e7f41e5d924c 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -48,6 +48,10 @@
#include "drm_internal.h"
+struct drm_client_offset {
+ int x, y;
+};
+
static bool drm_fbdev_emulation = true;
module_param_named(fbdev_emulation, drm_fbdev_emulation, bool, 0600);
MODULE_PARM_DESC(fbdev_emulation,
@@ -1809,7 +1813,7 @@ static bool drm_client_target_cloned(struct drm_device *dev,
struct drm_connector **connectors,
unsigned int connector_count,
struct drm_display_mode **modes,
- struct drm_fb_offset *offsets,
+ struct drm_client_offset *offsets,
bool *enabled, int width, int height)
{
int count, i, j;
@@ -1888,7 +1892,7 @@ static bool drm_client_target_cloned(struct drm_device *dev,
static int drm_client_get_tile_offsets(struct drm_connector **connectors,
unsigned int connector_count,
struct drm_display_mode **modes,
- struct drm_fb_offset *offsets,
+ struct drm_client_offset *offsets,
int idx,
int h_idx, int v_idx)
{
@@ -1921,7 +1925,7 @@ static int drm_client_get_tile_offsets(struct drm_connector **connectors,
static bool drm_client_target_preferred(struct drm_connector **connectors,
unsigned int connector_count,
struct drm_display_mode **modes,
- struct drm_fb_offset *offsets,
+ struct drm_client_offset *offsets,
bool *enabled, int width, int height)
{
const u64 mask = BIT_ULL(connector_count) - 1;
@@ -2085,7 +2089,7 @@ static bool drm_client_firmware_config(struct drm_client_dev *client,
unsigned int connector_count,
struct drm_crtc **crtcs,
struct drm_display_mode **modes,
- struct drm_fb_offset *offsets,
+ struct drm_client_offset *offsets,
bool *enabled, int width, int height)
{
unsigned int count = min_t(unsigned int, connector_count, BITS_PER_LONG);
@@ -2255,30 +2259,47 @@ static bool drm_client_firmware_config(struct drm_client_dev *client,
return ret;
}
-static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
- u32 width, u32 height)
+/**
+ * drm_client_modeset_probe() - Probe for displays
+ * @client: DRM client
+ * @width: Maximum display mode width (optional)
+ * @height: Maximum display mode height (optional)
+ *
+ * This function sets up display pipelines for enabled connectors and stores the
+ * config in the client's modeset array.
+ *
+ * Returns:
+ * Zero on success or negative error code on failure.
+ */
+int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height)
{
struct drm_connector *connector, **connectors = NULL;
- struct drm_client_dev *client = &fb_helper->client;
struct drm_connector_list_iter conn_iter;
- struct drm_device *dev = fb_helper->dev;
+ struct drm_device *dev = client->dev;
unsigned int total_modes_count = 0;
+ struct drm_client_offset *offsets;
unsigned int connector_count = 0;
struct drm_display_mode **modes;
- struct drm_fb_offset *offsets;
struct drm_crtc **crtcs;
+ int i, ret = 0;
bool *enabled;
- int i;
DRM_DEBUG_KMS("\n");
+ if (!width)
+ width = dev->mode_config.max_width;
+ if (!height)
+ height = dev->mode_config.max_height;
+
drm_connector_list_iter_begin(dev, &conn_iter);
drm_client_for_each_connector_iter(connector, &conn_iter) {
struct drm_connector **tmp;
tmp = krealloc(connectors, (connector_count + 1) * sizeof(*connectors), GFP_KERNEL);
- if (!tmp)
+ if (!tmp) {
+ ret = -ENOMEM;
goto free_connectors;
+ }
connectors = tmp;
drm_connector_get(connector);
@@ -2287,7 +2308,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
drm_connector_list_iter_end(&conn_iter);
if (!connector_count)
- return;
+ return 0;
crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL);
@@ -2295,12 +2316,13 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
enabled = kcalloc(connector_count, sizeof(bool), GFP_KERNEL);
if (!crtcs || !modes || !enabled || !offsets) {
DRM_ERROR("Memory allocation failed\n");
+ ret = -ENOMEM;
goto out;
}
mutex_lock(&client->modeset_mutex);
- mutex_lock(&fb_helper->dev->mode_config.mutex);
+ mutex_lock(&dev->mode_config.mutex);
for (i = 0; i < connector_count; i++)
total_modes_count += connectors[i]->funcs->fill_modes(connectors[i], width, height);
if (!total_modes_count)
@@ -2325,14 +2347,14 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
drm_client_pick_crtcs(client, connectors, connector_count,
crtcs, modes, 0, width, height);
}
- mutex_unlock(&fb_helper->dev->mode_config.mutex);
+ mutex_unlock(&dev->mode_config.mutex);
drm_client_modeset_release(client);
for (i = 0; i < connector_count; i++) {
struct drm_display_mode *mode = modes[i];
struct drm_crtc *crtc = crtcs[i];
- struct drm_fb_offset *offset = &offsets[i];
+ struct drm_client_offset *offset = &offsets[i];
if (mode && crtc) {
struct drm_mode_set *modeset = drm_client_find_modeset(client, crtc);
@@ -2342,8 +2364,10 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
mode->name, crtc->base.id, offset->x, offset->y);
if (WARN_ON_ONCE(modeset->num_connectors == DRM_CLIENT_MAX_CLONED_CONNECTORS ||
- (dev->mode_config.num_crtc > 1 && modeset->num_connectors == 1)))
+ (dev->mode_config.num_crtc > 1 && modeset->num_connectors == 1))) {
+ ret = -EINVAL;
break;
+ }
modeset->mode = drm_mode_duplicate(dev, mode);
drm_connector_get(connector);
@@ -2363,6 +2387,8 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
for (i = 0; i < connector_count; i++)
drm_connector_put(connectors[i]);
kfree(connectors);
+
+ return ret;
}
/*
@@ -2444,7 +2470,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
width = dev->mode_config.max_width;
height = dev->mode_config.max_height;
- drm_setup_crtcs(fb_helper, width, height);
+ drm_client_modeset_probe(&fb_helper->client, width, height);
ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
if (ret < 0) {
if (ret == -EAGAIN) {
@@ -2591,7 +2617,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
DRM_DEBUG_KMS("\n");
- drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height);
+ drm_client_modeset_probe(&fb_helper->client, fb_helper->fb->width, fb_helper->fb->height);
drm_setup_crtcs_fb(fb_helper);
mutex_unlock(&fb_helper->lock);
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index e14d52ef9638..c8a8ae2a678a 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -43,10 +43,6 @@ enum mode_set_atomic {
ENTER_ATOMIC_MODE_SET,
};
-struct drm_fb_offset {
- int x, y;
-};
-
/**
* struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size
* @fb_width: fbdev width
--
2.20.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v8 3/5] drm/fb-helper: Move out modeset config code
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 1/5] drm/fb-helper: Remove drm_fb_helper_connector Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 2/5] drm/fb-helper: Prepare to move out modeset config code Noralf Trønnes
@ 2019-06-08 15:26 ` Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 4/5] drm/client: Hack: Add bootsplash example Noralf Trønnes
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Noralf Trønnes @ 2019-06-08 15:26 UTC (permalink / raw)
To: dri-devel; +Cc: Maxime Ripard, intel-gfx, Noralf Trønnes, sam
No functional changes, just moving code as-is and fixing includes.
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Reviewed-by: Maxime Ripard <maxime.ripard@bootlin.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
---
drivers/gpu/drm/drm_client_modeset.c | 707 ++++++++++++++++++++++++++-
drivers/gpu/drm/drm_fb_helper.c | 692 --------------------------
include/drm/drm_client.h | 5 +-
3 files changed, 702 insertions(+), 702 deletions(-)
diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c
index b1984f901a6d..006bf7390e7d 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -13,13 +13,22 @@
#include <drm/drm_atomic.h>
#include <drm/drm_client.h>
+#include <drm/drm_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_drv.h>
+#include <drm/drm_encoder.h>
+#include <drm/drm_print.h>
#include "drm_crtc_internal.h"
#include "drm_internal.h"
+#define DRM_CLIENT_MAX_CLONED_CONNECTORS 8
+
+struct drm_client_offset {
+ int x, y;
+};
+
int drm_client_modeset_create(struct drm_client_dev *client)
{
struct drm_device *dev = client->dev;
@@ -58,7 +67,7 @@ int drm_client_modeset_create(struct drm_client_dev *client)
return -ENOMEM;
}
-void drm_client_modeset_release(struct drm_client_dev *client)
+static void drm_client_modeset_release(struct drm_client_dev *client)
{
struct drm_mode_set *modeset;
unsigned int i;
@@ -75,8 +84,6 @@ void drm_client_modeset_release(struct drm_client_dev *client)
modeset->num_connectors = 0;
}
}
-/* TODO: Remove export when modeset code has been moved over */
-EXPORT_SYMBOL(drm_client_modeset_release);
void drm_client_modeset_free(struct drm_client_dev *client)
{
@@ -95,7 +102,8 @@ void drm_client_modeset_free(struct drm_client_dev *client)
kfree(client->modesets);
}
-struct drm_mode_set *drm_client_find_modeset(struct drm_client_dev *client, struct drm_crtc *crtc)
+static struct drm_mode_set *
+drm_client_find_modeset(struct drm_client_dev *client, struct drm_crtc *crtc)
{
struct drm_mode_set *modeset;
@@ -105,8 +113,695 @@ struct drm_mode_set *drm_client_find_modeset(struct drm_client_dev *client, stru
return NULL;
}
-/* TODO: Remove export when modeset code has been moved over */
-EXPORT_SYMBOL(drm_client_find_modeset);
+
+static struct drm_display_mode *
+drm_connector_has_preferred_mode(struct drm_connector *connector, int width, int height)
+{
+ struct drm_display_mode *mode;
+
+ list_for_each_entry(mode, &connector->modes, head) {
+ if (mode->hdisplay > width ||
+ mode->vdisplay > height)
+ continue;
+ if (mode->type & DRM_MODE_TYPE_PREFERRED)
+ return mode;
+ }
+ return NULL;
+}
+
+static struct drm_display_mode *
+drm_connector_pick_cmdline_mode(struct drm_connector *connector)
+{
+ struct drm_cmdline_mode *cmdline_mode;
+ struct drm_display_mode *mode;
+ bool prefer_non_interlace;
+
+ cmdline_mode = &connector->cmdline_mode;
+ if (cmdline_mode->specified == false)
+ return NULL;
+
+ /* attempt to find a matching mode in the list of modes
+ * we have gotten so far, if not add a CVT mode that conforms
+ */
+ if (cmdline_mode->rb || cmdline_mode->margins)
+ goto create_mode;
+
+ prefer_non_interlace = !cmdline_mode->interlace;
+again:
+ list_for_each_entry(mode, &connector->modes, head) {
+ /* check width/height */
+ if (mode->hdisplay != cmdline_mode->xres ||
+ mode->vdisplay != cmdline_mode->yres)
+ continue;
+
+ if (cmdline_mode->refresh_specified) {
+ if (mode->vrefresh != cmdline_mode->refresh)
+ continue;
+ }
+
+ if (cmdline_mode->interlace) {
+ if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
+ continue;
+ } else if (prefer_non_interlace) {
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ continue;
+ }
+ return mode;
+ }
+
+ if (prefer_non_interlace) {
+ prefer_non_interlace = false;
+ goto again;
+ }
+
+create_mode:
+ mode = drm_mode_create_from_cmdline_mode(connector->dev, cmdline_mode);
+ list_add(&mode->head, &connector->modes);
+
+ return mode;
+}
+
+static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
+{
+ bool enable;
+
+ if (connector->display_info.non_desktop)
+ return false;
+
+ if (strict)
+ enable = connector->status == connector_status_connected;
+ else
+ enable = connector->status != connector_status_disconnected;
+
+ return enable;
+}
+
+static void drm_client_connectors_enabled(struct drm_connector **connectors,
+ unsigned int connector_count,
+ bool *enabled)
+{
+ bool any_enabled = false;
+ struct drm_connector *connector;
+ int i = 0;
+
+ for (i = 0; i < connector_count; i++) {
+ connector = connectors[i];
+ enabled[i] = drm_connector_enabled(connector, true);
+ DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
+ connector->display_info.non_desktop ? "non desktop" : enabled[i] ? "yes" : "no");
+
+ any_enabled |= enabled[i];
+ }
+
+ if (any_enabled)
+ return;
+
+ for (i = 0; i < connector_count; i++)
+ enabled[i] = drm_connector_enabled(connectors[i], false);
+}
+
+static bool drm_client_target_cloned(struct drm_device *dev,
+ struct drm_connector **connectors,
+ unsigned int connector_count,
+ struct drm_display_mode **modes,
+ struct drm_client_offset *offsets,
+ bool *enabled, int width, int height)
+{
+ int count, i, j;
+ bool can_clone = false;
+ struct drm_display_mode *dmt_mode, *mode;
+
+ /* only contemplate cloning in the single crtc case */
+ if (dev->mode_config.num_crtc > 1)
+ return false;
+
+ count = 0;
+ for (i = 0; i < 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 < connector_count; i++) {
+ if (!enabled[i])
+ continue;
+ modes[i] = drm_connector_pick_cmdline_mode(connectors[i]);
+ if (!modes[i]) {
+ can_clone = false;
+ break;
+ }
+ for (j = 0; j < i; j++) {
+ if (!enabled[j])
+ continue;
+ if (!drm_mode_match(modes[j], modes[i],
+ DRM_MODE_MATCH_TIMINGS |
+ DRM_MODE_MATCH_CLOCK |
+ DRM_MODE_MATCH_FLAGS |
+ DRM_MODE_MATCH_3D_FLAGS))
+ 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(dev, 1024, 768, 60, false);
+
+ for (i = 0; i < connector_count; i++) {
+ if (!enabled[i])
+ continue;
+
+ list_for_each_entry(mode, &connectors[i]->modes, head) {
+ if (drm_mode_match(mode, dmt_mode,
+ DRM_MODE_MATCH_TIMINGS |
+ DRM_MODE_MATCH_CLOCK |
+ DRM_MODE_MATCH_FLAGS |
+ DRM_MODE_MATCH_3D_FLAGS))
+ modes[i] = mode;
+ }
+ if (!modes[i])
+ can_clone = false;
+ }
+
+ if (can_clone) {
+ DRM_DEBUG_KMS("can clone using 1024x768\n");
+ return true;
+ }
+ DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
+ return false;
+}
+
+static int drm_client_get_tile_offsets(struct drm_connector **connectors,
+ unsigned int connector_count,
+ struct drm_display_mode **modes,
+ struct drm_client_offset *offsets,
+ int idx,
+ int h_idx, int v_idx)
+{
+ struct drm_connector *connector;
+ int i;
+ int hoffset = 0, voffset = 0;
+
+ for (i = 0; i < connector_count; i++) {
+ connector = connectors[i];
+ if (!connector->has_tile)
+ continue;
+
+ if (!modes[i] && (h_idx || v_idx)) {
+ DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i,
+ connector->base.id);
+ continue;
+ }
+ if (connector->tile_h_loc < h_idx)
+ hoffset += modes[i]->hdisplay;
+
+ if (connector->tile_v_loc < v_idx)
+ voffset += modes[i]->vdisplay;
+ }
+ offsets[idx].x = hoffset;
+ offsets[idx].y = voffset;
+ DRM_DEBUG_KMS("returned %d %d for %d %d\n", hoffset, voffset, h_idx, v_idx);
+ return 0;
+}
+
+static bool drm_client_target_preferred(struct drm_connector **connectors,
+ unsigned int connector_count,
+ struct drm_display_mode **modes,
+ struct drm_client_offset *offsets,
+ bool *enabled, int width, int height)
+{
+ const u64 mask = BIT_ULL(connector_count) - 1;
+ struct drm_connector *connector;
+ u64 conn_configured = 0;
+ int tile_pass = 0;
+ int i;
+
+retry:
+ for (i = 0; i < connector_count; i++) {
+ connector = connectors[i];
+
+ if (conn_configured & BIT_ULL(i))
+ continue;
+
+ if (enabled[i] == false) {
+ conn_configured |= BIT_ULL(i);
+ continue;
+ }
+
+ /* first pass over all the untiled connectors */
+ if (tile_pass == 0 && connector->has_tile)
+ continue;
+
+ if (tile_pass == 1) {
+ if (connector->tile_h_loc != 0 ||
+ connector->tile_v_loc != 0)
+ continue;
+
+ } else {
+ if (connector->tile_h_loc != tile_pass - 1 &&
+ connector->tile_v_loc != tile_pass - 1)
+ /* if this tile_pass doesn't cover any of the tiles - keep going */
+ continue;
+
+ /*
+ * find the tile offsets for this pass - need to find
+ * all tiles left and above
+ */
+ drm_client_get_tile_offsets(connectors, connector_count, modes, offsets, i,
+ connector->tile_h_loc, connector->tile_v_loc);
+ }
+ DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
+ connector->base.id);
+
+ /* got for command line mode first */
+ modes[i] = drm_connector_pick_cmdline_mode(connector);
+ if (!modes[i]) {
+ DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n",
+ connector->base.id, connector->tile_group ? connector->tile_group->id : 0);
+ modes[i] = drm_connector_has_preferred_mode(connector, width, height);
+ }
+ /* No preferred modes, pick one off the list */
+ if (!modes[i] && !list_empty(&connector->modes)) {
+ list_for_each_entry(modes[i], &connector->modes, head)
+ break;
+ }
+ DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
+ "none");
+ conn_configured |= BIT_ULL(i);
+ }
+
+ if ((conn_configured & mask) != mask) {
+ tile_pass++;
+ goto retry;
+ }
+ return true;
+}
+
+static bool connector_has_possible_crtc(struct drm_connector *connector,
+ struct drm_crtc *crtc)
+{
+ struct drm_encoder *encoder;
+ int i;
+
+ drm_connector_for_each_possible_encoder(connector, encoder, i) {
+ if (encoder->possible_crtcs & drm_crtc_mask(crtc))
+ return true;
+ }
+
+ return false;
+}
+
+static int drm_client_pick_crtcs(struct drm_client_dev *client,
+ struct drm_connector **connectors,
+ unsigned int connector_count,
+ struct drm_crtc **best_crtcs,
+ struct drm_display_mode **modes,
+ int n, int width, int height)
+{
+ struct drm_device *dev = client->dev;
+ struct drm_connector *connector;
+ int my_score, best_score, score;
+ struct drm_crtc **crtcs, *crtc;
+ struct drm_mode_set *modeset;
+ int o;
+
+ if (n == connector_count)
+ return 0;
+
+ connector = connectors[n];
+
+ best_crtcs[n] = NULL;
+ best_score = drm_client_pick_crtcs(client, connectors, connector_count,
+ best_crtcs, modes, n + 1, width, height);
+ if (modes[n] == NULL)
+ return best_score;
+
+ crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
+ if (!crtcs)
+ return best_score;
+
+ my_score = 1;
+ if (connector->status == connector_status_connected)
+ my_score++;
+ if (connector->cmdline_mode.specified)
+ my_score++;
+ if (drm_connector_has_preferred_mode(connector, width, height))
+ my_score++;
+
+ /*
+ * select a crtc for this connector and then attempt to configure
+ * remaining connectors
+ */
+ drm_client_for_each_modeset(modeset, client) {
+ crtc = modeset->crtc;
+
+ if (!connector_has_possible_crtc(connector, crtc))
+ continue;
+
+ for (o = 0; o < n; o++)
+ if (best_crtcs[o] == crtc)
+ break;
+
+ if (o < n) {
+ /* ignore cloning unless only a single crtc */
+ if (dev->mode_config.num_crtc > 1)
+ continue;
+
+ if (!drm_mode_equal(modes[o], modes[n]))
+ continue;
+ }
+
+ crtcs[n] = crtc;
+ memcpy(crtcs, best_crtcs, n * sizeof(*crtcs));
+ score = my_score + drm_client_pick_crtcs(client, connectors, connector_count,
+ crtcs, modes, n + 1, width, height);
+ if (score > best_score) {
+ best_score = score;
+ memcpy(best_crtcs, crtcs, connector_count * sizeof(*crtcs));
+ }
+ }
+
+ kfree(crtcs);
+ return best_score;
+}
+
+/* Try to read the BIOS display configuration and use it for the initial config */
+static bool drm_client_firmware_config(struct drm_client_dev *client,
+ struct drm_connector **connectors,
+ unsigned int connector_count,
+ struct drm_crtc **crtcs,
+ struct drm_display_mode **modes,
+ struct drm_client_offset *offsets,
+ bool *enabled, int width, int height)
+{
+ unsigned int count = min_t(unsigned int, connector_count, BITS_PER_LONG);
+ unsigned long conn_configured, conn_seq, mask;
+ struct drm_device *dev = client->dev;
+ int i, j;
+ bool *save_enabled;
+ bool fallback = true, ret = true;
+ int num_connectors_enabled = 0;
+ int num_connectors_detected = 0;
+ struct drm_modeset_acquire_ctx ctx;
+
+ if (!drm_drv_uses_atomic_modeset(dev))
+ return false;
+
+ save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
+ if (!save_enabled)
+ return false;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ while (drm_modeset_lock_all_ctx(dev, &ctx) != 0)
+ drm_modeset_backoff(&ctx);
+
+ memcpy(save_enabled, enabled, count);
+ mask = GENMASK(count - 1, 0);
+ conn_configured = 0;
+retry:
+ conn_seq = conn_configured;
+ for (i = 0; i < count; i++) {
+ struct drm_connector *connector;
+ struct drm_encoder *encoder;
+ struct drm_crtc *new_crtc;
+
+ connector = connectors[i];
+
+ if (conn_configured & BIT(i))
+ continue;
+
+ if (conn_seq == 0 && !connector->has_tile)
+ continue;
+
+ if (connector->status == connector_status_connected)
+ num_connectors_detected++;
+
+ if (!enabled[i]) {
+ DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
+ connector->name);
+ conn_configured |= BIT(i);
+ continue;
+ }
+
+ if (connector->force == DRM_FORCE_OFF) {
+ DRM_DEBUG_KMS("connector %s is disabled by user, skipping\n",
+ connector->name);
+ enabled[i] = false;
+ continue;
+ }
+
+ encoder = connector->state->best_encoder;
+ if (!encoder || WARN_ON(!connector->state->crtc)) {
+ if (connector->force > DRM_FORCE_OFF)
+ goto bail;
+
+ DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
+ connector->name);
+ enabled[i] = false;
+ conn_configured |= BIT(i);
+ continue;
+ }
+
+ num_connectors_enabled++;
+
+ new_crtc = connector->state->crtc;
+
+ /*
+ * Make sure we're not trying to drive multiple connectors
+ * with a single CRTC, since our cloning support may not
+ * match the BIOS.
+ */
+ for (j = 0; j < count; j++) {
+ if (crtcs[j] == new_crtc) {
+ DRM_DEBUG_KMS("fallback: cloned configuration\n");
+ goto bail;
+ }
+ }
+
+ DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
+ connector->name);
+
+ /* go for command line mode first */
+ modes[i] = drm_connector_pick_cmdline_mode(connector);
+
+ /* try for preferred next */
+ if (!modes[i]) {
+ DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
+ connector->name, connector->has_tile);
+ modes[i] = drm_connector_has_preferred_mode(connector, width, height);
+ }
+
+ /* No preferred mode marked by the EDID? Are there any modes? */
+ if (!modes[i] && !list_empty(&connector->modes)) {
+ DRM_DEBUG_KMS("using first mode listed on connector %s\n",
+ connector->name);
+ modes[i] = list_first_entry(&connector->modes,
+ struct drm_display_mode,
+ head);
+ }
+
+ /* last resort: use current mode */
+ if (!modes[i]) {
+ /*
+ * IMPORTANT: We want to use the adjusted mode (i.e.
+ * after the panel fitter upscaling) as the initial
+ * config, not the input mode, which is what crtc->mode
+ * usually contains. But since our current
+ * code puts a mode derived from the post-pfit timings
+ * into crtc->mode this works out correctly.
+ *
+ * This is crtc->mode and not crtc->state->mode for the
+ * fastboot check to work correctly.
+ */
+ DRM_DEBUG_KMS("looking for current mode on connector %s\n",
+ connector->name);
+ modes[i] = &connector->state->crtc->mode;
+ }
+ crtcs[i] = new_crtc;
+
+ DRM_DEBUG_KMS("connector %s on [CRTC:%d:%s]: %dx%d%s\n",
+ connector->name,
+ connector->state->crtc->base.id,
+ connector->state->crtc->name,
+ modes[i]->hdisplay, modes[i]->vdisplay,
+ modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "");
+
+ fallback = false;
+ conn_configured |= BIT(i);
+ }
+
+ if ((conn_configured & mask) != mask && conn_configured != conn_seq)
+ goto retry;
+
+ /*
+ * If the BIOS didn't enable everything it could, fall back to have the
+ * same user experiencing of lighting up as much as possible like the
+ * fbdev helper library.
+ */
+ if (num_connectors_enabled != num_connectors_detected &&
+ num_connectors_enabled < dev->mode_config.num_crtc) {
+ DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
+ DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
+ num_connectors_detected);
+ fallback = true;
+ }
+
+ if (fallback) {
+bail:
+ DRM_DEBUG_KMS("Not using firmware configuration\n");
+ memcpy(enabled, save_enabled, count);
+ ret = false;
+ }
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
+ kfree(save_enabled);
+ return ret;
+}
+
+/**
+ * drm_client_modeset_probe() - Probe for displays
+ * @client: DRM client
+ * @width: Maximum display mode width (optional)
+ * @height: Maximum display mode height (optional)
+ *
+ * This function sets up display pipelines for enabled connectors and stores the
+ * config in the client's modeset array.
+ *
+ * Returns:
+ * Zero on success or negative error code on failure.
+ */
+int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height)
+{
+ struct drm_connector *connector, **connectors = NULL;
+ struct drm_connector_list_iter conn_iter;
+ struct drm_device *dev = client->dev;
+ unsigned int total_modes_count = 0;
+ struct drm_client_offset *offsets;
+ unsigned int connector_count = 0;
+ struct drm_display_mode **modes;
+ struct drm_crtc **crtcs;
+ int i, ret = 0;
+ bool *enabled;
+
+ DRM_DEBUG_KMS("\n");
+
+ if (!width)
+ width = dev->mode_config.max_width;
+ if (!height)
+ height = dev->mode_config.max_height;
+
+ drm_connector_list_iter_begin(dev, &conn_iter);
+ drm_client_for_each_connector_iter(connector, &conn_iter) {
+ struct drm_connector **tmp;
+
+ tmp = krealloc(connectors, (connector_count + 1) * sizeof(*connectors), GFP_KERNEL);
+ if (!tmp) {
+ ret = -ENOMEM;
+ goto free_connectors;
+ }
+
+ connectors = tmp;
+ drm_connector_get(connector);
+ connectors[connector_count++] = connector;
+ }
+ drm_connector_list_iter_end(&conn_iter);
+
+ if (!connector_count)
+ return 0;
+
+ crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
+ modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL);
+ offsets = kcalloc(connector_count, sizeof(*offsets), GFP_KERNEL);
+ enabled = kcalloc(connector_count, sizeof(bool), GFP_KERNEL);
+ if (!crtcs || !modes || !enabled || !offsets) {
+ DRM_ERROR("Memory allocation failed\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ mutex_lock(&client->modeset_mutex);
+
+ mutex_lock(&dev->mode_config.mutex);
+ for (i = 0; i < connector_count; i++)
+ total_modes_count += connectors[i]->funcs->fill_modes(connectors[i], width, height);
+ if (!total_modes_count)
+ DRM_DEBUG_KMS("No connectors reported connected with modes\n");
+ drm_client_connectors_enabled(connectors, connector_count, enabled);
+
+ if (!drm_client_firmware_config(client, connectors, connector_count, crtcs,
+ modes, offsets, enabled, width, height)) {
+ memset(modes, 0, connector_count * sizeof(*modes));
+ memset(crtcs, 0, connector_count * sizeof(*crtcs));
+ memset(offsets, 0, connector_count * sizeof(*offsets));
+
+ if (!drm_client_target_cloned(dev, connectors, connector_count, modes,
+ offsets, enabled, width, height) &&
+ !drm_client_target_preferred(connectors, connector_count, modes,
+ offsets, enabled, width, height))
+ DRM_ERROR("Unable to find initial modes\n");
+
+ DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n",
+ width, height);
+
+ drm_client_pick_crtcs(client, connectors, connector_count,
+ crtcs, modes, 0, width, height);
+ }
+ mutex_unlock(&dev->mode_config.mutex);
+
+ drm_client_modeset_release(client);
+
+ for (i = 0; i < connector_count; i++) {
+ struct drm_display_mode *mode = modes[i];
+ struct drm_crtc *crtc = crtcs[i];
+ struct drm_client_offset *offset = &offsets[i];
+
+ if (mode && crtc) {
+ struct drm_mode_set *modeset = drm_client_find_modeset(client, crtc);
+ struct drm_connector *connector = connectors[i];
+
+ DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
+ mode->name, crtc->base.id, offset->x, offset->y);
+
+ if (WARN_ON_ONCE(modeset->num_connectors == DRM_CLIENT_MAX_CLONED_CONNECTORS ||
+ (dev->mode_config.num_crtc > 1 && modeset->num_connectors == 1))) {
+ ret = -EINVAL;
+ break;
+ }
+
+ modeset->mode = drm_mode_duplicate(dev, mode);
+ drm_connector_get(connector);
+ modeset->connectors[modeset->num_connectors++] = connector;
+ modeset->x = offset->x;
+ modeset->y = offset->y;
+ }
+ }
+
+ mutex_unlock(&client->modeset_mutex);
+out:
+ kfree(crtcs);
+ kfree(modes);
+ kfree(offsets);
+ kfree(enabled);
+free_connectors:
+ for (i = 0; i < connector_count; i++)
+ drm_connector_put(connectors[i]);
+ kfree(connectors);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_client_modeset_probe);
/**
* drm_client_panel_rotation() - Check panel orientation
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index e7f41e5d924c..946cae196475 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -48,10 +48,6 @@
#include "drm_internal.h"
-struct drm_client_offset {
- int x, y;
-};
-
static bool drm_fbdev_emulation = true;
module_param_named(fbdev_emulation, drm_fbdev_emulation, bool, 0600);
MODULE_PARM_DESC(fbdev_emulation,
@@ -1703,694 +1699,6 @@ void drm_fb_helper_fill_info(struct fb_info *info,
}
EXPORT_SYMBOL(drm_fb_helper_fill_info);
-static struct drm_display_mode *
-drm_connector_has_preferred_mode(struct drm_connector *connector, int width, int height)
-{
- struct drm_display_mode *mode;
-
- list_for_each_entry(mode, &connector->modes, head) {
- if (mode->hdisplay > width ||
- mode->vdisplay > height)
- continue;
- if (mode->type & DRM_MODE_TYPE_PREFERRED)
- return mode;
- }
- return NULL;
-}
-
-static struct drm_display_mode *
-drm_connector_pick_cmdline_mode(struct drm_connector *connector)
-{
- struct drm_cmdline_mode *cmdline_mode;
- struct drm_display_mode *mode;
- bool prefer_non_interlace;
-
- cmdline_mode = &connector->cmdline_mode;
- if (cmdline_mode->specified == false)
- return NULL;
-
- /* attempt to find a matching mode in the list of modes
- * we have gotten so far, if not add a CVT mode that conforms
- */
- if (cmdline_mode->rb || cmdline_mode->margins)
- goto create_mode;
-
- prefer_non_interlace = !cmdline_mode->interlace;
-again:
- list_for_each_entry(mode, &connector->modes, head) {
- /* check width/height */
- if (mode->hdisplay != cmdline_mode->xres ||
- mode->vdisplay != cmdline_mode->yres)
- continue;
-
- if (cmdline_mode->refresh_specified) {
- if (mode->vrefresh != cmdline_mode->refresh)
- continue;
- }
-
- if (cmdline_mode->interlace) {
- if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
- continue;
- } else if (prefer_non_interlace) {
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- continue;
- }
- return mode;
- }
-
- if (prefer_non_interlace) {
- prefer_non_interlace = false;
- goto again;
- }
-
-create_mode:
- mode = drm_mode_create_from_cmdline_mode(connector->dev, cmdline_mode);
- list_add(&mode->head, &connector->modes);
-
- return mode;
-}
-
-static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
-{
- bool enable;
-
- if (connector->display_info.non_desktop)
- return false;
-
- if (strict)
- enable = connector->status == connector_status_connected;
- else
- enable = connector->status != connector_status_disconnected;
-
- return enable;
-}
-
-static void drm_client_connectors_enabled(struct drm_connector **connectors,
- unsigned int connector_count,
- bool *enabled)
-{
- bool any_enabled = false;
- struct drm_connector *connector;
- int i = 0;
-
- for (i = 0; i < connector_count; i++) {
- connector = connectors[i];
- enabled[i] = drm_connector_enabled(connector, true);
- DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
- connector->display_info.non_desktop ? "non desktop" : enabled[i] ? "yes" : "no");
-
- any_enabled |= enabled[i];
- }
-
- if (any_enabled)
- return;
-
- for (i = 0; i < connector_count; i++)
- enabled[i] = drm_connector_enabled(connectors[i], false);
-}
-
-static bool drm_client_target_cloned(struct drm_device *dev,
- struct drm_connector **connectors,
- unsigned int connector_count,
- struct drm_display_mode **modes,
- struct drm_client_offset *offsets,
- bool *enabled, int width, int height)
-{
- int count, i, j;
- bool can_clone = false;
- struct drm_display_mode *dmt_mode, *mode;
-
- /* only contemplate cloning in the single crtc case */
- if (dev->mode_config.num_crtc > 1)
- return false;
-
- count = 0;
- for (i = 0; i < 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 < connector_count; i++) {
- if (!enabled[i])
- continue;
- modes[i] = drm_connector_pick_cmdline_mode(connectors[i]);
- if (!modes[i]) {
- can_clone = false;
- break;
- }
- for (j = 0; j < i; j++) {
- if (!enabled[j])
- continue;
- if (!drm_mode_match(modes[j], modes[i],
- DRM_MODE_MATCH_TIMINGS |
- DRM_MODE_MATCH_CLOCK |
- DRM_MODE_MATCH_FLAGS |
- DRM_MODE_MATCH_3D_FLAGS))
- 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(dev, 1024, 768, 60, false);
-
- for (i = 0; i < connector_count; i++) {
- if (!enabled[i])
- continue;
-
- list_for_each_entry(mode, &connectors[i]->modes, head) {
- if (drm_mode_match(mode, dmt_mode,
- DRM_MODE_MATCH_TIMINGS |
- DRM_MODE_MATCH_CLOCK |
- DRM_MODE_MATCH_FLAGS |
- DRM_MODE_MATCH_3D_FLAGS))
- modes[i] = mode;
- }
- if (!modes[i])
- can_clone = false;
- }
-
- if (can_clone) {
- DRM_DEBUG_KMS("can clone using 1024x768\n");
- return true;
- }
- DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
- return false;
-}
-
-static int drm_client_get_tile_offsets(struct drm_connector **connectors,
- unsigned int connector_count,
- struct drm_display_mode **modes,
- struct drm_client_offset *offsets,
- int idx,
- int h_idx, int v_idx)
-{
- struct drm_connector *connector;
- int i;
- int hoffset = 0, voffset = 0;
-
- for (i = 0; i < connector_count; i++) {
- connector = connectors[i];
- if (!connector->has_tile)
- continue;
-
- if (!modes[i] && (h_idx || v_idx)) {
- DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i,
- connector->base.id);
- continue;
- }
- if (connector->tile_h_loc < h_idx)
- hoffset += modes[i]->hdisplay;
-
- if (connector->tile_v_loc < v_idx)
- voffset += modes[i]->vdisplay;
- }
- offsets[idx].x = hoffset;
- offsets[idx].y = voffset;
- DRM_DEBUG_KMS("returned %d %d for %d %d\n", hoffset, voffset, h_idx, v_idx);
- return 0;
-}
-
-static bool drm_client_target_preferred(struct drm_connector **connectors,
- unsigned int connector_count,
- struct drm_display_mode **modes,
- struct drm_client_offset *offsets,
- bool *enabled, int width, int height)
-{
- const u64 mask = BIT_ULL(connector_count) - 1;
- struct drm_connector *connector;
- u64 conn_configured = 0;
- int tile_pass = 0;
- int i;
-
-retry:
- for (i = 0; i < connector_count; i++) {
- connector = connectors[i];
-
- if (conn_configured & BIT_ULL(i))
- continue;
-
- if (enabled[i] == false) {
- conn_configured |= BIT_ULL(i);
- continue;
- }
-
- /* first pass over all the untiled connectors */
- if (tile_pass == 0 && connector->has_tile)
- continue;
-
- if (tile_pass == 1) {
- if (connector->tile_h_loc != 0 ||
- connector->tile_v_loc != 0)
- continue;
-
- } else {
- if (connector->tile_h_loc != tile_pass - 1 &&
- connector->tile_v_loc != tile_pass - 1)
- /* if this tile_pass doesn't cover any of the tiles - keep going */
- continue;
-
- /*
- * find the tile offsets for this pass - need to find
- * all tiles left and above
- */
- drm_client_get_tile_offsets(connectors, connector_count, modes, offsets, i,
- connector->tile_h_loc, connector->tile_v_loc);
- }
- DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
- connector->base.id);
-
- /* got for command line mode first */
- modes[i] = drm_connector_pick_cmdline_mode(connector);
- if (!modes[i]) {
- DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n",
- connector->base.id, connector->tile_group ? connector->tile_group->id : 0);
- modes[i] = drm_connector_has_preferred_mode(connector, width, height);
- }
- /* No preferred modes, pick one off the list */
- if (!modes[i] && !list_empty(&connector->modes)) {
- list_for_each_entry(modes[i], &connector->modes, head)
- break;
- }
- DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
- "none");
- conn_configured |= BIT_ULL(i);
- }
-
- if ((conn_configured & mask) != mask) {
- tile_pass++;
- goto retry;
- }
- return true;
-}
-
-static bool connector_has_possible_crtc(struct drm_connector *connector,
- struct drm_crtc *crtc)
-{
- struct drm_encoder *encoder;
- int i;
-
- drm_connector_for_each_possible_encoder(connector, encoder, i) {
- if (encoder->possible_crtcs & drm_crtc_mask(crtc))
- return true;
- }
-
- return false;
-}
-
-static int drm_client_pick_crtcs(struct drm_client_dev *client,
- struct drm_connector **connectors,
- unsigned int connector_count,
- struct drm_crtc **best_crtcs,
- struct drm_display_mode **modes,
- int n, int width, int height)
-{
- struct drm_device *dev = client->dev;
- struct drm_connector *connector;
- int my_score, best_score, score;
- struct drm_crtc **crtcs, *crtc;
- struct drm_mode_set *modeset;
- int o;
-
- if (n == connector_count)
- return 0;
-
- connector = connectors[n];
-
- best_crtcs[n] = NULL;
- best_score = drm_client_pick_crtcs(client, connectors, connector_count,
- best_crtcs, modes, n + 1, width, height);
- if (modes[n] == NULL)
- return best_score;
-
- crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
- if (!crtcs)
- return best_score;
-
- my_score = 1;
- if (connector->status == connector_status_connected)
- my_score++;
- if (connector->cmdline_mode.specified)
- my_score++;
- if (drm_connector_has_preferred_mode(connector, width, height))
- my_score++;
-
- /*
- * select a crtc for this connector and then attempt to configure
- * remaining connectors
- */
- drm_client_for_each_modeset(modeset, client) {
- crtc = modeset->crtc;
-
- if (!connector_has_possible_crtc(connector, crtc))
- continue;
-
- for (o = 0; o < n; o++)
- if (best_crtcs[o] == crtc)
- break;
-
- if (o < n) {
- /* ignore cloning unless only a single crtc */
- if (dev->mode_config.num_crtc > 1)
- continue;
-
- if (!drm_mode_equal(modes[o], modes[n]))
- continue;
- }
-
- crtcs[n] = crtc;
- memcpy(crtcs, best_crtcs, n * sizeof(*crtcs));
- score = my_score + drm_client_pick_crtcs(client, connectors, connector_count,
- crtcs, modes, n + 1, width, height);
- if (score > best_score) {
- best_score = score;
- memcpy(best_crtcs, crtcs, connector_count * sizeof(*crtcs));
- }
- }
-
- kfree(crtcs);
- return best_score;
-}
-
-/* Try to read the BIOS display configuration and use it for the initial config */
-static bool drm_client_firmware_config(struct drm_client_dev *client,
- struct drm_connector **connectors,
- unsigned int connector_count,
- struct drm_crtc **crtcs,
- struct drm_display_mode **modes,
- struct drm_client_offset *offsets,
- bool *enabled, int width, int height)
-{
- unsigned int count = min_t(unsigned int, connector_count, BITS_PER_LONG);
- unsigned long conn_configured, conn_seq, mask;
- struct drm_device *dev = client->dev;
- int i, j;
- bool *save_enabled;
- bool fallback = true, ret = true;
- int num_connectors_enabled = 0;
- int num_connectors_detected = 0;
- struct drm_modeset_acquire_ctx ctx;
-
- if (!drm_drv_uses_atomic_modeset(dev))
- return false;
-
- save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
- if (!save_enabled)
- return false;
-
- drm_modeset_acquire_init(&ctx, 0);
-
- while (drm_modeset_lock_all_ctx(dev, &ctx) != 0)
- drm_modeset_backoff(&ctx);
-
- memcpy(save_enabled, enabled, count);
- mask = GENMASK(count - 1, 0);
- conn_configured = 0;
-retry:
- conn_seq = conn_configured;
- for (i = 0; i < count; i++) {
- struct drm_connector *connector;
- struct drm_encoder *encoder;
- struct drm_crtc *new_crtc;
-
- connector = connectors[i];
-
- if (conn_configured & BIT(i))
- continue;
-
- if (conn_seq == 0 && !connector->has_tile)
- continue;
-
- if (connector->status == connector_status_connected)
- num_connectors_detected++;
-
- if (!enabled[i]) {
- DRM_DEBUG_KMS("connector %s not enabled, skipping\n",
- connector->name);
- conn_configured |= BIT(i);
- continue;
- }
-
- if (connector->force == DRM_FORCE_OFF) {
- DRM_DEBUG_KMS("connector %s is disabled by user, skipping\n",
- connector->name);
- enabled[i] = false;
- continue;
- }
-
- encoder = connector->state->best_encoder;
- if (!encoder || WARN_ON(!connector->state->crtc)) {
- if (connector->force > DRM_FORCE_OFF)
- goto bail;
-
- DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n",
- connector->name);
- enabled[i] = false;
- conn_configured |= BIT(i);
- continue;
- }
-
- num_connectors_enabled++;
-
- new_crtc = connector->state->crtc;
-
- /*
- * Make sure we're not trying to drive multiple connectors
- * with a single CRTC, since our cloning support may not
- * match the BIOS.
- */
- for (j = 0; j < count; j++) {
- if (crtcs[j] == new_crtc) {
- DRM_DEBUG_KMS("fallback: cloned configuration\n");
- goto bail;
- }
- }
-
- DRM_DEBUG_KMS("looking for cmdline mode on connector %s\n",
- connector->name);
-
- /* go for command line mode first */
- modes[i] = drm_connector_pick_cmdline_mode(connector);
-
- /* try for preferred next */
- if (!modes[i]) {
- DRM_DEBUG_KMS("looking for preferred mode on connector %s %d\n",
- connector->name, connector->has_tile);
- modes[i] = drm_connector_has_preferred_mode(connector, width, height);
- }
-
- /* No preferred mode marked by the EDID? Are there any modes? */
- if (!modes[i] && !list_empty(&connector->modes)) {
- DRM_DEBUG_KMS("using first mode listed on connector %s\n",
- connector->name);
- modes[i] = list_first_entry(&connector->modes,
- struct drm_display_mode,
- head);
- }
-
- /* last resort: use current mode */
- if (!modes[i]) {
- /*
- * IMPORTANT: We want to use the adjusted mode (i.e.
- * after the panel fitter upscaling) as the initial
- * config, not the input mode, which is what crtc->mode
- * usually contains. But since our current
- * code puts a mode derived from the post-pfit timings
- * into crtc->mode this works out correctly.
- *
- * This is crtc->mode and not crtc->state->mode for the
- * fastboot check to work correctly.
- */
- DRM_DEBUG_KMS("looking for current mode on connector %s\n",
- connector->name);
- modes[i] = &connector->state->crtc->mode;
- }
- crtcs[i] = new_crtc;
-
- DRM_DEBUG_KMS("connector %s on [CRTC:%d:%s]: %dx%d%s\n",
- connector->name,
- connector->state->crtc->base.id,
- connector->state->crtc->name,
- modes[i]->hdisplay, modes[i]->vdisplay,
- modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "");
-
- fallback = false;
- conn_configured |= BIT(i);
- }
-
- if ((conn_configured & mask) != mask && conn_configured != conn_seq)
- goto retry;
-
- /*
- * If the BIOS didn't enable everything it could, fall back to have the
- * same user experiencing of lighting up as much as possible like the
- * fbdev helper library.
- */
- if (num_connectors_enabled != num_connectors_detected &&
- num_connectors_enabled < dev->mode_config.num_crtc) {
- DRM_DEBUG_KMS("fallback: Not all outputs enabled\n");
- DRM_DEBUG_KMS("Enabled: %i, detected: %i\n", num_connectors_enabled,
- num_connectors_detected);
- fallback = true;
- }
-
- if (fallback) {
-bail:
- DRM_DEBUG_KMS("Not using firmware configuration\n");
- memcpy(enabled, save_enabled, count);
- ret = false;
- }
-
- drm_modeset_drop_locks(&ctx);
- drm_modeset_acquire_fini(&ctx);
-
- kfree(save_enabled);
- return ret;
-}
-
-/**
- * drm_client_modeset_probe() - Probe for displays
- * @client: DRM client
- * @width: Maximum display mode width (optional)
- * @height: Maximum display mode height (optional)
- *
- * This function sets up display pipelines for enabled connectors and stores the
- * config in the client's modeset array.
- *
- * Returns:
- * Zero on success or negative error code on failure.
- */
-int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height)
-{
- struct drm_connector *connector, **connectors = NULL;
- struct drm_connector_list_iter conn_iter;
- struct drm_device *dev = client->dev;
- unsigned int total_modes_count = 0;
- struct drm_client_offset *offsets;
- unsigned int connector_count = 0;
- struct drm_display_mode **modes;
- struct drm_crtc **crtcs;
- int i, ret = 0;
- bool *enabled;
-
- DRM_DEBUG_KMS("\n");
-
- if (!width)
- width = dev->mode_config.max_width;
- if (!height)
- height = dev->mode_config.max_height;
-
- drm_connector_list_iter_begin(dev, &conn_iter);
- drm_client_for_each_connector_iter(connector, &conn_iter) {
- struct drm_connector **tmp;
-
- tmp = krealloc(connectors, (connector_count + 1) * sizeof(*connectors), GFP_KERNEL);
- if (!tmp) {
- ret = -ENOMEM;
- goto free_connectors;
- }
-
- connectors = tmp;
- drm_connector_get(connector);
- connectors[connector_count++] = connector;
- }
- drm_connector_list_iter_end(&conn_iter);
-
- if (!connector_count)
- return 0;
-
- crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
- modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL);
- offsets = kcalloc(connector_count, sizeof(*offsets), GFP_KERNEL);
- enabled = kcalloc(connector_count, sizeof(bool), GFP_KERNEL);
- if (!crtcs || !modes || !enabled || !offsets) {
- DRM_ERROR("Memory allocation failed\n");
- ret = -ENOMEM;
- goto out;
- }
-
- mutex_lock(&client->modeset_mutex);
-
- mutex_lock(&dev->mode_config.mutex);
- for (i = 0; i < connector_count; i++)
- total_modes_count += connectors[i]->funcs->fill_modes(connectors[i], width, height);
- if (!total_modes_count)
- DRM_DEBUG_KMS("No connectors reported connected with modes\n");
- drm_client_connectors_enabled(connectors, connector_count, enabled);
-
- if (!drm_client_firmware_config(client, connectors, connector_count, crtcs,
- modes, offsets, enabled, width, height)) {
- memset(modes, 0, connector_count * sizeof(*modes));
- memset(crtcs, 0, connector_count * sizeof(*crtcs));
- memset(offsets, 0, connector_count * sizeof(*offsets));
-
- if (!drm_client_target_cloned(dev, connectors, connector_count, modes,
- offsets, enabled, width, height) &&
- !drm_client_target_preferred(connectors, connector_count, modes,
- offsets, enabled, width, height))
- DRM_ERROR("Unable to find initial modes\n");
-
- DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n",
- width, height);
-
- drm_client_pick_crtcs(client, connectors, connector_count,
- crtcs, modes, 0, width, height);
- }
- mutex_unlock(&dev->mode_config.mutex);
-
- drm_client_modeset_release(client);
-
- for (i = 0; i < connector_count; i++) {
- struct drm_display_mode *mode = modes[i];
- struct drm_crtc *crtc = crtcs[i];
- struct drm_client_offset *offset = &offsets[i];
-
- if (mode && crtc) {
- struct drm_mode_set *modeset = drm_client_find_modeset(client, crtc);
- struct drm_connector *connector = connectors[i];
-
- DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
- mode->name, crtc->base.id, offset->x, offset->y);
-
- if (WARN_ON_ONCE(modeset->num_connectors == DRM_CLIENT_MAX_CLONED_CONNECTORS ||
- (dev->mode_config.num_crtc > 1 && modeset->num_connectors == 1))) {
- ret = -EINVAL;
- break;
- }
-
- modeset->mode = drm_mode_duplicate(dev, mode);
- drm_connector_get(connector);
- modeset->connectors[modeset->num_connectors++] = connector;
- modeset->x = offset->x;
- modeset->y = offset->y;
- }
- }
-
- mutex_unlock(&client->modeset_mutex);
-out:
- kfree(crtcs);
- kfree(modes);
- kfree(offsets);
- kfree(enabled);
-free_connectors:
- for (i = 0; i < connector_count; i++)
- drm_connector_put(connectors[i]);
- kfree(connectors);
-
- return ret;
-}
-
/*
* This is a continuation of drm_setup_crtcs() that sets up anything related
* to the framebuffer. During initialization, drm_setup_crtcs() is called before
diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
index 8d94880bbe25..f2d5ed745733 100644
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -18,8 +18,6 @@ struct drm_gem_object;
struct drm_minor;
struct module;
-#define DRM_CLIENT_MAX_CLONED_CONNECTORS 8
-
/**
* struct drm_client_funcs - DRM client callbacks
*/
@@ -154,8 +152,7 @@ void drm_client_framebuffer_delete(struct drm_client_buffer *buffer);
int drm_client_modeset_create(struct drm_client_dev *client);
void drm_client_modeset_free(struct drm_client_dev *client);
-void drm_client_modeset_release(struct drm_client_dev *client);
-struct drm_mode_set *drm_client_find_modeset(struct drm_client_dev *client, struct drm_crtc *crtc);
+int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height);
bool drm_client_panel_rotation(struct drm_mode_set *modeset, unsigned int *rotation);
int drm_client_modeset_commit_force(struct drm_client_dev *client);
int drm_client_modeset_commit(struct drm_client_dev *client);
--
2.20.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v8 4/5] drm/client: Hack: Add bootsplash example
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
` (2 preceding siblings ...)
2019-06-08 15:26 ` [PATCH v8 3/5] drm/fb-helper: Move " Noralf Trønnes
@ 2019-06-08 15:26 ` Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 5/5] drm/todo: Add bootsplash entry Noralf Trønnes
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Noralf Trønnes @ 2019-06-08 15:26 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx, Noralf Trønnes, sam
An example to showcase the client API.
TODO:
- A bootsplash client needs a way to tell drm_fb_helper to stay away,
otherwise it will chime in on setup and hotplug.
Most DRM drivers register fbdev before calling drm_dev_register() (the
generic emulation is an exception). This have to be reversed for
bootsplash to fend off fbdev.
- Probably need some way to determine which is the primary display/device
on multi DRM device systems.
- Maybe do handover from early/simple DRM driver
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
drivers/gpu/drm/Kconfig | 5 +
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/drm_bootsplash.c | 358 +++++++++++++++++++++++++++++++
drivers/gpu/drm/drm_client.c | 7 +
drivers/gpu/drm/drm_drv.c | 4 +
include/drm/drm_client.h | 3 +
6 files changed, 378 insertions(+)
create mode 100644 drivers/gpu/drm/drm_bootsplash.c
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 6b34949416b1..d77a67cf3a89 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -66,6 +66,11 @@ config DRM_DEBUG_SELFTEST
If in doubt, say "N".
+config DRM_CLIENT_BOOTSPLASH
+ bool "DRM Bootsplash"
+ help
+ DRM Bootsplash
+
config DRM_KMS_HELPER
tristate
depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index d36feb4a6233..86a2ceb95838 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -31,6 +31,7 @@ drm-$(CONFIG_OF) += drm_of.o
drm-$(CONFIG_AGP) += drm_agpsupport.o
drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
+drm-$(CONFIG_DRM_CLIENT_BOOTSPLASH) += drm_bootsplash.o
drm_vram_helper-y := drm_gem_vram_helper.o \
drm_vram_helper_common.o \
diff --git a/drivers/gpu/drm/drm_bootsplash.c b/drivers/gpu/drm/drm_bootsplash.c
new file mode 100644
index 000000000000..f58ee19e268f
--- /dev/null
+++ b/drivers/gpu/drm/drm_bootsplash.c
@@ -0,0 +1,358 @@
+/* DRM internal client example */
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/keyboard.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+
+#include <drm/drm_client.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_print.h>
+
+// drm_lastclose()
+#include "drm_internal.h"
+
+static bool drm_bootsplash_enabled = true;
+module_param_named(bootsplash_enabled, drm_bootsplash_enabled, bool, 0600);
+MODULE_PARM_DESC(bootsplash_enabled, "Enable bootsplash client [default=true]");
+
+struct drm_bootsplash {
+ struct drm_client_dev client;
+ struct mutex lock;
+ struct work_struct worker;
+ struct drm_client_buffer *buffers[2];
+ bool started;
+ bool stop;
+};
+
+static bool drm_bootsplash_key_pressed;
+
+static int drm_bootsplash_keyboard_notifier_call(struct notifier_block *blk,
+ unsigned long code, void *_param)
+{
+ /* Any key is good */
+ drm_bootsplash_key_pressed = true;
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block drm_bootsplash_keyboard_notifier_block = {
+ .notifier_call = drm_bootsplash_keyboard_notifier_call,
+};
+
+static void drm_bootsplash_buffer_delete(struct drm_bootsplash *splash)
+{
+ unsigned int i;
+
+ for (i = 0; i < 2; i++) {
+ if (!IS_ERR_OR_NULL(splash->buffers[i]))
+ drm_client_framebuffer_delete(splash->buffers[i]);
+ splash->buffers[i] = NULL;
+ }
+}
+
+static int drm_bootsplash_buffer_create(struct drm_bootsplash *splash, u32 width, u32 height)
+{
+ unsigned int i;
+
+ for (i = 0; i < 2; i++) {
+ splash->buffers[i] = drm_client_framebuffer_create(&splash->client, width, height, DRM_FORMAT_XRGB8888);
+ if (IS_ERR(splash->buffers[i])) {
+ drm_bootsplash_buffer_delete(splash);
+ return PTR_ERR(splash->buffers[i]);
+ }
+ }
+
+ return 0;
+}
+
+static int drm_bootsplash_display_probe(struct drm_bootsplash *splash)
+{
+ struct drm_client_dev *client = &splash->client;
+ unsigned int width = 0, height = 0;
+ unsigned int num_non_tiled = 0, i;
+ unsigned int modeset_mask = 0;
+ struct drm_mode_set *modeset;
+ bool tiled = false;
+ int ret;
+
+ ret = drm_client_modeset_probe(client, 0, 0);
+ if (ret)
+ return ret;
+
+ mutex_lock(&client->modeset_mutex);
+
+ drm_client_for_each_modeset(modeset, client) {
+ if (!modeset->mode)
+ continue;
+
+ if (modeset->connectors[0]->has_tile)
+ tiled = true;
+ else
+ num_non_tiled++;
+ }
+
+ if (!tiled && !num_non_tiled) {
+ drm_bootsplash_buffer_delete(splash);
+ ret = -ENOENT;
+ goto out;
+ }
+
+ /* Assume only one tiled monitor is possible */
+ if (tiled) {
+ int hdisplay = 0, vdisplay = 0;
+
+ i = 0;
+ drm_client_for_each_modeset(modeset, client) {
+ i++;
+ if (!modeset->connectors[0]->has_tile)
+ continue;
+
+ if (!modeset->y)
+ hdisplay += modeset->mode->hdisplay;
+ if (!modeset->x)
+ vdisplay += modeset->mode->vdisplay;
+ modeset_mask |= BIT(i - 1);
+ }
+
+ width = hdisplay;
+ height = vdisplay;
+
+ goto trim;
+ }
+
+ /* The rest have one display (maybe cloned) per modeset, pick the largest */
+ i = 0;
+ drm_client_for_each_modeset(modeset, client) {
+ i++;
+ if (!modeset->mode || modeset->connectors[0]->has_tile)
+ continue;
+
+ if (modeset->mode->hdisplay * modeset->mode->vdisplay > width * height) {
+ width = modeset->mode->hdisplay;
+ height = modeset->mode->vdisplay;
+ modeset_mask = BIT(i - 1);
+ }
+ }
+
+trim:
+ /* Remove unused modesets (warning in __drm_atomic_helper_set_config()) */
+ i = 0;
+ drm_client_for_each_modeset(modeset, client) {
+ unsigned int j;
+
+ if (modeset_mask & BIT(i++))
+ continue;
+ drm_mode_destroy(client->dev, modeset->mode);
+ modeset->mode = NULL;
+
+ for (j = 0; j < modeset->num_connectors; j++) {
+ drm_connector_put(modeset->connectors[j]);
+ modeset->connectors[j] = NULL;
+ }
+ modeset->num_connectors = 0;
+ }
+
+ if (!splash->buffers[0] ||
+ splash->buffers[0]->fb->width != width ||
+ splash->buffers[0]->fb->height != height) {
+ drm_bootsplash_buffer_delete(splash);
+ ret = drm_bootsplash_buffer_create(splash, width, height);
+ }
+
+out:
+ mutex_unlock(&client->modeset_mutex);
+
+ return ret;
+}
+
+static int drm_bootsplash_display_commit_buffer(struct drm_bootsplash *splash, unsigned int num)
+{
+ struct drm_client_dev *client = &splash->client;
+ struct drm_mode_set *modeset;
+
+ mutex_lock(&client->modeset_mutex);
+ drm_client_for_each_modeset(modeset, client) {
+ if (modeset->mode)
+ modeset->fb = splash->buffers[num]->fb;
+ }
+ mutex_unlock(&client->modeset_mutex);
+
+ return drm_client_modeset_commit(client);
+}
+
+static u32 drm_bootsplash_color_table[3] = {
+ 0x00ff0000, 0x0000ff00, 0x000000ff,
+};
+
+/* Draw a box with changing colors */
+static void drm_bootsplash_draw_box(struct drm_client_buffer *buffer, unsigned int sequence)
+{
+ unsigned int width = buffer->fb->width;
+ unsigned int height = buffer->fb->height;
+ unsigned int x, y;
+ u32 *pix;
+
+ pix = buffer->vaddr;
+ pix += ((height / 2) - 50) * width;
+ pix += (width / 2) - 50;
+
+ for (y = 0; y < 100; y++) {
+ for (x = 0; x < 100; x++)
+ *pix++ = drm_bootsplash_color_table[sequence];
+ pix += width - 100;
+ }
+}
+
+static int drm_bootsplash_draw(struct drm_bootsplash *splash, unsigned int sequence, unsigned int buffer_num)
+{
+ if (!splash->buffers[buffer_num])
+ return -ENOENT;
+
+ DRM_DEBUG_KMS("draw: buffer_num=%u, sequence=%u\n", buffer_num, sequence);
+
+ drm_bootsplash_draw_box(splash->buffers[buffer_num], sequence);
+
+ return drm_bootsplash_display_commit_buffer(splash, buffer_num);
+}
+
+static void drm_bootsplash_worker(struct work_struct *work)
+{
+ struct drm_bootsplash *splash = container_of(work, struct drm_bootsplash, worker);
+ struct drm_client_dev *client = &splash->client;
+ struct drm_device *dev = client->dev;
+ unsigned int buffer_num = 0, sequence = 0;
+ bool stop = false;
+ int ret = 0;
+
+ while (!drm_bootsplash_key_pressed) {
+ mutex_lock(&splash->lock);
+
+ stop = splash->stop;
+
+ buffer_num = !buffer_num;
+
+ ret = drm_bootsplash_draw(splash, sequence, buffer_num);
+
+ mutex_unlock(&splash->lock);
+
+ if (stop || ret == -ENOENT || ret == -EBUSY)
+ break;
+
+ if (++sequence == 3)
+ sequence = 0;
+
+ msleep(500);
+ }
+
+ /* Restore fbdev (or other) on key press. */
+ /* TODO: Check if it's OK to call drm_lastclose here. */
+ if (drm_bootsplash_key_pressed && !splash->stop)
+ drm_lastclose(dev);
+
+ drm_bootsplash_buffer_delete(splash);
+
+ DRM_DEV_DEBUG_KMS(dev->dev, "Bootsplash has stopped (key=%u stop=%u, ret=%d).\n",
+ drm_bootsplash_key_pressed, splash->stop, ret);
+}
+
+static int drm_bootsplash_client_hotplug(struct drm_client_dev *client)
+{
+ struct drm_bootsplash *splash = container_of(client, struct drm_bootsplash, client);
+ int ret = 0;
+
+ if (drm_bootsplash_key_pressed)
+ return 0;
+
+ mutex_lock(&splash->lock);
+
+ if (splash->stop)
+ goto out_unlock;
+
+ ret = drm_bootsplash_display_probe(splash);
+ if (ret < 0) {
+ if (splash->started && ret == -ENOENT)
+ splash->stop = true;
+ goto out_unlock;
+ }
+
+ /*
+ * TODO: Deal with rotated panels, might have to sw rotate
+ if (drm_client_panel_rotation(...))
+ */
+
+ if (!splash->started) {
+ splash->started = true;
+ schedule_work(&splash->worker);
+ }
+
+out_unlock:
+ mutex_unlock(&splash->lock);
+
+ return ret;
+}
+
+static void drm_bootsplash_client_unregister(struct drm_client_dev *client)
+{
+ struct drm_bootsplash *splash = container_of(client, struct drm_bootsplash, client);
+
+ DRM_DEBUG_KMS("%s: IN\n", __func__);
+
+ mutex_lock(&splash->lock);
+ splash->stop = true;
+ mutex_unlock(&splash->lock);
+
+ flush_work(&splash->worker);
+
+ drm_client_release(client);
+ kfree(splash);
+
+ unregister_keyboard_notifier(&drm_bootsplash_keyboard_notifier_block);
+
+ DRM_DEBUG_KMS("%s: OUT\n", __func__);
+}
+
+static const struct drm_client_funcs drm_bootsplash_client_funcs = {
+ .owner = THIS_MODULE,
+ .unregister = drm_bootsplash_client_unregister,
+ .hotplug = drm_bootsplash_client_hotplug,
+};
+
+void drm_bootsplash_client_register(struct drm_device *dev)
+{
+ struct drm_bootsplash *splash;
+ int ret;
+
+ if (!drm_bootsplash_enabled)
+ return;
+
+ splash = kzalloc(sizeof(*splash), GFP_KERNEL);
+ if (!splash)
+ return;
+
+ ret = drm_client_init(dev, &splash->client, "bootsplash", &drm_bootsplash_client_funcs);
+ if (ret) {
+ DRM_DEV_ERROR(dev->dev, "Failed to create client, ret=%d\n", ret);
+ kfree(splash);
+ return;
+ }
+
+ /* For this simple example only allow the first */
+ drm_bootsplash_enabled = false;
+
+ mutex_init(&splash->lock);
+
+ INIT_WORK(&splash->worker, drm_bootsplash_worker);
+
+ register_keyboard_notifier(&drm_bootsplash_keyboard_notifier_block);
+
+ drm_bootsplash_client_hotplug(&splash->client);
+
+ drm_client_register(&splash->client);
+}
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 410572f14257..2813b0cbdf39 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -161,6 +161,13 @@ void drm_client_release(struct drm_client_dev *client)
}
EXPORT_SYMBOL(drm_client_release);
+void drm_client_dev_register(struct drm_device *dev)
+{
+#if CONFIG_DRM_CLIENT_BOOTSPLASH
+ drm_bootsplash_client_register(dev);
+#endif
+}
+
void drm_client_dev_unregister(struct drm_device *dev)
{
struct drm_client_dev *client, *tmp;
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 95a55d98e152..754e34aed92e 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -1017,6 +1017,10 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
drm_minor_unregister(dev, DRM_MINOR_RENDER);
out_unlock:
mutex_unlock(&drm_global_mutex);
+
+ if (!ret)
+ drm_client_dev_register(dev);
+
return ret;
}
EXPORT_SYMBOL(drm_dev_register);
diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
index f2d5ed745733..e9eb770093fb 100644
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -107,6 +107,7 @@ int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
void drm_client_release(struct drm_client_dev *client);
void drm_client_register(struct drm_client_dev *client);
+void drm_client_dev_register(struct drm_device *dev);
void drm_client_dev_unregister(struct drm_device *dev);
void drm_client_dev_hotplug(struct drm_device *dev);
void drm_client_dev_restore(struct drm_device *dev);
@@ -183,4 +184,6 @@ int drm_client_modeset_dpms(struct drm_client_dev *client, int mode);
int drm_client_debugfs_init(struct drm_minor *minor);
+void drm_bootsplash_client_register(struct drm_device *dev);
+
#endif
--
2.20.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v8 5/5] drm/todo: Add bootsplash entry
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
` (3 preceding siblings ...)
2019-06-08 15:26 ` [PATCH v8 4/5] drm/client: Hack: Add bootsplash example Noralf Trønnes
@ 2019-06-08 15:26 ` Noralf Trønnes
2019-06-10 10:18 ` ✗ Fi.CI.CHECKPATCH: warning for drm/fb-helper: Move modesetting code to drm_client (rev9) Patchwork
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Noralf Trønnes @ 2019-06-08 15:26 UTC (permalink / raw)
To: dri-devel; +Cc: Paul Kocialkowski, intel-gfx, sam
Ease entry for anyone wanting to pick up the bootsplash work by providing
a couple of pointers.
v2: Add Sam as contact (Sam)
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
---
Documentation/gpu/todo.rst | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index ab96ba0600a9..b4a76c2703e5 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -484,5 +484,20 @@ i915
device_link_add to model the dependency between i915 and snd_had. See
https://dri.freedesktop.org/docs/drm/driver-api/device_link.html
+Bootsplash
+==========
+
+There is support in place now for writing internal DRM clients making it
+possible to pick up the bootsplash work that was rejected because it was written
+for fbdev.
+
+- [v6,8/8] drm/client: Hack: Add bootsplash example
+ https://patchwork.freedesktop.org/patch/306579/
+
+- [RFC PATCH v2 00/13] Kernel based bootsplash
+ https://lkml.org/lkml/2017/12/13/764
+
+Contact: Sam Ravnborg
+
Outside DRM
===========
--
2.20.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 11+ messages in thread
* ✗ Fi.CI.CHECKPATCH: warning for drm/fb-helper: Move modesetting code to drm_client (rev9)
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
` (4 preceding siblings ...)
2019-06-08 15:26 ` [PATCH v8 5/5] drm/todo: Add bootsplash entry Noralf Trønnes
@ 2019-06-10 10:18 ` Patchwork
2019-06-10 10:22 ` ✗ Fi.CI.SPARSE: " Patchwork
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Patchwork @ 2019-06-10 10:18 UTC (permalink / raw)
To: Noralf Trønnes; +Cc: intel-gfx
== Series Details ==
Series: drm/fb-helper: Move modesetting code to drm_client (rev9)
URL : https://patchwork.freedesktop.org/series/58597/
State : warning
== Summary ==
$ dim checkpatch origin/drm-tip
12c568eec3fc drm/fb-helper: Remove drm_fb_helper_connector
-:596: WARNING:LONG_LINE: line over 100 characters
#596: FILE: drivers/gpu/drm/drm_fb_helper.c:1974:
+ connector->base.id, connector->tile_group ? connector->tile_group->id : 0);
-:953: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#953: FILE: include/drm/drm_client.h:183:
+#define drm_client_for_each_connector_iter(connector, iter) \
+ drm_for_each_connector_iter(connector, iter) \
+ if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
-:953: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'connector' - possible side-effects?
#953: FILE: include/drm/drm_client.h:183:
+#define drm_client_for_each_connector_iter(connector, iter) \
+ drm_for_each_connector_iter(connector, iter) \
+ if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
total: 1 errors, 1 warnings, 1 checks, 1007 lines checked
cd49b73dec87 drm/fb-helper: Prepare to move out modeset config code
-:170: WARNING:LONG_LINE: line over 100 characters
#170: FILE: drivers/gpu/drm/drm_fb_helper.c:2367:
+ (dev->mode_config.num_crtc > 1 && modeset->num_connectors == 1))) {
total: 0 errors, 1 warnings, 0 checks, 179 lines checked
ae7f45590011 drm/fb-helper: Move out modeset config code
-:100: CHECK:BOOL_COMPARISON: Using comparison to false is error prone
#100: FILE: drivers/gpu/drm/drm_client_modeset.c:140:
+ if (cmdline_mode->specified == false)
-:171: WARNING:LONG_LINE: line over 100 characters
#171: FILE: drivers/gpu/drm/drm_client_modeset.c:211:
+ connector->display_info.non_desktop ? "non desktop" : enabled[i] ? "yes" : "no");
-:315: CHECK:BOOL_COMPARISON: Using comparison to false is error prone
#315: FILE: drivers/gpu/drm/drm_client_modeset.c:355:
+ if (enabled[i] == false) {
-:349: WARNING:LONG_LINE: line over 100 characters
#349: FILE: drivers/gpu/drm/drm_client_modeset.c:389:
+ connector->base.id, connector->tile_group ? connector->tile_group->id : 0);
-:405: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!modes[n]"
#405: FILE: drivers/gpu/drm/drm_client_modeset.c:445:
+ if (modes[n] == NULL)
-:737: WARNING:LONG_LINE: line over 100 characters
#737: FILE: drivers/gpu/drm/drm_client_modeset.c:777:
+ if (WARN_ON_ONCE(modeset->num_connectors == DRM_CLIENT_MAX_CLONED_CONNECTORS ||
-:738: WARNING:LONG_LINE: line over 100 characters
#738: FILE: drivers/gpu/drm/drm_client_modeset.c:778:
+ (dev->mode_config.num_crtc > 1 && modeset->num_connectors == 1))) {
-:1497: WARNING:LONG_LINE: line over 100 characters
#1497: FILE: include/drm/drm_client.h:155:
+int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height);
total: 0 errors, 5 warnings, 3 checks, 1465 lines checked
357686de15f3 drm/client: Hack: Add bootsplash example
-:31: WARNING:CONFIG_DESCRIPTION: please write a paragraph that describes the config symbol fully
#31: FILE: drivers/gpu/drm/Kconfig:69:
+config DRM_CLIENT_BOOTSPLASH
-:52: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#52:
new file mode 100644
-:57: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#57: FILE: drivers/gpu/drm/drm_bootsplash.c:1:
+/* DRM internal client example */
-:83: CHECK:UNCOMMENTED_DEFINITION: struct mutex definition without comment
#83: FILE: drivers/gpu/drm/drm_bootsplash.c:27:
+ struct mutex lock;
-:121: WARNING:LONG_LINE: line over 100 characters
#121: FILE: drivers/gpu/drm/drm_bootsplash.c:65:
+ splash->buffers[i] = drm_client_framebuffer_create(&splash->client, width, height, DRM_FORMAT_XRGB8888);
-:269: WARNING:LONG_LINE: line over 100 characters
#269: FILE: drivers/gpu/drm/drm_bootsplash.c:213:
+static int drm_bootsplash_draw(struct drm_bootsplash *splash, unsigned int sequence, unsigned int buffer_num)
total: 0 errors, 5 warnings, 1 checks, 412 lines checked
da65a3f2816d drm/todo: Add bootsplash entry
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* ✗ Fi.CI.SPARSE: warning for drm/fb-helper: Move modesetting code to drm_client (rev9)
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
` (5 preceding siblings ...)
2019-06-10 10:18 ` ✗ Fi.CI.CHECKPATCH: warning for drm/fb-helper: Move modesetting code to drm_client (rev9) Patchwork
@ 2019-06-10 10:22 ` Patchwork
2019-06-10 10:41 ` ✓ Fi.CI.BAT: success " Patchwork
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Patchwork @ 2019-06-10 10:22 UTC (permalink / raw)
To: Noralf Trønnes; +Cc: intel-gfx
== Series Details ==
Series: drm/fb-helper: Move modesetting code to drm_client (rev9)
URL : https://patchwork.freedesktop.org/series/58597/
State : warning
== Summary ==
$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/fb-helper: Remove drm_fb_helper_connector
-O:drivers/gpu/drm/drm_fb_helper.c:2292:30: warning: expression using sizeof(void)
+drivers/gpu/drm/drm_fb_helper.c:2091:30: warning: expression using sizeof(void)
-./include/linux/slab.h:666:13: error: not a function <noident>
Commit: drm/fb-helper: Prepare to move out modeset config code
-O:drivers/gpu/drm/drm_fb_helper.c:2091:30: warning: expression using sizeof(void)
+drivers/gpu/drm/drm_fb_helper.c:2095:30: warning: expression using sizeof(void)
Commit: drm/fb-helper: Move out modeset config code
+drivers/gpu/drm/drm_client_modeset.c:506:30: warning: expression using sizeof(void)
-O:drivers/gpu/drm/drm_fb_helper.c:2095:30: warning: expression using sizeof(void)
+./include/linux/slab.h:666:13: error: not a function <noident>
-./include/linux/slab.h:666:13: error: undefined identifier '__builtin_mul_overflow'
-./include/linux/slab.h:666:13: warning: call with no type!
Commit: drm/client: Hack: Add bootsplash example
+
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
+drivers/gpu/drm/drm_client.c:166:5: warning: "CONFIG_DRM_CLIENT_BOOTSPLASH" is not defined, evaluates to 0 [-Wundef]
+drivers/gpu/drm/drm_client.c:166:5: warning: undefined preprocessor identifier 'CONFIG_DRM_CLIENT_BOOTSPLASH'
+drivers/gpu/drm/drm_client.c: In function ‘drm_client_dev_register’:
+Error in reading or end of file.
+ #if CONFIG_DRM_CLIENT_BOOTSPLASH
Commit: drm/todo: Add bootsplash entry
Okay!
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* ✓ Fi.CI.BAT: success for drm/fb-helper: Move modesetting code to drm_client (rev9)
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
` (6 preceding siblings ...)
2019-06-10 10:22 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2019-06-10 10:41 ` Patchwork
2019-06-10 23:14 ` ✓ Fi.CI.IGT: " Patchwork
2019-06-11 13:00 ` [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
9 siblings, 0 replies; 11+ messages in thread
From: Patchwork @ 2019-06-10 10:41 UTC (permalink / raw)
To: Noralf Trønnes; +Cc: intel-gfx
== Series Details ==
Series: drm/fb-helper: Move modesetting code to drm_client (rev9)
URL : https://patchwork.freedesktop.org/series/58597/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_6225 -> Patchwork_13211
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/
Known issues
------------
Here are the changes found in Patchwork_13211 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@debugfs_test@read_all_entries:
- fi-icl-u3: [PASS][1] -> [DMESG-WARN][2] ([fdo#107724]) +3 similar issues
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/fi-icl-u3/igt@debugfs_test@read_all_entries.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/fi-icl-u3/igt@debugfs_test@read_all_entries.html
* igt@i915_selftest@live_contexts:
- fi-bdw-gvtdvm: [PASS][3] -> [DMESG-FAIL][4] ([fdo#110235])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/fi-bdw-gvtdvm/igt@i915_selftest@live_contexts.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/fi-bdw-gvtdvm/igt@i915_selftest@live_contexts.html
#### Possible fixes ####
* igt@gem_render_linear_blits@basic:
- fi-icl-u3: [DMESG-WARN][5] ([fdo#107724]) -> [PASS][6]
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/fi-icl-u3/igt@gem_render_linear_blits@basic.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/fi-icl-u3/igt@gem_render_linear_blits@basic.html
* igt@kms_chamelium@hdmi-hpd-fast:
- fi-kbl-7500u: [FAIL][7] ([fdo#109485]) -> [PASS][8]
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html
* igt@kms_frontbuffer_tracking@basic:
- fi-hsw-peppy: [DMESG-WARN][9] ([fdo#102614]) -> [PASS][10]
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/fi-hsw-peppy/igt@kms_frontbuffer_tracking@basic.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/fi-hsw-peppy/igt@kms_frontbuffer_tracking@basic.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[fdo#102614]: https://bugs.freedesktop.org/show_bug.cgi?id=102614
[fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
[fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
[fdo#108569]: https://bugs.freedesktop.org/show_bug.cgi?id=108569
[fdo#109485]: https://bugs.freedesktop.org/show_bug.cgi?id=109485
[fdo#110235]: https://bugs.freedesktop.org/show_bug.cgi?id=110235
Participating hosts (54 -> 44)
------------------------------
Missing (10): fi-kbl-soraka fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ivb-3770 fi-skl-6600u fi-bdw-samus fi-byt-clapper fi-skl-6700k2
Build changes
-------------
* Linux: CI_DRM_6225 -> Patchwork_13211
CI_DRM_6225: 39bb7459567aada2e706e4da4a650dc4f7c41abf @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_5049: db51cbba5a8f4856d6f56a61aa51fda6e239fa44 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
Patchwork_13211: da65a3f2816d7a9dc74f7b79b0de74a600d08230 @ git://anongit.freedesktop.org/gfx-ci/linux
== Linux commits ==
da65a3f2816d drm/todo: Add bootsplash entry
357686de15f3 drm/client: Hack: Add bootsplash example
ae7f45590011 drm/fb-helper: Move out modeset config code
cd49b73dec87 drm/fb-helper: Prepare to move out modeset config code
12c568eec3fc drm/fb-helper: Remove drm_fb_helper_connector
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* ✓ Fi.CI.IGT: success for drm/fb-helper: Move modesetting code to drm_client (rev9)
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
` (7 preceding siblings ...)
2019-06-10 10:41 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2019-06-10 23:14 ` Patchwork
2019-06-11 13:00 ` [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
9 siblings, 0 replies; 11+ messages in thread
From: Patchwork @ 2019-06-10 23:14 UTC (permalink / raw)
To: Noralf Trønnes; +Cc: intel-gfx
== Series Details ==
Series: drm/fb-helper: Move modesetting code to drm_client (rev9)
URL : https://patchwork.freedesktop.org/series/58597/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_6225_full -> Patchwork_13211_full
====================================================
Summary
-------
**SUCCESS**
No regressions found.
Known issues
------------
Here are the changes found in Patchwork_13211_full that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@kms_draw_crc@draw-method-rgb565-blt-xtiled:
- shard-skl: [PASS][1] -> [FAIL][2] ([fdo#103184] / [fdo#103232])
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-skl2/igt@kms_draw_crc@draw-method-rgb565-blt-xtiled.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-skl7/igt@kms_draw_crc@draw-method-rgb565-blt-xtiled.html
* igt@kms_flip@flip-vs-expired-vblank:
- shard-skl: [PASS][3] -> [FAIL][4] ([fdo#105363])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-skl2/igt@kms_flip@flip-vs-expired-vblank.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-skl1/igt@kms_flip@flip-vs-expired-vblank.html
* igt@kms_flip@flip-vs-suspend:
- shard-iclb: [PASS][5] -> [INCOMPLETE][6] ([fdo#107713] / [fdo#109507])
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-iclb6/igt@kms_flip@flip-vs-suspend.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-iclb6/igt@kms_flip@flip-vs-suspend.html
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-pwrite:
- shard-iclb: [PASS][7] -> [FAIL][8] ([fdo#103167]) +2 similar issues
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-iclb7/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-pwrite.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-iclb8/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-pwrite.html
* igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-move:
- shard-hsw: [PASS][9] -> [SKIP][10] ([fdo#109271]) +14 similar issues
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-hsw2/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-move.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-hsw1/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-move.html
* igt@kms_frontbuffer_tracking@fbc-suspend:
- shard-apl: [PASS][11] -> [DMESG-WARN][12] ([fdo#108566]) +1 similar issue
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-apl4/igt@kms_frontbuffer_tracking@fbc-suspend.html
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-apl7/igt@kms_frontbuffer_tracking@fbc-suspend.html
* igt@kms_frontbuffer_tracking@fbcpsr-1p-pri-indfb-multidraw:
- shard-skl: [PASS][13] -> [FAIL][14] ([fdo#108040]) +1 similar issue
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-skl2/igt@kms_frontbuffer_tracking@fbcpsr-1p-pri-indfb-multidraw.html
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-skl7/igt@kms_frontbuffer_tracking@fbcpsr-1p-pri-indfb-multidraw.html
* igt@kms_mmap_write_crc@main:
- shard-skl: [PASS][15] -> [FAIL][16] ([fdo#110870])
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-skl2/igt@kms_mmap_write_crc@main.html
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-skl7/igt@kms_mmap_write_crc@main.html
* igt@kms_setmode@basic:
- shard-apl: [PASS][17] -> [FAIL][18] ([fdo#99912])
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-apl4/igt@kms_setmode@basic.html
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-apl3/igt@kms_setmode@basic.html
#### Possible fixes ####
* igt@gem_eio@in-flight-suspend:
- shard-skl: [INCOMPLETE][19] ([fdo#104108]) -> [PASS][20] +2 similar issues
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-skl4/igt@gem_eio@in-flight-suspend.html
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-skl2/igt@gem_eio@in-flight-suspend.html
* igt@kms_cursor_crc@pipe-b-cursor-suspend:
- shard-kbl: [DMESG-WARN][21] ([fdo#108566]) -> [PASS][22]
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-kbl6/igt@kms_cursor_crc@pipe-b-cursor-suspend.html
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-kbl4/igt@kms_cursor_crc@pipe-b-cursor-suspend.html
* igt@kms_flip@2x-flip-vs-expired-vblank-interruptible:
- shard-glk: [FAIL][23] ([fdo#105363]) -> [PASS][24]
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-glk1/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible.html
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-glk8/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible.html
* igt@kms_flip@2x-plain-flip-ts-check-interruptible:
- shard-hsw: [SKIP][25] ([fdo#109271]) -> [PASS][26] +22 similar issues
[25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-hsw1/igt@kms_flip@2x-plain-flip-ts-check-interruptible.html
[26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-hsw7/igt@kms_flip@2x-plain-flip-ts-check-interruptible.html
* igt@kms_flip@flip-vs-expired-vblank-interruptible:
- shard-skl: [FAIL][27] ([fdo#105363]) -> [PASS][28]
[27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-skl9/igt@kms_flip@flip-vs-expired-vblank-interruptible.html
[28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-skl6/igt@kms_flip@flip-vs-expired-vblank-interruptible.html
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-blt:
- shard-iclb: [FAIL][29] ([fdo#103167]) -> [PASS][30] +2 similar issues
[29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-iclb4/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-blt.html
[30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-iclb3/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-blt.html
* igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes:
- shard-apl: [DMESG-WARN][31] ([fdo#108566]) -> [PASS][32] +5 similar issues
[31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-apl7/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes.html
[32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-apl3/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes.html
* igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
- shard-skl: [FAIL][33] ([fdo#108145]) -> [PASS][34]
[33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-skl6/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html
[34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-skl8/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html
* igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
- shard-skl: [FAIL][35] ([fdo#108145] / [fdo#110403]) -> [PASS][36]
[35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-skl6/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
[36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-skl6/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
* igt@kms_setmode@basic:
- shard-skl: [FAIL][37] ([fdo#99912]) -> [PASS][38]
[37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-skl1/igt@kms_setmode@basic.html
[38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-skl7/igt@kms_setmode@basic.html
#### Warnings ####
* igt@gem_mmap_gtt@forked-big-copy-xy:
- shard-iclb: [TIMEOUT][39] ([fdo#109673]) -> [INCOMPLETE][40] ([fdo#107713] / [fdo#109100])
[39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6225/shard-iclb1/igt@gem_mmap_gtt@forked-big-copy-xy.html
[40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/shard-iclb7/igt@gem_mmap_gtt@forked-big-copy-xy.html
[fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
[fdo#103184]: https://bugs.freedesktop.org/show_bug.cgi?id=103184
[fdo#103232]: https://bugs.freedesktop.org/show_bug.cgi?id=103232
[fdo#104108]: https://bugs.freedesktop.org/show_bug.cgi?id=104108
[fdo#105363]: https://bugs.freedesktop.org/show_bug.cgi?id=105363
[fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
[fdo#108040]: https://bugs.freedesktop.org/show_bug.cgi?id=108040
[fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
[fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
[fdo#109100]: https://bugs.freedesktop.org/show_bug.cgi?id=109100
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109507]: https://bugs.freedesktop.org/show_bug.cgi?id=109507
[fdo#109673]: https://bugs.freedesktop.org/show_bug.cgi?id=109673
[fdo#110403]: https://bugs.freedesktop.org/show_bug.cgi?id=110403
[fdo#110870]: https://bugs.freedesktop.org/show_bug.cgi?id=110870
[fdo#99912]: https://bugs.freedesktop.org/show_bug.cgi?id=99912
Participating hosts (10 -> 10)
------------------------------
No changes in participating hosts
Build changes
-------------
* Linux: CI_DRM_6225 -> Patchwork_13211
CI_DRM_6225: 39bb7459567aada2e706e4da4a650dc4f7c41abf @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_5049: db51cbba5a8f4856d6f56a61aa51fda6e239fa44 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
Patchwork_13211: da65a3f2816d7a9dc74f7b79b0de74a600d08230 @ git://anongit.freedesktop.org/gfx-ci/linux
piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13211/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
` (8 preceding siblings ...)
2019-06-10 23:14 ` ✓ Fi.CI.IGT: " Patchwork
@ 2019-06-11 13:00 ` Noralf Trønnes
9 siblings, 0 replies; 11+ messages in thread
From: Noralf Trønnes @ 2019-06-11 13:00 UTC (permalink / raw)
To: dri-devel; +Cc: intel-gfx, sam
Den 08.06.2019 17.26, skrev Noralf Trønnes:
> This moves the modesetting code from drm_fb_helper to drm_client so it
> can be shared by all internal clients.
>
> Let's see what the CI says about the remaining patches. I have added the
> bootsplash todo entry patch adding Sam as contact.
>
> Noralf.
>
> Noralf Trønnes (5):
> drm/fb-helper: Remove drm_fb_helper_connector
> drm/fb-helper: Prepare to move out modeset config code
> drm/fb-helper: Move out modeset config code
> drm/client: Hack: Add bootsplash example
> drm/todo: Add bootsplash entry
>
The CI agreed this time so all applied except the example.
Nice to be done with this. It started out as an idea about making
generic fbdev emulation 18 months ago but turned out to be something
even more generic :-)
Noralf.
> Documentation/gpu/todo.rst | 19 +
> drivers/gpu/drm/Kconfig | 5 +
> drivers/gpu/drm/Makefile | 1 +
> drivers/gpu/drm/drm_bootsplash.c | 358 +++++++++++
> drivers/gpu/drm/drm_client.c | 7 +
> drivers/gpu/drm/drm_client_modeset.c | 707 ++++++++++++++++++++-
> drivers/gpu/drm/drm_drv.c | 4 +
> drivers/gpu/drm/drm_fb_helper.c | 886 +--------------------------
> include/drm/drm_client.h | 23 +-
> include/drm/drm_fb_helper.h | 84 +--
> 10 files changed, 1149 insertions(+), 945 deletions(-)
> create mode 100644 drivers/gpu/drm/drm_bootsplash.c
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2019-06-11 13:00 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-06-08 15:26 [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 1/5] drm/fb-helper: Remove drm_fb_helper_connector Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 2/5] drm/fb-helper: Prepare to move out modeset config code Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 3/5] drm/fb-helper: Move " Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 4/5] drm/client: Hack: Add bootsplash example Noralf Trønnes
2019-06-08 15:26 ` [PATCH v8 5/5] drm/todo: Add bootsplash entry Noralf Trønnes
2019-06-10 10:18 ` ✗ Fi.CI.CHECKPATCH: warning for drm/fb-helper: Move modesetting code to drm_client (rev9) Patchwork
2019-06-10 10:22 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-06-10 10:41 ` ✓ Fi.CI.BAT: success " Patchwork
2019-06-10 23:14 ` ✓ Fi.CI.IGT: " Patchwork
2019-06-11 13:00 ` [PATCH v8 0/5] drm/fb-helper: Move modesetting code to drm_client Noralf Trønnes
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox