From patchwork Thu Apr 12 16:12:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 10338955 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 61232600D0 for ; Thu, 12 Apr 2018 16:13:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F37C26220 for ; Thu, 12 Apr 2018 16:13:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 43C1B26247; Thu, 12 Apr 2018 16:13:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 18DA726246 for ; Thu, 12 Apr 2018 16:13:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8834B6EA9C; Thu, 12 Apr 2018 16:13:05 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5A0BB6E991; Thu, 12 Apr 2018 16:12:59 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:54390 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1f6eqG-0002mh-N4; Thu, 12 Apr 2018 18:12:56 +0200 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Subject: [RFC v4 14/25] drm/fb-helper: Remove struct drm_fb_helper_connector Date: Thu, 12 Apr 2018 18:12:26 +0200 Message-Id: <20180412161237.9314-3-noralf@tronnes.org> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180412161237.9314-1-noralf@tronnes.org> References: <20180412161237.9314-1-noralf@tronnes.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, intel-gfx@lists.freedesktop.org, laurent.pinchart@ideasonboard.com, mstaudt@suse.de Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP No need to maintain a list of registered connectors. Just use the connector iterator. TODO: Remove: - drm_fb_helper_add_one_connector() - drm_fb_helper_single_add_all_connectors() - drm_fb_helper_remove_one_connector() Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_fb_helper.c | 359 ++++++++++------------------------------ include/drm/drm_fb_helper.h | 13 -- 2 files changed, 86 insertions(+), 286 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index ce38eadcb346..6ee61f195321 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -112,59 +112,10 @@ 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; + return 0; } EXPORT_SYMBOL(drm_fb_helper_add_one_connector); @@ -184,87 +135,14 @@ EXPORT_SYMBOL(drm_fb_helper_add_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) { - 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; } +EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors); 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; + return 0; } EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); @@ -443,17 +321,6 @@ int drm_fb_helper_blank(int blank, struct fb_info *info) } EXPORT_SYMBOL(drm_fb_helper_blank); -static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) -{ - int i; - - for (i = 0; i < helper->connector_count; i++) { - drm_connector_put(helper->connector_info[i]->connector); - kfree(helper->connector_info[i]); - } - kfree(helper->connector_info); -} - static void drm_fb_helper_resume_worker(struct work_struct *work) { struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, @@ -531,23 +398,13 @@ int drm_fb_helper_init(struct drm_device *dev, return 0; } - fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL); - if (!fb_helper->connector_info) - return -ENOMEM; - - fb_helper->connector_info_alloc_count = dev->mode_config.num_connector; - fb_helper->connector_count = 0; - fb_helper->display = drm_client_display_create(dev); if (IS_ERR(fb_helper->display)) - goto out_free; + return PTR_ERR(fb_helper->display); dev->fb_helper = fb_helper; return 0; -out_free: - drm_fb_helper_crtc_free(fb_helper); - return -ENOMEM; } EXPORT_SYMBOL(drm_fb_helper_init); @@ -651,8 +508,6 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) mutex_destroy(&fb_helper->lock); drm_client_display_free(fb_helper->display); - drm_fb_helper_crtc_free(fb_helper); - } EXPORT_SYMBOL(drm_fb_helper_fini); @@ -1474,8 +1329,9 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, { 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 gamma_size = 0; @@ -1490,11 +1346,9 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, sizes.surface_depth = sizes.surface_bpp = preferred_bpp; /* first up get a count of crtcs now in use and new min/maxes width/heights */ - drm_fb_helper_for_each_connector(fb_helper, i) { - struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i]; - struct drm_cmdline_mode *cmdline_mode; - - cmdline_mode = &fb_helper_conn->connector->cmdline_mode; + drm_connector_list_iter_begin(fb_helper->dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode; if (cmdline_mode->bpp_specified) { switch (cmdline_mode->bpp) { @@ -1519,6 +1373,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, break; } } + drm_connector_list_iter_end(&conn_iter); crtc_count = 0; drm_client_display_for_each_modeset(mode_set, fb_helper->display) { @@ -1707,70 +1562,28 @@ static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper, uint32_t maxX, uint32_t maxY) { + struct drm_connector_list_iter conn_iter; struct drm_connector *connector; - int i, count = 0; + int count = 0; - drm_fb_helper_for_each_connector(fb_helper, i) { - connector = fb_helper->connector_info[i]->connector; + drm_connector_list_iter_begin(fb_helper->dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { count += connector->funcs->fill_modes(connector, maxX, maxY); } + drm_connector_list_iter_end(&conn_iter); return count; } -static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector) -{ - return fb_connector->connector->cmdline_mode.specified; -} - -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_enable_connectors(struct drm_fb_helper *fb_helper, - 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; - 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; - - drm_fb_helper_for_each_connector(fb_helper, i) { - connector = fb_helper->connector_info[i]->connector; - enabled[i] = drm_connector_enabled(connector, false); - } -} - static bool drm_target_cloned(struct drm_fb_helper *fb_helper, + 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 */ @@ -1778,7 +1591,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, return false; count = 0; - drm_fb_helper_for_each_connector(fb_helper, i) { + for (i = 0; i < connector_count; i++) { if (enabled[i]) count++; } @@ -1789,11 +1602,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_connector_pick_cmdline_mode(fb_helper_conn->connector); + modes[i] = drm_connector_pick_cmdline_mode(connectors[i]); if (!modes[i]) { can_clone = false; break; @@ -1815,12 +1627,11 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, can_clone = true; dmt_mode = drm_mode_find_dmt(fb_helper->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_equal(mode, dmt_mode)) modes[i] = mode; } @@ -1836,30 +1647,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, +static int drm_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; 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++) { + struct drm_connector *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; @@ -1868,20 +1680,20 @@ 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, +static bool drm_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; 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++) { + struct drm_connector *connector = connectors[i]; if (conn_configured & BIT_ULL(i)) continue; @@ -1892,17 +1704,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; @@ -1910,24 +1722,23 @@ 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_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_connector_pick_cmdline_mode(fb_helper_conn->connector); + 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_connector_has_preferred_mode(fb_helper_conn->connector, 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) - break; - } + if (!modes[i]) + modes[i] = list_first_entry_or_null(&connector->modes, struct drm_display_mode, head); + DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name : "none"); conn_configured |= BIT_ULL(i); @@ -1940,12 +1751,13 @@ static bool drm_target_preferred(struct drm_fb_helper *fb_helper, return true; } -static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, +static int drm_pick_crtcs(struct drm_client_display *display, + 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_display *display = fb_helper->display; struct drm_device *dev = display->dev; int o, my_score, best_score, score; struct drm_connector *connector; @@ -1953,27 +1765,26 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, struct drm_mode_set *modeset; struct drm_encoder *encoder; struct drm_crtc **crtcs; - struct drm_fb_helper_connector *fb_helper_conn; - 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_pick_crtcs(display, 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_connector_has_preferred_mode(connector, width, height)) my_score++; @@ -1985,7 +1796,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, * NULL we fallback to the default drm_atomic_helper_best_encoder() * helper. */ - if (drm_drv_uses_atomic_modeset(fb_helper->dev) && + if (drm_drv_uses_atomic_modeset(dev) && !connector_funcs->best_encoder) encoder = drm_atomic_helper_best_encoder(connector); else @@ -2019,12 +1830,12 @@ 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_pick_crtcs(display, 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)); + connector_count * sizeof(*crtcs)); } } out: @@ -2037,11 +1848,12 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, { struct drm_device *dev = fb_helper->dev; struct drm_client_display *display; + struct drm_connector **connectors; struct drm_display_mode **modes; struct drm_fb_offset *offsets; struct drm_crtc **crtcs; + int i, connector_count; bool *enabled; - int i; DRM_DEBUG_KMS("\n"); /* prevent concurrent modification of connector_count by hotplug */ @@ -2061,13 +1873,14 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, } } - 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); + connector_count = drm_connector_get_all(dev, &connectors); + if (connector_count < 1) + return; + + enabled = drm_connector_get_enabled_status(connectors, connector_count); + crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL); + modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL); + offsets = kcalloc(connector_count, sizeof(*offsets), GFP_KERNEL); if (!crtcs || !modes || !enabled || !offsets) { DRM_ERROR("Memory allocation failed\n"); goto out; @@ -2077,27 +1890,26 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, if (IS_ERR(display)) goto out; - drm_enable_connectors(fb_helper, enabled); - - if (!drm_target_cloned(fb_helper, modes, offsets, enabled, width, height) && - !drm_target_preferred(fb_helper, modes, offsets, enabled, width, height)) + if (!drm_target_cloned(fb_helper, connectors, connector_count, + modes, offsets, enabled, width, height) && + !drm_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_pick_crtcs(display, connectors, connector_count, crtcs, modes, 0, width, height); /* need to set the modesets up here for use later */ /* fill out the connector<->crtc mappings into the modesets */ - drm_fb_helper_for_each_connector(fb_helper, i) { + for (i = 0; i < connector_count; i++) { + struct drm_connector *connector = connectors[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_connector *connector = - fb_helper->connector_info[i]->connector; struct drm_mode_set *modeset; modeset = drm_client_display_find_modeset(display, crtc); @@ -2121,6 +1933,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, fb_helper->display = display; out: mutex_unlock(&dev->mode_config.mutex); + drm_connector_put_all(connectors, connector_count); kfree(crtcs); kfree(modes); kfree(offsets); @@ -2136,10 +1949,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_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; drm_client_display_for_each_modeset(modeset, fb_helper->display) { if (!modeset->num_connectors) @@ -2156,10 +1970,8 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) } 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_for_each_connector_iter(connector, &conn_iter) { /* use first connected connector for the physical dimensions */ if (connector->status == connector_status_connected) { info->var.width = connector->display_info.width_mm; @@ -2167,6 +1979,7 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) break; } } + drm_connector_list_iter_end(&conn_iter); mutex_unlock(&fb_helper->dev->mode_config.mutex); switch (sw_rotations) { diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 408931f7613f..a1e1ab1247c5 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -97,10 +97,6 @@ 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 @@ -134,15 +130,6 @@ struct drm_fb_helper { */ struct drm_client_display *display; - 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];