1// SPDX-License-Identifier: GPL-2.0 or MIT
2/*
3 * Copyright 2018 Noralf Trønnes
4 */
5
6#include <linux/iosys-map.h>
7#include <linux/list.h>
8#include <linux/module.h>
9#include <linux/mutex.h>
10#include <linux/seq_file.h>
11#include <linux/slab.h>
12
13#include <drm/drm_client.h>
14#include <drm/drm_debugfs.h>
15#include <drm/drm_device.h>
16#include <drm/drm_drv.h>
17#include <drm/drm_file.h>
18#include <drm/drm_fourcc.h>
19#include <drm/drm_framebuffer.h>
20#include <drm/drm_gem.h>
21#include <drm/drm_mode.h>
22#include <drm/drm_print.h>
23
24#include "drm_crtc_internal.h"
25#include "drm_internal.h"
26
27/**
28 * DOC: overview
29 *
30 * This library provides support for clients running in the kernel like fbdev and bootsplash.
31 *
32 * GEM drivers which provide a GEM based dumb buffer with a virtual address are supported.
33 */
34
35static int drm_client_open(struct drm_client_dev *client)
36{
37	struct drm_device *dev = client->dev;
38	struct drm_file *file;
39
40	file = drm_file_alloc(dev->primary);
41	if (IS_ERR(file))
42		return PTR_ERR(file);
43
44	mutex_lock(&dev->filelist_mutex);
45	list_add(&file->lhead, &dev->filelist_internal);
46	mutex_unlock(&dev->filelist_mutex);
47
48	client->file = file;
49
50	return 0;
51}
52
53static void drm_client_close(struct drm_client_dev *client)
54{
55	struct drm_device *dev = client->dev;
56
57	mutex_lock(&dev->filelist_mutex);
58	list_del(&client->file->lhead);
59	mutex_unlock(&dev->filelist_mutex);
60
61	drm_file_free(client->file);
62}
63
64/**
65 * drm_client_init - Initialise a DRM client
66 * @dev: DRM device
67 * @client: DRM client
68 * @name: Client name
69 * @funcs: DRM client functions (optional)
70 *
71 * This initialises the client and opens a &drm_file.
72 * Use drm_client_register() to complete the process.
73 * The caller needs to hold a reference on @dev before calling this function.
74 * The client is freed when the &drm_device is unregistered. See drm_client_release().
75 *
76 * Returns:
77 * Zero on success or negative error code on failure.
78 */
79int drm_client_init(struct drm_device *dev, struct drm_client_dev *client,
80		    const char *name, const struct drm_client_funcs *funcs)
81{
82	int ret;
83
84	if (!drm_core_check_feature(dev, DRIVER_MODESET) || !dev->driver->dumb_create)
85		return -EOPNOTSUPP;
86
87	if (funcs && !try_module_get(funcs->owner))
88		return -ENODEV;
89
90	client->dev = dev;
91	client->name = name;
92	client->funcs = funcs;
93
94	ret = drm_client_modeset_create(client);
95	if (ret)
96		goto err_put_module;
97
98	ret = drm_client_open(client);
99	if (ret)
100		goto err_free;
101
102	drm_dev_get(dev);
103
104	return 0;
105
106err_free:
107	drm_client_modeset_free(client);
108err_put_module:
109	if (funcs)
110		module_put(funcs->owner);
111
112	return ret;
113}
114EXPORT_SYMBOL(drm_client_init);
115
116/**
117 * drm_client_register - Register client
118 * @client: DRM client
119 *
120 * Add the client to the &drm_device client list to activate its callbacks.
121 * @client must be initialized by a call to drm_client_init(). After
122 * drm_client_register() it is no longer permissible to call drm_client_release()
123 * directly (outside the unregister callback), instead cleanup will happen
124 * automatically on driver unload.
125 *
126 * Registering a client generates a hotplug event that allows the client
127 * to set up its display from pre-existing outputs. The client must have
128 * initialized its state to able to handle the hotplug event successfully.
129 */
130void drm_client_register(struct drm_client_dev *client)
131{
132	struct drm_device *dev = client->dev;
133	int ret;
134
135	mutex_lock(&dev->clientlist_mutex);
136	list_add(&client->list, &dev->clientlist);
137
138	if (client->funcs && client->funcs->hotplug) {
139		/*
140		 * Perform an initial hotplug event to pick up the
141		 * display configuration for the client. This step
142		 * has to be performed *after* registering the client
143		 * in the list of clients, or a concurrent hotplug
144		 * event might be lost; leaving the display off.
145		 *
146		 * Hold the clientlist_mutex as for a regular hotplug
147		 * event.
148		 */
149		ret = client->funcs->hotplug(client);
150		if (ret)
151			drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
152	}
153	mutex_unlock(&dev->clientlist_mutex);
154}
155EXPORT_SYMBOL(drm_client_register);
156
157/**
158 * drm_client_release - Release DRM client resources
159 * @client: DRM client
160 *
161 * Releases resources by closing the &drm_file that was opened by drm_client_init().
162 * It is called automatically if the &drm_client_funcs.unregister callback is _not_ set.
163 *
164 * This function should only be called from the unregister callback. An exception
165 * is fbdev which cannot free the buffer if userspace has open file descriptors.
166 *
167 * Note:
168 * Clients cannot initiate a release by themselves. This is done to keep the code simple.
169 * The driver has to be unloaded before the client can be unloaded.
170 */
171void drm_client_release(struct drm_client_dev *client)
172{
173	struct drm_device *dev = client->dev;
174
175	drm_dbg_kms(dev, "%s\n", client->name);
176
177	drm_client_modeset_free(client);
178	drm_client_close(client);
179	drm_dev_put(dev);
180	if (client->funcs)
181		module_put(client->funcs->owner);
182}
183EXPORT_SYMBOL(drm_client_release);
184
185void drm_client_dev_unregister(struct drm_device *dev)
186{
187	struct drm_client_dev *client, *tmp;
188
189	if (!drm_core_check_feature(dev, DRIVER_MODESET))
190		return;
191
192	mutex_lock(&dev->clientlist_mutex);
193	list_for_each_entry_safe(client, tmp, &dev->clientlist, list) {
194		list_del(&client->list);
195		if (client->funcs && client->funcs->unregister) {
196			client->funcs->unregister(client);
197		} else {
198			drm_client_release(client);
199			kfree(client);
200		}
201	}
202	mutex_unlock(&dev->clientlist_mutex);
203}
204
205/**
206 * drm_client_dev_hotplug - Send hotplug event to clients
207 * @dev: DRM device
208 *
209 * This function calls the &drm_client_funcs.hotplug callback on the attached clients.
210 *
211 * drm_kms_helper_hotplug_event() calls this function, so drivers that use it
212 * don't need to call this function themselves.
213 */
214void drm_client_dev_hotplug(struct drm_device *dev)
215{
216	struct drm_client_dev *client;
217	int ret;
218
219	if (!drm_core_check_feature(dev, DRIVER_MODESET))
220		return;
221
222	if (!dev->mode_config.num_connector) {
223		drm_dbg_kms(dev, "No connectors found, will not send hotplug events!\n");
224		return;
225	}
226
227	mutex_lock(&dev->clientlist_mutex);
228	list_for_each_entry(client, &dev->clientlist, list) {
229		if (!client->funcs || !client->funcs->hotplug)
230			continue;
231
232		if (client->hotplug_failed)
233			continue;
234
235		ret = client->funcs->hotplug(client);
236		drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
237		if (ret)
238			client->hotplug_failed = true;
239	}
240	mutex_unlock(&dev->clientlist_mutex);
241}
242EXPORT_SYMBOL(drm_client_dev_hotplug);
243
244void drm_client_dev_restore(struct drm_device *dev)
245{
246	struct drm_client_dev *client;
247	int ret;
248
249	if (!drm_core_check_feature(dev, DRIVER_MODESET))
250		return;
251
252	mutex_lock(&dev->clientlist_mutex);
253	list_for_each_entry(client, &dev->clientlist, list) {
254		if (!client->funcs || !client->funcs->restore)
255			continue;
256
257		ret = client->funcs->restore(client);
258		drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
259		if (!ret) /* The first one to return zero gets the privilege to restore */
260			break;
261	}
262	mutex_unlock(&dev->clientlist_mutex);
263}
264
265static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
266{
267	if (buffer->gem) {
268		drm_gem_vunmap_unlocked(buffer->gem, &buffer->map);
269		drm_gem_object_put(buffer->gem);
270	}
271
272	kfree(buffer);
273}
274
275static struct drm_client_buffer *
276drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height,
277			 u32 format, u32 *handle)
278{
279	const struct drm_format_info *info = drm_format_info(format);
280	struct drm_mode_create_dumb dumb_args = { };
281	struct drm_device *dev = client->dev;
282	struct drm_client_buffer *buffer;
283	struct drm_gem_object *obj;
284	int ret;
285
286	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
287	if (!buffer)
288		return ERR_PTR(-ENOMEM);
289
290	buffer->client = client;
291
292	dumb_args.width = width;
293	dumb_args.height = height;
294	dumb_args.bpp = drm_format_info_bpp(info, 0);
295	ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
296	if (ret)
297		goto err_delete;
298
299	obj = drm_gem_object_lookup(client->file, dumb_args.handle);
300	if (!obj)  {
301		ret = -ENOENT;
302		goto err_delete;
303	}
304
305	buffer->pitch = dumb_args.pitch;
306	buffer->gem = obj;
307	*handle = dumb_args.handle;
308
309	return buffer;
310
311err_delete:
312	drm_client_buffer_delete(buffer);
313
314	return ERR_PTR(ret);
315}
316
317/**
318 * drm_client_buffer_vmap - Map DRM client buffer into address space
319 * @buffer: DRM client buffer
320 * @map_copy: Returns the mapped memory's address
321 *
322 * This function maps a client buffer into kernel address space. If the
323 * buffer is already mapped, it returns the existing mapping's address.
324 *
325 * Client buffer mappings are not ref'counted. Each call to
326 * drm_client_buffer_vmap() should be followed by a call to
327 * drm_client_buffer_vunmap(); or the client buffer should be mapped
328 * throughout its lifetime.
329 *
330 * The returned address is a copy of the internal value. In contrast to
331 * other vmap interfaces, you don't need it for the client's vunmap
332 * function. So you can modify it at will during blit and draw operations.
333 *
334 * Returns:
335 *	0 on success, or a negative errno code otherwise.
336 */
337int
338drm_client_buffer_vmap(struct drm_client_buffer *buffer,
339		       struct iosys_map *map_copy)
340{
341	struct iosys_map *map = &buffer->map;
342	int ret;
343
344	/*
345	 * FIXME: The dependency on GEM here isn't required, we could
346	 * convert the driver handle to a dma-buf instead and use the
347	 * backend-agnostic dma-buf vmap support instead. This would
348	 * require that the handle2fd prime ioctl is reworked to pull the
349	 * fd_install step out of the driver backend hooks, to make that
350	 * final step optional for internal users.
351	 */
352	ret = drm_gem_vmap_unlocked(buffer->gem, map);
353	if (ret)
354		return ret;
355
356	*map_copy = *map;
357
358	return 0;
359}
360EXPORT_SYMBOL(drm_client_buffer_vmap);
361
362/**
363 * drm_client_buffer_vunmap - Unmap DRM client buffer
364 * @buffer: DRM client buffer
365 *
366 * This function removes a client buffer's memory mapping. Calling this
367 * function is only required by clients that manage their buffer mappings
368 * by themselves.
369 */
370void drm_client_buffer_vunmap(struct drm_client_buffer *buffer)
371{
372	struct iosys_map *map = &buffer->map;
373
374	drm_gem_vunmap_unlocked(buffer->gem, map);
375}
376EXPORT_SYMBOL(drm_client_buffer_vunmap);
377
378static void drm_client_buffer_rmfb(struct drm_client_buffer *buffer)
379{
380	int ret;
381
382	if (!buffer->fb)
383		return;
384
385	ret = drm_mode_rmfb(buffer->client->dev, buffer->fb->base.id, buffer->client->file);
386	if (ret)
387		drm_err(buffer->client->dev,
388			"Error removing FB:%u (%d)\n", buffer->fb->base.id, ret);
389
390	buffer->fb = NULL;
391}
392
393static int drm_client_buffer_addfb(struct drm_client_buffer *buffer,
394				   u32 width, u32 height, u32 format,
395				   u32 handle)
396{
397	struct drm_client_dev *client = buffer->client;
398	struct drm_mode_fb_cmd fb_req = { };
399	const struct drm_format_info *info;
400	int ret;
401
402	info = drm_format_info(format);
403	fb_req.bpp = drm_format_info_bpp(info, 0);
404	fb_req.depth = info->depth;
405	fb_req.width = width;
406	fb_req.height = height;
407	fb_req.handle = handle;
408	fb_req.pitch = buffer->pitch;
409
410	ret = drm_mode_addfb(client->dev, &fb_req, client->file);
411	if (ret)
412		return ret;
413
414	buffer->fb = drm_framebuffer_lookup(client->dev, buffer->client->file, fb_req.fb_id);
415	if (WARN_ON(!buffer->fb))
416		return -ENOENT;
417
418	/* drop the reference we picked up in framebuffer lookup */
419	drm_framebuffer_put(buffer->fb);
420
421	strscpy(buffer->fb->comm, client->name, TASK_COMM_LEN);
422
423	return 0;
424}
425
426/**
427 * drm_client_framebuffer_create - Create a client framebuffer
428 * @client: DRM client
429 * @width: Framebuffer width
430 * @height: Framebuffer height
431 * @format: Buffer format
432 *
433 * This function creates a &drm_client_buffer which consists of a
434 * &drm_framebuffer backed by a dumb buffer.
435 * Call drm_client_framebuffer_delete() to free the buffer.
436 *
437 * Returns:
438 * Pointer to a client buffer or an error pointer on failure.
439 */
440struct drm_client_buffer *
441drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)
442{
443	struct drm_client_buffer *buffer;
444	u32 handle;
445	int ret;
446
447	buffer = drm_client_buffer_create(client, width, height, format,
448					  &handle);
449	if (IS_ERR(buffer))
450		return buffer;
451
452	ret = drm_client_buffer_addfb(buffer, width, height, format, handle);
453
454	/*
455	 * The handle is only needed for creating the framebuffer, destroy it
456	 * again to solve a circular dependency should anybody export the GEM
457	 * object as DMA-buf. The framebuffer and our buffer structure are still
458	 * holding references to the GEM object to prevent its destruction.
459	 */
460	drm_mode_destroy_dumb(client->dev, handle, client->file);
461
462	if (ret) {
463		drm_client_buffer_delete(buffer);
464		return ERR_PTR(ret);
465	}
466
467	return buffer;
468}
469EXPORT_SYMBOL(drm_client_framebuffer_create);
470
471/**
472 * drm_client_framebuffer_delete - Delete a client framebuffer
473 * @buffer: DRM client buffer (can be NULL)
474 */
475void drm_client_framebuffer_delete(struct drm_client_buffer *buffer)
476{
477	if (!buffer)
478		return;
479
480	drm_client_buffer_rmfb(buffer);
481	drm_client_buffer_delete(buffer);
482}
483EXPORT_SYMBOL(drm_client_framebuffer_delete);
484
485/**
486 * drm_client_framebuffer_flush - Manually flush client framebuffer
487 * @buffer: DRM client buffer (can be NULL)
488 * @rect: Damage rectangle (if NULL flushes all)
489 *
490 * This calls &drm_framebuffer_funcs->dirty (if present) to flush buffer changes
491 * for drivers that need it.
492 *
493 * Returns:
494 * Zero on success or negative error code on failure.
495 */
496int drm_client_framebuffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect)
497{
498	if (!buffer || !buffer->fb || !buffer->fb->funcs->dirty)
499		return 0;
500
501	if (rect) {
502		struct drm_clip_rect clip = {
503			.x1 = rect->x1,
504			.y1 = rect->y1,
505			.x2 = rect->x2,
506			.y2 = rect->y2,
507		};
508
509		return buffer->fb->funcs->dirty(buffer->fb, buffer->client->file,
510						0, 0, &clip, 1);
511	}
512
513	return buffer->fb->funcs->dirty(buffer->fb, buffer->client->file,
514					0, 0, NULL, 0);
515}
516EXPORT_SYMBOL(drm_client_framebuffer_flush);
517
518#ifdef CONFIG_DEBUG_FS
519static int drm_client_debugfs_internal_clients(struct seq_file *m, void *data)
520{
521	struct drm_debugfs_entry *entry = m->private;
522	struct drm_device *dev = entry->dev;
523	struct drm_printer p = drm_seq_file_printer(m);
524	struct drm_client_dev *client;
525
526	mutex_lock(&dev->clientlist_mutex);
527	list_for_each_entry(client, &dev->clientlist, list)
528		drm_printf(&p, "%s\n", client->name);
529	mutex_unlock(&dev->clientlist_mutex);
530
531	return 0;
532}
533
534static const struct drm_debugfs_info drm_client_debugfs_list[] = {
535	{ "internal_clients", drm_client_debugfs_internal_clients, 0 },
536};
537
538void drm_client_debugfs_init(struct drm_minor *minor)
539{
540	drm_debugfs_add_files(minor->dev, drm_client_debugfs_list,
541			      ARRAY_SIZE(drm_client_debugfs_list));
542}
543#endif
544