@@ -443,24 +443,6 @@ int drm_fb_helper_blank(int blank, struct fb_info *info)
}
EXPORT_SYMBOL(drm_fb_helper_blank);
-static void drm_fb_helper_modeset_release(struct drm_fb_helper *helper,
- struct drm_mode_set *modeset)
-{
- int i;
-
- for (i = 0; i < modeset->num_connectors; i++) {
- drm_connector_put(modeset->connectors[i]);
- modeset->connectors[i] = NULL;
- }
- modeset->num_connectors = 0;
-
- drm_mode_destroy(helper->dev, modeset->mode);
- modeset->mode = NULL;
-
- /* FIXME should hold a ref? */
- modeset->fb = NULL;
-}
-
static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
{
int i;
@@ -470,14 +452,6 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
kfree(helper->connector_info[i]);
}
kfree(helper->connector_info);
-
- for (i = 0; i < helper->crtc_count; i++) {
- struct drm_mode_set *modeset = &helper->crtc_info[i].mode_set;
-
- drm_fb_helper_modeset_release(helper, modeset);
- kfree(modeset->connectors);
- }
- kfree(helper->crtc_info);
}
static void drm_fb_helper_resume_worker(struct work_struct *work)
@@ -552,48 +526,18 @@ int drm_fb_helper_init(struct drm_device *dev,
struct drm_fb_helper *fb_helper,
int max_conn_count)
{
- struct drm_crtc *crtc;
- struct drm_mode_config *config = &dev->mode_config;
- int i;
-
if (!drm_fbdev_emulation) {
dev->fb_helper = fb_helper;
return 0;
}
- if (!max_conn_count)
- return -EINVAL;
-
- fb_helper->crtc_info = kcalloc(config->num_crtc, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
- if (!fb_helper->crtc_info)
- return -ENOMEM;
-
- fb_helper->crtc_count = config->num_crtc;
fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL);
- if (!fb_helper->connector_info) {
- kfree(fb_helper->crtc_info);
+ if (!fb_helper->connector_info)
return -ENOMEM;
- }
+
fb_helper->connector_info_alloc_count = dev->mode_config.num_connector;
fb_helper->connector_count = 0;
- for (i = 0; i < fb_helper->crtc_count; i++) {
- fb_helper->crtc_info[i].mode_set.connectors =
- kcalloc(max_conn_count,
- sizeof(struct drm_connector *),
- GFP_KERNEL);
-
- if (!fb_helper->crtc_info[i].mode_set.connectors)
- goto out_free;
- fb_helper->crtc_info[i].mode_set.num_connectors = 0;
- }
-
- i = 0;
- drm_for_each_crtc(crtc, dev) {
- fb_helper->crtc_info[i].mode_set.crtc = crtc;
- i++;
- }
-
fb_helper->display = drm_client_display_create(dev);
if (IS_ERR(fb_helper->display))
goto out_free;
@@ -1830,7 +1774,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
struct drm_display_mode *dmt_mode, *mode;
/* only contemplate cloning in the single crtc case */
- if (fb_helper->crtc_count > 1)
+ if (fb_helper->dev->mode_config.num_crtc > 1)
return false;
count = 0;
@@ -1997,16 +1941,18 @@ static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
}
static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
- struct drm_fb_helper_crtc **best_crtcs,
+ struct drm_crtc **best_crtcs,
struct drm_display_mode **modes,
int n, int width, int height)
{
- int c, o;
+ 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;
const struct drm_connector_helper_funcs *connector_funcs;
+ struct drm_mode_set *modeset;
struct drm_encoder *encoder;
- int my_score, best_score, score;
- struct drm_fb_helper_crtc **crtcs, *crtc;
+ struct drm_crtc **crtcs;
struct drm_fb_helper_connector *fb_helper_conn;
if (n == fb_helper->connector_count)
@@ -2020,8 +1966,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
if (modes[n] == NULL)
return best_score;
- crtcs = kcalloc(fb_helper->connector_count,
- sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
+ crtcs = kcalloc(fb_helper->connector_count, sizeof(*crtcs), GFP_KERNEL);
if (!crtcs)
return best_score;
@@ -2053,10 +1998,10 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
* select a crtc for this connector and then attempt to configure
* remaining connectors
*/
- for (c = 0; c < fb_helper->crtc_count; c++) {
- crtc = &fb_helper->crtc_info[c];
+ drm_client_display_for_each_modeset(modeset, display) {
+ struct drm_crtc *crtc = modeset->crtc;
- if ((encoder->possible_crtcs & (1 << c)) == 0)
+ if ((encoder->possible_crtcs & drm_crtc_mask(crtc)) == 0)
continue;
for (o = 0; o < n; o++)
@@ -2065,7 +2010,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->crtc_count > 1)
+ if (dev->mode_config.num_crtc > 1)
continue;
if (!drm_mode_equal(modes[o], modes[n]))
@@ -2073,14 +2018,13 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
}
crtcs[n] = crtc;
- memcpy(crtcs, best_crtcs, n * sizeof(struct drm_fb_helper_crtc *));
+ memcpy(crtcs, best_crtcs, n * sizeof(*crtcs));
score = my_score + drm_pick_crtcs(fb_helper, crtcs, modes, n + 1,
width, height);
if (score > best_score) {
best_score = score;
memcpy(best_crtcs, crtcs,
- fb_helper->connector_count *
- sizeof(struct drm_fb_helper_crtc *));
+ fb_helper->connector_count * sizeof(*crtcs));
}
}
out:
@@ -2093,9 +2037,9 @@ 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_fb_helper_crtc **crtcs;
struct drm_display_mode **modes;
struct drm_fb_offset *offsets;
+ struct drm_crtc **crtcs;
bool *enabled;
int i;
@@ -2117,8 +2061,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
}
}
- crtcs = kcalloc(fb_helper->connector_count,
- sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
+ 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,
@@ -2136,43 +2079,28 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
drm_enable_connectors(fb_helper, enabled);
- if (!(fb_helper->funcs->initial_config &&
- fb_helper->funcs->initial_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_target_cloned(fb_helper, modes, offsets, enabled, width, height) &&
+ !drm_target_preferred(fb_helper, modes, offsets, enabled, width, height))
+ DRM_ERROR("Unable to find initial modes\n");
- if (!drm_target_cloned(fb_helper, modes, offsets,
- enabled, width, height) &&
- !drm_target_preferred(fb_helper, 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_DEBUG_KMS("picking CRTCs for %dx%d config\n",
- width, height);
-
- drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height);
- }
+ drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height);
/* need to set the modesets up here for use later */
/* fill out the connector<->crtc mappings into the modesets */
- for (i = 0; i < fb_helper->crtc_count; i++)
- drm_fb_helper_modeset_release(fb_helper,
- &fb_helper->crtc_info[i].mode_set);
drm_fb_helper_for_each_connector(fb_helper, i) {
struct drm_display_mode *mode = modes[i];
- struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
+ struct drm_crtc *crtc = crtcs[i];
struct drm_fb_offset *offset = &offsets[i];
- if (mode && fb_crtc) {
+ 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, fb_crtc->mode_set.crtc);
+ modeset = drm_client_display_find_modeset(display, crtc);
if (WARN_ON(!modeset)) {
drm_client_display_free(display);
goto out;
@@ -45,12 +45,6 @@ struct drm_fb_offset {
int x, y;
};
-struct drm_fb_helper_crtc {
- struct drm_mode_set mode_set;
- struct drm_display_mode *desired_mode;
- int x, y;
-};
-
/**
* struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size
* @fb_width: fbdev width
@@ -101,29 +95,6 @@ struct drm_fb_helper_funcs {
*/
int (*fb_probe)(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes);
-
- /**
- * @initial_config:
- *
- * Driver callback to setup an initial fbdev display configuration.
- * Drivers can use this callback to tell the fbdev emulation what the
- * preferred initial configuration is. This is useful to implement
- * smooth booting where the fbdev (and subsequently all userspace) never
- * changes the mode, but always inherits the existing configuration.
- *
- * This callback is optional.
- *
- * RETURNS:
- *
- * The driver should return true if a suitable initial configuration has
- * been filled out and false when the fbdev helper should fall back to
- * the default probing logic.
- */
- bool (*initial_config)(struct drm_fb_helper *fb_helper,
- struct drm_fb_helper_crtc **crtcs,
- struct drm_display_mode **modes,
- struct drm_fb_offset *offsets,
- bool *enabled, int width, int height);
};
struct drm_fb_helper_connector {
@@ -163,8 +134,6 @@ struct drm_fb_helper {
*/
struct drm_client_display *display;
- int crtc_count;
- struct drm_fb_helper_crtc *crtc_info;
int connector_count;
int connector_info_alloc_count;
/**
The stage is now set for a clean removal of drm_fb_helper_crtc. struct drm_client_display is doing its job now. Also remove the drm_fb_helper_funcs->initial_config which has been superseded by drm_driver->initial_client_display. Signed-off-by: Noralf Trønnes <noralf@tronnes.org> --- drivers/gpu/drm/drm_fb_helper.c | 124 +++++++++------------------------------- include/drm/drm_fb_helper.h | 31 ---------- 2 files changed, 26 insertions(+), 129 deletions(-)