Commit 2e2245ef authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-next-2023-01-26' of git://anongit.freedesktop.org/drm/drm-misc into drm-next



drm-misc-next for v6.3:

UAPI Changes:

Cross-subsystem Changes:

Core Changes:

 * fbdev-helper: Streamline code in generic fbdev and its helpers

 * TTM: Fixes plus their reverts

Driver Changes:

 * accel/ivpu: Typo fixes

 * i915: TTM-related fixes

 * nouveau: Remove unused return value from disable helper

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/Y9I2nOzHxTxPeTjg@linux-uq9g
parents 68de345e 6ca80b9e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -608,7 +608,7 @@ static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable)

	ret = REGB_POLL_FLD(MTL_BUTTRESS_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
	if (ret) {
		ivpu_err(vdev, "Failed to sync before D0i3 tansition: %d\n", ret);
		ivpu_err(vdev, "Failed to sync before D0i3 transition: %d\n", ret);
		return ret;
	}

@@ -621,7 +621,7 @@ static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable)

	ret = REGB_POLL_FLD(MTL_BUTTRESS_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
	if (ret)
		ivpu_err(vdev, "Failed to sync after D0i3 tansition: %d\n", ret);
		ivpu_err(vdev, "Failed to sync after D0i3 transition: %d\n", ret);

	return ret;
}
+2 −2
Original line number Diff line number Diff line
@@ -129,7 +129,7 @@ int armada_fbdev_init(struct drm_device *dev)

	priv->fbdev = fbh;

	drm_fb_helper_prepare(dev, fbh, &armada_fb_helper_funcs);
	drm_fb_helper_prepare(dev, fbh, 32, &armada_fb_helper_funcs);

	ret = drm_fb_helper_init(dev, fbh);
	if (ret) {
@@ -137,7 +137,7 @@ int armada_fbdev_init(struct drm_device *dev)
		goto err_fb_helper;
	}

	ret = drm_fb_helper_initial_config(fbh, 32);
	ret = drm_fb_helper_initial_config(fbh);
	if (ret) {
		DRM_ERROR("failed to set initial config\n");
		goto err_fb_setup;
+10 −0
Original line number Diff line number Diff line
@@ -198,13 +198,23 @@ void drm_client_dev_hotplug(struct drm_device *dev)
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return;

	if (!dev->mode_config.num_connector) {
		drm_dbg_kms(dev, "No connectors found, will not send hotplug events!\n");
		return;
	}

	mutex_lock(&dev->clientlist_mutex);
	list_for_each_entry(client, &dev->clientlist, list) {
		if (!client->funcs || !client->funcs->hotplug)
			continue;

		if (client->hotplug_failed)
			continue;

		ret = client->funcs->hotplug(client);
		drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
		if (ret)
			client->hotplug_failed = true;
	}
	mutex_unlock(&dev->clientlist_mutex);
}
+41 −17
Original line number Diff line number Diff line
@@ -414,14 +414,30 @@ static void drm_fb_helper_damage_work(struct work_struct *work)
 * drm_fb_helper_prepare - setup a drm_fb_helper structure
 * @dev: DRM device
 * @helper: driver-allocated fbdev helper structure to set up
 * @preferred_bpp: Preferred bits per pixel for the device.
 * @funcs: pointer to structure of functions associate with this helper
 *
 * Sets up the bare minimum to make the framebuffer helper usable. This is
 * useful to implement race-free initialization of the polling helpers.
 */
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
			   unsigned int preferred_bpp,
			   const struct drm_fb_helper_funcs *funcs)
{
	/*
	 * Pick a preferred bpp of 32 if no value has been given. This
	 * will select XRGB8888 for the framebuffer formats. All drivers
	 * have to support XRGB8888 for backwards compatibility with legacy
	 * userspace, so it's the safe choice here.
	 *
	 * TODO: Replace struct drm_mode_config.preferred_depth and this
	 *       bpp value with a preferred format that is given as struct
	 *       drm_format_info. Then derive all other values from the
	 *       format.
	 */
	if (!preferred_bpp)
		preferred_bpp = 32;

	INIT_LIST_HEAD(&helper->kernel_fb_list);
	spin_lock_init(&helper->damage_lock);
	INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker);
@@ -430,9 +446,22 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
	mutex_init(&helper->lock);
	helper->funcs = funcs;
	helper->dev = dev;
	helper->preferred_bpp = preferred_bpp;
}
EXPORT_SYMBOL(drm_fb_helper_prepare);

/**
 * drm_fb_helper_unprepare - clean up a drm_fb_helper structure
 * @fb_helper: driver-allocated fbdev helper structure to set up
 *
 * Cleans up the framebuffer helper. Inverse of drm_fb_helper_prepare().
 */
void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)
{
	mutex_destroy(&fb_helper->lock);
}
EXPORT_SYMBOL(drm_fb_helper_unprepare);

/**
 * drm_fb_helper_init - initialize a &struct drm_fb_helper
 * @dev: drm device
@@ -559,7 +588,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
	}
	mutex_unlock(&kernel_fb_helper_lock);

	mutex_destroy(&fb_helper->lock);
	drm_fb_helper_unprepare(fb_helper);

	if (!fb_helper->client.funcs)
		drm_client_release(&fb_helper->client);
@@ -1772,7 +1801,7 @@ static uint32_t drm_fb_helper_find_color_mode_format(struct drm_fb_helper *fb_he
	return drm_fb_helper_find_format(fb_helper, formats, format_count, bpp, depth);
}

static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferred_bpp,
static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper,
				      struct drm_fb_helper_surface_size *sizes)
{
	struct drm_client_dev *client = &fb_helper->client;
@@ -1817,7 +1846,7 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe
		surface_format = drm_fb_helper_find_color_mode_format(fb_helper,
								      plane->format_types,
								      plane->format_count,
								      preferred_bpp);
								      fb_helper->preferred_bpp);
		if (surface_format != DRM_FORMAT_INVALID)
			break; /* found supported format */
	}
@@ -1889,7 +1918,7 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe
	return 0;
}

static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferred_bpp,
static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper,
				    struct drm_fb_helper_surface_size *sizes)
{
	struct drm_client_dev *client = &fb_helper->client;
@@ -1898,7 +1927,7 @@ static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferr
	int ret;

	mutex_lock(&client->modeset_mutex);
	ret = __drm_fb_helper_find_sizes(fb_helper, preferred_bpp, sizes);
	ret = __drm_fb_helper_find_sizes(fb_helper, sizes);
	mutex_unlock(&client->modeset_mutex);

	if (ret)
@@ -1920,14 +1949,13 @@ static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferr
 * Allocates the backing storage and sets up the fbdev info structure through
 * the ->fb_probe callback.
 */
static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
					 int preferred_bpp)
static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper)
{
	struct drm_client_dev *client = &fb_helper->client;
	struct drm_fb_helper_surface_size sizes;
	int ret;

	ret = drm_fb_helper_find_sizes(fb_helper, preferred_bpp, &sizes);
	ret = drm_fb_helper_find_sizes(fb_helper, &sizes);
	if (ret) {
		/* First time: disable all crtc's.. */
		if (!fb_helper->deferred_setup)
@@ -2105,8 +2133,7 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)

/* Note: Drops fb_helper->lock before returning. */
static int
__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
					  int bpp_sel)
__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper)
{
	struct drm_device *dev = fb_helper->dev;
	struct fb_info *info;
@@ -2117,10 +2144,9 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
	height = dev->mode_config.max_height;

	drm_client_modeset_probe(&fb_helper->client, width, height);
	ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
	ret = drm_fb_helper_single_fb_probe(fb_helper);
	if (ret < 0) {
		if (ret == -EAGAIN) {
			fb_helper->preferred_bpp = bpp_sel;
			fb_helper->deferred_setup = true;
			ret = 0;
		}
@@ -2166,7 +2192,6 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
/**
 * drm_fb_helper_initial_config - setup a sane initial connector configuration
 * @fb_helper: fb_helper device struct
 * @bpp_sel: bpp value to use for the framebuffer configuration
 *
 * Scans the CRTCs and connectors and tries to put together an initial setup.
 * At the moment, this is a cloned configuration across all heads with
@@ -2204,7 +2229,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
 * RETURNS:
 * Zero if everything went ok, nonzero otherwise.
 */
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
{
	int ret;

@@ -2212,7 +2237,7 @@ int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
		return 0;

	mutex_lock(&fb_helper->lock);
	ret = __drm_fb_helper_initial_config_and_unlock(fb_helper, bpp_sel);
	ret = __drm_fb_helper_initial_config_and_unlock(fb_helper);

	return ret;
}
@@ -2248,8 +2273,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)

	mutex_lock(&fb_helper->lock);
	if (fb_helper->deferred_setup) {
		err = __drm_fb_helper_initial_config_and_unlock(fb_helper,
				fb_helper->preferred_bpp);
		err = __drm_fb_helper_initial_config_and_unlock(fb_helper);
		return err;
	}

+47 −84
Original line number Diff line number Diff line
@@ -43,20 +43,18 @@ static int drm_fbdev_fb_release(struct fb_info *info, int user)
	return 0;
}

static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper)
static void drm_fbdev_fb_destroy(struct fb_info *info)
{
	struct fb_info *fbi = fb_helper->info;
	struct drm_fb_helper *fb_helper = info->par;
	void *shadow = NULL;

	if (!fb_helper->dev)
		return;

	if (fbi) {
		if (fbi->fbdefio)
			fb_deferred_io_cleanup(fbi);
	if (info->fbdefio)
		fb_deferred_io_cleanup(info);
	if (drm_fbdev_use_shadow_fb(fb_helper))
			shadow = fbi->screen_buffer;
	}
		shadow = info->screen_buffer;

	drm_fb_helper_fini(fb_helper);

@@ -66,24 +64,10 @@ static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper)
		drm_client_buffer_vunmap(fb_helper->buffer);

	drm_client_framebuffer_delete(fb_helper->buffer);
}

static void drm_fbdev_release(struct drm_fb_helper *fb_helper)
{
	drm_fbdev_cleanup(fb_helper);
	drm_client_release(&fb_helper->client);
	kfree(fb_helper);
}

/*
 * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of
 * unregister_framebuffer() or fb_release().
 */
static void drm_fbdev_fb_destroy(struct fb_info *info)
{
	drm_fbdev_release(info->par);
}

static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
	struct drm_fb_helper *fb_helper = info->par;
@@ -186,7 +170,7 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
	struct drm_device *dev = fb_helper->dev;
	struct drm_client_buffer *buffer;
	struct drm_framebuffer *fb;
	struct fb_info *fbi;
	struct fb_info *info;
	u32 format;
	struct iosys_map map;
	int ret;
@@ -205,35 +189,35 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
	fb_helper->fb = buffer->fb;
	fb = buffer->fb;

	fbi = drm_fb_helper_alloc_info(fb_helper);
	if (IS_ERR(fbi))
		return PTR_ERR(fbi);
	info = drm_fb_helper_alloc_info(fb_helper);
	if (IS_ERR(info))
		return PTR_ERR(info);

	fbi->fbops = &drm_fbdev_fb_ops;
	fbi->screen_size = sizes->surface_height * fb->pitches[0];
	fbi->fix.smem_len = fbi->screen_size;
	fbi->flags = FBINFO_DEFAULT;
	info->fbops = &drm_fbdev_fb_ops;
	info->screen_size = sizes->surface_height * fb->pitches[0];
	info->fix.smem_len = info->screen_size;
	info->flags = FBINFO_DEFAULT;

	drm_fb_helper_fill_info(fbi, fb_helper, sizes);
	drm_fb_helper_fill_info(info, fb_helper, sizes);

	if (drm_fbdev_use_shadow_fb(fb_helper)) {
		fbi->screen_buffer = vzalloc(fbi->screen_size);
		if (!fbi->screen_buffer)
		info->screen_buffer = vzalloc(info->screen_size);
		if (!info->screen_buffer)
			return -ENOMEM;
		fbi->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
		info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;

		fbi->fbdefio = &drm_fbdev_defio;
		fb_deferred_io_init(fbi);
		info->fbdefio = &drm_fbdev_defio;
		fb_deferred_io_init(info);
	} else {
		/* buffer is mapped for HW framebuffer */
		ret = drm_client_buffer_vmap(fb_helper->buffer, &map);
		if (ret)
			return ret;
		if (map.is_iomem) {
			fbi->screen_base = map.vaddr_iomem;
			info->screen_base = map.vaddr_iomem;
		} else {
			fbi->screen_buffer = map.vaddr;
			fbi->flags |= FBINFO_VIRTFB;
			info->screen_buffer = map.vaddr;
			info->flags |= FBINFO_VIRTFB;
		}

		/*
@@ -242,10 +226,10 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
		 * case.
		 */
#if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM)
		if (fb_helper->hint_leak_smem_start && fbi->fix.smem_start == 0 &&
		if (fb_helper->hint_leak_smem_start && info->fix.smem_start == 0 &&
		    !drm_WARN_ON_ONCE(dev, map.is_iomem))
			fbi->fix.smem_start =
				page_to_phys(virt_to_page(fbi->screen_buffer));
			info->fix.smem_start =
				page_to_phys(virt_to_page(info->screen_buffer));
#endif
	}

@@ -362,11 +346,13 @@ static void drm_fbdev_client_unregister(struct drm_client_dev *client)
{
	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);

	if (fb_helper->info)
		/* drm_fbdev_fb_destroy() takes care of cleanup */
	if (fb_helper->info) {
		drm_fb_helper_unregister_info(fb_helper);
	else
		drm_fbdev_release(fb_helper);
	} else {
		drm_client_release(&fb_helper->client);
		drm_fb_helper_unprepare(fb_helper);
		kfree(fb_helper);
	}
}

static int drm_fbdev_client_restore(struct drm_client_dev *client)
@@ -382,41 +368,26 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client)
	struct drm_device *dev = client->dev;
	int ret;

	/* Setup is not retried if it has failed */
	if (!fb_helper->dev && fb_helper->funcs)
		return 0;

	if (dev->fb_helper)
		return drm_fb_helper_hotplug_event(dev->fb_helper);

	if (!dev->mode_config.num_connector) {
		drm_dbg_kms(dev, "No connectors found, will not create framebuffer!\n");
		return 0;
	}

	drm_fb_helper_prepare(dev, fb_helper, &drm_fb_helper_generic_funcs);

	ret = drm_fb_helper_init(dev, fb_helper);
	if (ret)
		goto err;
		goto err_drm_err;

	if (!drm_drv_uses_atomic_modeset(dev))
		drm_helper_disable_unused_functions(dev);

	ret = drm_fb_helper_initial_config(fb_helper, fb_helper->preferred_bpp);
	ret = drm_fb_helper_initial_config(fb_helper);
	if (ret)
		goto err_cleanup;
		goto err_drm_fb_helper_fini;

	return 0;

err_cleanup:
	drm_fbdev_cleanup(fb_helper);
err:
	fb_helper->dev = NULL;
	fb_helper->info = NULL;

err_drm_fb_helper_fini:
	drm_fb_helper_fini(fb_helper);
err_drm_err:
	drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret);

	return ret;
}

@@ -465,33 +436,25 @@ void drm_fbdev_generic_setup(struct drm_device *dev,
	fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
	if (!fb_helper)
		return;
	drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fb_helper_generic_funcs);

	ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
	if (ret) {
		kfree(fb_helper);
		drm_err(dev, "Failed to register client: %d\n", ret);
		return;
		goto err_drm_client_init;
	}

	/*
	 * Pick a preferred bpp of 32 if no value has been given. This
	 * will select XRGB8888 for the framebuffer formats. All drivers
	 * have to support XRGB8888 for backwards compatibility with legacy
	 * userspace, so it's the safe choice here.
	 *
	 * TODO: Replace struct drm_mode_config.preferred_depth and this
	 *       bpp value with a preferred format that is given as struct
	 *       drm_format_info. Then derive all other values from the
	 *       format.
	 */
	if (!preferred_bpp)
		preferred_bpp = 32;
	fb_helper->preferred_bpp = preferred_bpp;

	ret = drm_fbdev_client_hotplug(&fb_helper->client);
	if (ret)
		drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);

	drm_client_register(&fb_helper->client);

	return;

err_drm_client_init:
	drm_fb_helper_unprepare(fb_helper);
	kfree(fb_helper);
	return;
}
EXPORT_SYMBOL(drm_fbdev_generic_setup);
Loading