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