Prepare to move the modeset committing code to drm_client. Signed-off-by: Noralf Trønnes <noralf@xxxxxxxxxxx> --- drivers/gpu/drm/drm_fb_helper.c | 161 ++++++++++++++++++++-------------------- include/drm/drm_fb_helper.h | 8 ++ 2 files changed, 89 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 2eef24db21f8..bdb4b57d2c12 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -35,6 +35,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <drm/drmP.h> +#include <drm/drm_client.h> #include <drm/drm_crtc.h> #include <drm/drm_fb_helper.h> #include <drm/drm_crtc_helper.h> @@ -321,13 +322,14 @@ static bool drm_fb_helper_panel_rotation(struct drm_connector *connector, return true; } -static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active) +static int drm_client_display_restore_atomic(struct drm_client_display *display, bool active) { - struct drm_device *dev = fb_helper->dev; + struct drm_device *dev = display->dev; struct drm_plane_state *plane_state; + struct drm_mode_set *mode_set; struct drm_plane *plane; struct drm_atomic_state *state; - int i, ret; + int ret; unsigned int plane_mask; struct drm_modeset_acquire_ctx ctx; @@ -363,8 +365,7 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ goto out_state; } - for (i = 0; i < fb_helper->crtc_count; i++) { - struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; + drm_client_display_for_each_modeset(mode_set, display) { struct drm_plane *primary = mode_set->crtc->primary; unsigned int rotation; @@ -412,13 +413,14 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ goto retry; } -static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper) +static int drm_client_display_restore_legacy(struct drm_client_display *display) { - struct drm_device *dev = fb_helper->dev; + struct drm_device *dev = display->dev; + struct drm_mode_set *mode_set; struct drm_plane *plane; - int i, ret = 0; + int ret = 0; - drm_modeset_lock_all(fb_helper->dev); + drm_modeset_lock_all(dev); drm_for_each_plane(plane, dev) { if (plane->type != DRM_PLANE_TYPE_PRIMARY) drm_plane_force_disable(plane); @@ -429,8 +431,7 @@ static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper) DRM_MODE_ROTATE_0); } - for (i = 0; i < fb_helper->crtc_count; i++) { - struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; + drm_client_display_for_each_modeset(mode_set, display) { struct drm_crtc *crtc = mode_set->crtc; if (crtc->funcs->cursor_set2) { @@ -448,19 +449,17 @@ static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper) goto out; } out: - drm_modeset_unlock_all(fb_helper->dev); + drm_modeset_unlock_all(dev); return ret; } -static int restore_fbdev_mode(struct drm_fb_helper *fb_helper) +static int drm_client_display_restore(struct drm_client_display *display) { - struct drm_device *dev = fb_helper->dev; - - if (drm_drv_uses_atomic_modeset(dev)) - return restore_fbdev_mode_atomic(fb_helper, true); + if (drm_drv_uses_atomic_modeset(display->dev)) + return drm_client_display_restore_atomic(display, true); else - return restore_fbdev_mode_legacy(fb_helper); + return drm_client_display_restore_legacy(display); } /** @@ -486,7 +485,7 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) return 0; mutex_lock(&fb_helper->lock); - ret = restore_fbdev_mode(fb_helper); + ret = drm_client_display_restore(fb_helper->display); do_delayed = fb_helper->delayed_hotplug; if (do_delayed) @@ -548,7 +547,7 @@ static bool drm_fb_helper_force_kernel_mode(void) continue; mutex_lock(&helper->lock); - ret = restore_fbdev_mode(helper); + ret = drm_client_display_restore(helper->display); if (ret) error = true; mutex_unlock(&helper->lock); @@ -580,22 +579,20 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; #endif -static void dpms_legacy(struct drm_fb_helper *fb_helper, int dpms_mode) +static void drm_client_display_dpms_legacy(struct drm_client_display *display, int dpms_mode) { - struct drm_device *dev = fb_helper->dev; + struct drm_device *dev = display->dev; struct drm_connector *connector; struct drm_mode_set *modeset; - int i, j; + int i; drm_modeset_lock_all(dev); - for (i = 0; i < fb_helper->crtc_count; i++) { - modeset = &fb_helper->crtc_info[i].mode_set; - + drm_client_display_for_each_modeset(modeset, display) { if (!modeset->crtc->enabled) continue; - for (j = 0; j < modeset->num_connectors; j++) { - connector = modeset->connectors[j]; + for (i = 0; i < modeset->num_connectors; i++) { + connector = modeset->connectors[i]; connector->funcs->dpms(connector, dpms_mode); drm_object_property_set_value(&connector->base, dev->mode_config.dpms_property, dpms_mode); @@ -604,23 +601,21 @@ static void dpms_legacy(struct drm_fb_helper *fb_helper, int dpms_mode) drm_modeset_unlock_all(dev); } +static void drm_client_display_dpms(struct drm_client_display *display, int mode) +{ + if (drm_drv_uses_atomic_modeset(display->dev)) + drm_client_display_restore_atomic(display, mode == DRM_MODE_DPMS_ON); + else + drm_client_display_dpms_legacy(display, mode); +} + static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) { struct drm_fb_helper *fb_helper = info->par; - /* - * For each CRTC in this fb, turn the connectors on/off. - */ mutex_lock(&fb_helper->lock); - if (!drm_fb_helper_is_bound(fb_helper)) { - mutex_unlock(&fb_helper->lock); - return; - } - - if (drm_drv_uses_atomic_modeset(fb_helper->dev)) - restore_fbdev_mode_atomic(fb_helper, dpms_mode == DRM_MODE_DPMS_ON); - else - dpms_legacy(fb_helper, dpms_mode); + if (drm_fb_helper_is_bound(fb_helper)) + drm_client_display_dpms(fb_helper->display, dpms_mode); mutex_unlock(&fb_helper->lock); } @@ -811,6 +806,10 @@ int drm_fb_helper_init(struct drm_device *dev, i++; } + fb_helper->display = drm_client_display_create(dev); + if (IS_ERR(fb_helper->display)) + goto out_free; + dev->fb_helper = fb_helper; return 0; @@ -919,6 +918,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) mutex_unlock(&kernel_fb_helper_lock); mutex_destroy(&fb_helper->lock); + drm_client_display_free(fb_helper->display); drm_fb_helper_crtc_free(fb_helper); } @@ -1265,13 +1265,14 @@ static int setcmap_pseudo_palette(struct fb_cmap *cmap, struct fb_info *info) static int setcmap_legacy(struct fb_cmap *cmap, struct fb_info *info) { struct drm_fb_helper *fb_helper = info->par; + struct drm_mode_set *modeset; struct drm_crtc *crtc; u16 *r, *g, *b; - int i, ret = 0; + int ret = 0; drm_modeset_lock_all(fb_helper->dev); - for (i = 0; i < fb_helper->crtc_count; i++) { - crtc = fb_helper->crtc_info[i].mode_set.crtc; + drm_client_display_for_each_modeset(modeset, fb_helper->display) { + crtc = modeset->crtc; if (!crtc->funcs->gamma_set || !crtc->gamma_size) return -EINVAL; @@ -1347,9 +1348,10 @@ static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info) struct drm_modeset_acquire_ctx ctx; struct drm_crtc_state *crtc_state; struct drm_atomic_state *state; + struct drm_mode_set *modeset; struct drm_crtc *crtc; u16 *r, *g, *b; - int i, ret = 0; + int ret = 0; bool replaced; drm_modeset_acquire_init(&ctx, 0); @@ -1362,8 +1364,8 @@ static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info) state->acquire_ctx = &ctx; retry: - for (i = 0; i < fb_helper->crtc_count; i++) { - crtc = fb_helper->crtc_info[i].mode_set.crtc; + drm_client_display_for_each_modeset(modeset, fb_helper->display) { + crtc = modeset->crtc; if (!gamma_lut) gamma_lut = setcmap_new_gamma_lut(crtc, cmap); @@ -1391,8 +1393,8 @@ static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info) if (ret) goto out_state; - for (i = 0; i < fb_helper->crtc_count; i++) { - crtc = fb_helper->crtc_info[i].mode_set.crtc; + drm_client_display_for_each_modeset(modeset, fb_helper->display) { + crtc = modeset->crtc; r = crtc->gamma_store; g = r + crtc->gamma_size; @@ -1468,7 +1470,6 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { struct drm_fb_helper *fb_helper = info->par; - struct drm_mode_set *mode_set; struct drm_crtc *crtc; int ret = 0; @@ -1496,8 +1497,7 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, * make. If we're not smart enough here, one should * just consider switch the userspace to KMS. */ - mode_set = &fb_helper->crtc_info[0].mode_set; - crtc = mode_set->crtc; + crtc = fb_helper->display->modesets[0].crtc; /* * Only wait for a vblank event if the CRTC is @@ -1651,13 +1651,9 @@ EXPORT_SYMBOL(drm_fb_helper_set_par); static void pan_set(struct drm_fb_helper *fb_helper, int x, int y) { - int i; - - for (i = 0; i < fb_helper->crtc_count; i++) { - struct drm_mode_set *mode_set; - - mode_set = &fb_helper->crtc_info[i].mode_set; + struct drm_mode_set *mode_set; + drm_client_display_for_each_modeset(mode_set, fb_helper->display) { mode_set->x = x; mode_set->y = y; } @@ -1671,7 +1667,7 @@ static int pan_display_atomic(struct fb_var_screeninfo *var, pan_set(fb_helper, var->xoffset, var->yoffset); - ret = restore_fbdev_mode_atomic(fb_helper, true); + ret = drm_client_display_restore(fb_helper->display); if (!ret) { info->var.xoffset = var->xoffset; info->var.yoffset = var->yoffset; @@ -1687,12 +1683,9 @@ static int pan_display_legacy(struct fb_var_screeninfo *var, struct drm_fb_helper *fb_helper = info->par; struct drm_mode_set *modeset; int ret = 0; - int i; drm_modeset_lock_all(fb_helper->dev); - for (i = 0; i < fb_helper->crtc_count; i++) { - modeset = &fb_helper->crtc_info[i].mode_set; - + drm_client_display_for_each_modeset(modeset, fb_helper->display) { modeset->x = var->xoffset; modeset->y = var->yoffset; @@ -1751,6 +1744,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, int crtc_count = 0; int i; struct drm_fb_helper_surface_size sizes; + struct drm_mode_set *mode_set; int gamma_size = 0; memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size)); @@ -1795,9 +1789,8 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, } crtc_count = 0; - for (i = 0; i < fb_helper->crtc_count; i++) { + drm_client_display_for_each_modeset(mode_set, fb_helper->display) { struct drm_display_mode *desired_mode; - struct drm_mode_set *mode_set; int x, y, j; /* in case of tile group, are we the last tile vert or horiz? * If no tile group you are always the last one both vertically @@ -1805,19 +1798,18 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, */ bool lastv = true, lasth = true; - desired_mode = fb_helper->crtc_info[i].desired_mode; - mode_set = &fb_helper->crtc_info[i].mode_set; + desired_mode = mode_set->mode; if (!desired_mode) continue; crtc_count++; - x = fb_helper->crtc_info[i].x; - y = fb_helper->crtc_info[i].y; + x = mode_set->x; + y = mode_set->y; if (gamma_size == 0) - gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size; + gamma_size = mode_set->crtc->gamma_size; sizes.surface_width = max_t(u32, desired_mode->hdisplay + x, sizes.surface_width); sizes.surface_height = max_t(u32, desired_mode->vdisplay + y, sizes.surface_height); @@ -1844,7 +1836,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, /* First time: disable all crtc's.. */ if (!fb_helper->deferred_setup && !READ_ONCE(fb_helper->dev->master)) - restore_fbdev_mode(fb_helper); + drm_client_display_restore(fb_helper->display); return -EAGAIN; } @@ -2379,6 +2371,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, u32 width, u32 height) { 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; @@ -2402,6 +2395,10 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, goto out; } + display = drm_client_display_create(dev); + if (IS_ERR(display)) + goto out; + mutex_lock(&fb_helper->dev->mode_config.mutex); if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0) DRM_DEBUG_KMS("No connectors reported connected with modes\n"); @@ -2440,24 +2437,29 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, struct drm_fb_offset *offset = &offsets[i]; if (mode && fb_crtc) { - struct drm_mode_set *modeset = &fb_crtc->mode_set; 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); + if (WARN_ON(!modeset)) { + drm_client_display_free(display); + goto out; + } DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n", - mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y); + mode->name, modeset->crtc->base.id, offset->x, offset->y); - fb_crtc->desired_mode = mode; - fb_crtc->x = offset->x; - fb_crtc->y = offset->y; - modeset->mode = drm_mode_duplicate(dev, - fb_crtc->desired_mode); + 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; } } + + drm_client_display_free(fb_helper->display); + fb_helper->display = display; out: kfree(crtcs); kfree(modes); @@ -2476,11 +2478,10 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) { struct fb_info *info = fb_helper->fbdev; unsigned int rotation, sw_rotations = 0; + struct drm_mode_set *modeset; int i; - for (i = 0; i < fb_helper->crtc_count; i++) { - struct drm_mode_set *modeset = &fb_helper->crtc_info[i].mode_set; - + drm_client_display_for_each_modeset(modeset, fb_helper->display) { if (!modeset->num_connectors) continue; diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index d1e45c832cd5..e2df40ad5063 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -155,6 +155,14 @@ struct drm_fb_helper_connector { struct drm_fb_helper { struct drm_framebuffer *fb; struct drm_device *dev; + + /** + * @display: + * + * Display representation. + */ + struct drm_client_display *display; + int crtc_count; struct drm_fb_helper_crtc *crtc_info; int connector_count; -- 2.15.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel