From fc66811ce1de3f79cbe3f83c2fdb1ef3e2cdac1c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 21 Jan 2014 12:02:26 +0100 Subject: drm/doc: Fix up kerneldoc in drm_edid.c v2: Also do s/RETURNS/Returns/, less yelling in docs is always good. Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_edid.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index b924306b8477..2d54e460c95b 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1098,10 +1098,14 @@ EXPORT_SYMBOL(drm_edid_is_valid); /** * Get EDID information via I2C. * - * \param adapter : i2c device adaptor - * \param buf : EDID data buffer to be filled - * \param len : EDID data buffer length - * \return 0 on success or -1 on failure. + * @adapter : i2c device adaptor + * @buf: EDID data buffer to be filled + * @block: 128 byte EDID block to start fetching from + * @len: EDID data buffer length to fetch + * + * Returns: + * + * 0 on success or -1 on failure. * * Try to fetch EDID information by calling i2c driver function. */ @@ -1243,9 +1247,11 @@ out: /** * Probe DDC presence. + * @adapter: i2c adapter to probe + * + * Returns: * - * \param adapter : i2c device adaptor - * \return 1 on success + * 1 on success */ bool drm_probe_ddc(struct i2c_adapter *adapter) @@ -1586,8 +1592,10 @@ bad_std_timing(u8 a, u8 b) /** * drm_mode_std - convert standard mode info (width, height, refresh) into mode + * @connector: connector of for the EDID block + * @edid: EDID block to scan * @t: standard timing params - * @timing_level: standard timing level + * @revision: standard timing level * * Take the standard timing params (in this case width, aspect, and refresh) * and convert them into a real mode using CVT/GTF/DMT. @@ -2132,6 +2140,7 @@ do_established_modes(struct detailed_timing *timing, void *c) /** * add_established_modes - get est. modes from EDID and add them + * @connector: connector of for the EDID block * @edid: EDID block to scan * * Each EDID block contains a bitmap of the supported "established modes" list @@ -2194,6 +2203,7 @@ do_standard_modes(struct detailed_timing *timing, void *c) /** * add_standard_modes - get std. modes from EDID and add them + * @connector: connector of for the EDID block * @edid: EDID block to scan * * Standard modes can be calculated using the appropriate standard (DMT, @@ -3300,6 +3310,7 @@ EXPORT_SYMBOL(drm_detect_hdmi_monitor); /** * drm_detect_monitor_audio - check monitor audio capability + * @edid: EDID block to scan * * Monitor should have CEA extension block. * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic @@ -3345,6 +3356,7 @@ EXPORT_SYMBOL(drm_detect_monitor_audio); /** * drm_rgb_quant_range_selectable - is RGB quantization range selectable? + * @edid: EDID block to scan * * Check whether the monitor reports the RGB quantization range selection * as supported. The AVI infoframe can then be used to inform the monitor -- cgit v1.2.1 From 89d61fc0f5d384f07f3e93af2bb52009ce26283a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 21 Jan 2014 12:39:00 +0100 Subject: drm/doc: Clean up and integrate kerneldoc for drm_gem.c Fairly incomplete, but at least a start. Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_gem.c | 63 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 5bbad873c798..2136052ccee1 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -85,9 +85,9 @@ #endif /** - * Initialize the GEM device fields + * drm_gem_init - Initialize the GEM device fields + * @dev: drm_devic structure to initialize */ - int drm_gem_init(struct drm_device *dev) { @@ -120,6 +120,11 @@ drm_gem_destroy(struct drm_device *dev) } /** + * drm_gem_object_init - initialize an allocated shmem-backed GEM object + * @dev: drm_device the object should be initialized for + * @obj: drm_gem_object to initialize + * @size: object size + * * Initialize an already allocated GEM object of the specified size with * shmfs backing store. */ @@ -141,6 +146,11 @@ int drm_gem_object_init(struct drm_device *dev, EXPORT_SYMBOL(drm_gem_object_init); /** + * drm_gem_object_init - initialize an allocated private GEM object + * @dev: drm_device the object should be initialized for + * @obj: drm_gem_object to initialize + * @size: object size + * * Initialize an already allocated GEM object of the specified size with * no GEM provided backing store. Instead the caller is responsible for * backing the object and handling it. @@ -176,6 +186,9 @@ drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) } /** + * drm_gem_object_free - release resources bound to userspace handles + * @obj: GEM object to clean up. + * * Called after the last handle to the object has been closed * * Removes any name for the object. Note that this must be @@ -225,7 +238,12 @@ drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) } /** - * Removes the mapping from handle to filp for this object. + * drm_gem_handle_delete - deletes the given file-private handle + * @filp: drm file-private structure to use for the handle look up + * @handle: userspace handle to delete + * + * Removes the GEM handle from the @filp lookup table and if this is the last + * handle also cleans up linked resources like GEM names. */ int drm_gem_handle_delete(struct drm_file *filp, u32 handle) @@ -270,6 +288,9 @@ EXPORT_SYMBOL(drm_gem_handle_delete); /** * drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers + * @file: drm file-private structure to remove the dumb handle from + * @dev: corresponding drm_device + * @handle: the dumb handle to remove * * This implements the ->dumb_destroy kms driver callback for drivers which use * gem to manage their backing storage. @@ -284,6 +305,9 @@ EXPORT_SYMBOL(drm_gem_dumb_destroy); /** * drm_gem_handle_create_tail - internal functions to create a handle + * @file_priv: drm file-private structure to register the handle for + * @obj: object to register + * @handlep: pionter to return the created handle to the caller * * This expects the dev->object_name_lock to be held already and will drop it * before returning. Used to avoid races in establishing new handles when @@ -336,6 +360,11 @@ drm_gem_handle_create_tail(struct drm_file *file_priv, } /** + * gem_handle_create - create a gem handle for an object + * @file_priv: drm file-private structure to register the handle for + * @obj: object to register + * @handlep: pionter to return the created handle to the caller + * * Create a handle for this object. This adds a handle reference * to the object, which includes a regular reference count. Callers * will likely want to dereference the object afterwards. @@ -536,6 +565,11 @@ drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, EXPORT_SYMBOL(drm_gem_object_lookup); /** + * drm_gem_close_ioctl - implementation of the GEM_CLOSE ioctl + * @dev: drm_device + * @data: ioctl data + * @file_priv: drm file-private structure + * * Releases the handle to an mm object. */ int @@ -554,6 +588,11 @@ drm_gem_close_ioctl(struct drm_device *dev, void *data, } /** + * drm_gem_flink_ioctl - implementation of the GEM_FLINK ioctl + * @dev: drm_device + * @data: ioctl data + * @file_priv: drm file-private structure + * * Create a global name for an object, returning the name. * * Note that the name does not hold a reference; when the object @@ -601,6 +640,11 @@ err: } /** + * drm_gem_open - implementation of the GEM_OPEN ioctl + * @dev: drm_device + * @data: ioctl data + * @file_priv: drm file-private structure + * * Open an object using the global name, returning a handle and the size. * * This handle (of course) holds a reference to the object, so the object @@ -640,6 +684,10 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, } /** + * gem_gem_open - initalizes GEM file-private structures at devnode open time + * @dev: drm_device which is being opened by userspace + * @file_private: drm file-private structure to set up + * * Called at device open time, sets up the structure for handling refcounting * of mm objects. */ @@ -650,7 +698,7 @@ drm_gem_open(struct drm_device *dev, struct drm_file *file_private) spin_lock_init(&file_private->table_lock); } -/** +/* * Called at device close to release the file's * handle references on objects. */ @@ -674,6 +722,10 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) } /** + * drm_gem_release - release file-private GEM resources + * @dev: drm_device which is being closed by userspace + * @file_private: drm file-private structure to clean up + * * Called at close time when the filp is going away. * * Releases any remaining references on objects by this filp. @@ -697,6 +749,9 @@ drm_gem_object_release(struct drm_gem_object *obj) EXPORT_SYMBOL(drm_gem_object_release); /** + * drm_gem_object_free - free a GEM object + * @kref: kref of the object to free + * * Called after the last reference to the object has been lost. * Must be called holding struct_ mutex * -- cgit v1.2.1 From aa4cd9100e0709ea0bc6f85090188ace895e51fe Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 22 Jan 2014 16:42:02 +0100 Subject: drm/doc: Document drm_helper_resume_force_mode Stumbled over while reviewing all occurences in the DRM doc talking about suspend/resume. Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc_helper.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index ea92b827e787..85d476abea6c 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -943,6 +943,15 @@ int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, } EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct); +/** + * drm_helper_resume_force_mode - force-restore mode setting configuration + * @dev: drm_device which should be restored + * + * Drivers which use the mode setting helpers can use this function to + * force-restore the mode setting configuration e.g. on resume or when something + * else might have trampled over the hw state (like some overzealous old BIOSen + * tended to do). + */ int drm_helper_resume_force_mode(struct drm_device *dev) { struct drm_crtc *crtc; -- cgit v1.2.1 From 39cc344acd414eda231f612325cf824b976025e5 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 22 Jan 2014 19:16:30 +0100 Subject: drm/doc: Add PRIME function references For giant hilarity the DocBook reference overview is only generated when in a level 2 section, not in a level 3 section. So we need to move this up a bit as a side-by-side section to the main PRIME documentation. Whatever. To have a complete set of references add the missing kerneldoc for all functions exported to modules with the exception of the file private init/destroy functions - drivers have no business calling those, so let's just drop the EXPORT_SYMBOL instead. Also reflow the function parameters to align correctly and break at 80 chars - my OCD couldn't stand them while writing the kerneldoc ;-) Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_prime.c | 110 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 89 insertions(+), 21 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 56805c39c906..f1437b6c8dbf 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -68,7 +68,8 @@ struct drm_prime_attachment { enum dma_data_direction dir; }; -static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle) +static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, + struct dma_buf *dma_buf, uint32_t handle) { struct drm_prime_member *member; @@ -174,7 +175,7 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr } static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, - enum dma_data_direction dir) + enum dma_data_direction dir) { struct drm_prime_attachment *prime_attach = attach->priv; struct drm_gem_object *obj = attach->dmabuf->priv; @@ -211,11 +212,19 @@ static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach, } static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach, - struct sg_table *sgt, enum dma_data_direction dir) + struct sg_table *sgt, + enum dma_data_direction dir) { /* nothing to be done here */ } +/** + * drm_gem_dmabuf_release - dma_buf release implementation for GEM + * @dma_buf: buffer to be released + * + * Generic release function for dma_bufs exported as PRIME buffers. GEM drivers + * must use this in their dma_buf ops structure as the release callback. + */ void drm_gem_dmabuf_release(struct dma_buf *dma_buf) { struct drm_gem_object *obj = dma_buf->priv; @@ -242,30 +251,30 @@ static void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr) } static void *drm_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, - unsigned long page_num) + unsigned long page_num) { return NULL; } static void drm_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, - unsigned long page_num, void *addr) + unsigned long page_num, void *addr) { } static void *drm_gem_dmabuf_kmap(struct dma_buf *dma_buf, - unsigned long page_num) + unsigned long page_num) { return NULL; } static void drm_gem_dmabuf_kunmap(struct dma_buf *dma_buf, - unsigned long page_num, void *addr) + unsigned long page_num, void *addr) { } static int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, - struct vm_area_struct *vma) + struct vm_area_struct *vma) { struct drm_gem_object *obj = dma_buf->priv; struct drm_device *dev = obj->dev; @@ -315,6 +324,15 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { * driver's scatter/gather table */ +/** + * drm_gem_prime_export - helper library implemention of the export callback + * @dev: drm_device to export from + * @obj: GEM object to export + * @flags: flags like DRM_CLOEXEC + * + * This is the implementation of the gem_prime_export functions for GEM drivers + * using the PRIME helpers. + */ struct dma_buf *drm_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) { @@ -355,9 +373,23 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, return dmabuf; } +/** + * drm_gem_prime_handle_to_fd - PRIME export function for GEM drivers + * @dev: dev to export the buffer from + * @file_priv: drm file-private structure + * @handle: buffer handle to export + * @flags: flags like DRM_CLOEXEC + * @prime_fd: pointer to storage for the fd id of the create dma-buf + * + * This is the PRIME export function which must be used mandatorily by GEM + * drivers to ensure correct lifetime management of the underlying GEM object. + * The actual exporting from GEM object to a dma-buf is done through the + * gem_prime_export driver callback. + */ int drm_gem_prime_handle_to_fd(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle, uint32_t flags, - int *prime_fd) + struct drm_file *file_priv, uint32_t handle, + uint32_t flags, + int *prime_fd) { struct drm_gem_object *obj; int ret = 0; @@ -441,6 +473,14 @@ out_unlock: } EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); +/** + * drm_gem_prime_import - helper library implemention of the import callback + * @dev: drm_device to import into + * @dma_buf: dma-buf object to import + * + * This is the implementation of the gem_prime_import functions for GEM drivers + * using the PRIME helpers. + */ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf) { @@ -496,8 +536,21 @@ fail_detach: } EXPORT_SYMBOL(drm_gem_prime_import); +/** + * drm_gem_prime_fd_to_handle - PRIME import function for GEM drivers + * @dev: dev to export the buffer from + * @file_priv: drm file-private structure + * @prime_fd: fd id of the dma-buf which should be imported + * @handle: pointer to storage for the handle of the imported buffer object + * + * This is the PRIME import function which must be used mandatorily by GEM + * drivers to ensure correct lifetime management of the underlying GEM object. + * The actual importing of GEM object from the dma-buf is done through the + * gem_import_export driver callback. + */ int drm_gem_prime_fd_to_handle(struct drm_device *dev, - struct drm_file *file_priv, int prime_fd, uint32_t *handle) + struct drm_file *file_priv, int prime_fd, + uint32_t *handle) { struct dma_buf *dma_buf; struct drm_gem_object *obj; @@ -598,12 +651,14 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, args->fd, &args->handle); } -/* - * drm_prime_pages_to_sg +/** + * drm_prime_pages_to_sg - converts a page array into an sg list + * @pages: pointer to the array of page pointers to convert + * @nr_pages: length of the page vector * - * this helper creates an sg table object from a set of pages + * This helper creates an sg table object from a set of pages * the driver is responsible for mapping the pages into the - * importers address space + * importers address space for use with dma_buf itself. */ struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) { @@ -628,9 +683,16 @@ out: } EXPORT_SYMBOL(drm_prime_pages_to_sg); -/* export an sg table into an array of pages and addresses - this is currently required by the TTM driver in order to do correct fault - handling */ +/** + * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array + * @sgt: scatter-gather table to convert + * @pages: array of page pointers to store the page array in + * @addrs: optional array to store the dma bus address of each page + * @max_pages: size of both the passed-in arrays + * + * Exports an sg table into an array of pages and addresses. This is currently + * required by the TTM driver in order to do correct fault handling. + */ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, dma_addr_t *addrs, int max_pages) { @@ -663,7 +725,15 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, return 0; } EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays); -/* helper function to cleanup a GEM/prime object */ + +/** + * drm_prime_gem_destroy - helper to clean up a PRIME-imported GEM object + * @obj: GEM object which was created from a dma-buf + * @sg: the sg-table which was pinned at import time + * + * This is the cleanup functions which GEM drivers need to call when they use + * @drm_gem_prime_import to import dma-bufs. + */ void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) { struct dma_buf_attachment *attach; @@ -683,11 +753,9 @@ void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) INIT_LIST_HEAD(&prime_fpriv->head); mutex_init(&prime_fpriv->lock); } -EXPORT_SYMBOL(drm_prime_init_file_private); void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv) { /* by now drm_gem_release should've made sure the list is empty */ WARN_ON(!list_empty(&prime_fpriv->head)); } -EXPORT_SYMBOL(drm_prime_destroy_file_private); -- cgit v1.2.1 From 79d1154478c057a7c894e34975ca4e5f16fe9803 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 22 Jan 2014 23:03:27 +0100 Subject: drm/mm: Remove MM_UNUSED_TARGET This was missed in commit c700c67bae6698fbc6bd20e2ae5dc62ddd367b3b Author: David Herrmann Date: Sat Jul 27 13:39:28 2013 +0200 drm/mm: remove unused API Cc: David Herrmann Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_mm.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index af93cc55259f..d0a8e8482fe0 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -47,8 +47,6 @@ #include #include -#define MM_UNUSED_TARGET 4 - static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, unsigned long size, unsigned alignment, -- cgit v1.2.1 From 93110be69616df7dcd9cc3611e94400287fc26fb Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 23 Jan 2014 00:31:48 +0100 Subject: drm/doc: Overview documentation for drm_mm.c kerneldoc polish will follow in the next patch. Hopefully documenting the lru scan support a bit better spurs someone to give this a shot in the ttm eviction code. At least in i915 it helped quite a lot with memory thrashing on platforms where eviction was (we've fixed that too meanwhile) fairly expensive. Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_mm.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index d0a8e8482fe0..276a7a27c166 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -47,6 +47,45 @@ #include #include +/** + * DOC: Overview + * + * drm_mm provides a simple range allocator. The drivers are free to use the + * resource allocator from the linux core if it suits them, the upside of drm_mm + * is that it's in the DRM core. Which means that it's easier to extend for + * some of the crazier special purpose needs of gpus. + * + * The main data struct is &drm_mm, allocations are tracked in &drm_mm_node. + * Drivers are free to embed either of them into their own suitable + * datastructures. drm_mm itself will not do any allocations of its own, so if + * drivers choose not to embed nodes they need to still allocate them + * themselves. + * + * The range allocator also supports reservation of preallocated blocks. This is + * useful for taking over initial mode setting configurations from the firmware, + * where an object needs to be created which exactly matches the firmware's + * scanout target. As long as the range is still free it can be inserted anytime + * after the allocator is initialized, which helps with avoiding looped + * depencies in the driver load sequence. + * + * drm_mm maintains a stack of most recently freed holes, which of all + * simplistic datastructures seems to be a fairly decent approach to clustering + * allocations and avoiding too much fragmentation. This means free space + * searches are O(num_holes). Given that all the fancy features drm_mm supports + * something better would be fairly complex and since gfx thrashing is a fairly + * steep cliff not a real concern. Removing a node again is O(1). + * + * drm_mm supports a few features: Alignment and range restrictions can be + * supplied. Further more every &drm_mm_node has a color value (which is just an + * opaqua unsigned long) which in conjunction with a driver callback can be used + * to implement sophisticated placement restrictions. The i915 DRM driver uses + * this to implement guard pages between incompatible caching domains in the + * graphics TT. + * + * Finally iteration helpers to walk all nodes and all holes are provided as are + * some basic allocator dumpers for debugging. + */ + static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm, unsigned long size, unsigned alignment, @@ -399,6 +438,34 @@ void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) } EXPORT_SYMBOL(drm_mm_replace_node); +/** + * DOC: lru scan roaster + * + * Very often GPUs need to have continuous allocations for a given object. When + * evicting objects to make space for a new one it is therefore not most + * efficient when we simply start to select all objects from the tail of an LRU + * until there's a suitable hole: Especially for big objects or nodes that + * otherwise have special allocation constraints there's a good chance we evict + * lots of (smaller) objects unecessarily. + * + * The DRM range allocator supports this use-case through the scanning + * interfaces. First a scan operation needs to be initialized with + * drm_mm_init_scan() or drm_mm_init_scan_with_range(). The the driver adds + * objects to the roaster (probably by walking an LRU list, but this can be + * freely implemented) until a suitable hole is found or there's no further + * evitable object. + * + * The the driver must walk through all objects again in exactly the reverse + * order to restore the allocator state. Note that while the allocator is used + * in the scan mode no other operation is allowed. + * + * Finally the driver evicts all objects selected in the scan. Adding and + * removing an object is O(1), and since freeing a node is also O(1) the overall + * complexity is O(scanned_objects). So like the free stack which needs to be + * walked before a scan operation even begins this is linear in the number of + * objects. It doesn't seem to hurt badly. + */ + /** * Initializa lru scanning. * -- cgit v1.2.1 From e18c04128faa2aa08547f8b73b9ecbf8fd6936af Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 23 Jan 2014 00:39:13 +0100 Subject: drm/doc: Add function reference documentation for drm_mm.c While at it do a tiny bit of interface cleanup and convert boolean return values to bool. With this patch all exported functions and inline helpers which are part of the drm_mm public interface are documented. Also drop superflous extern function modifiers since most of drm_mm.h doesn't use them - more consistent that way. Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_mm.c | 144 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 121 insertions(+), 23 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 276a7a27c166..a2d45b748f86 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -144,6 +144,20 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node, } } +/** + * drm_mm_reserve_node - insert an pre-initialized node + * @mm: drm_mm allocator to insert @node into + * @node: drm_mm_node to insert + * + * This functions inserts an already set-up drm_mm_node into the allocator, + * meaning that start, size and color must be set by the caller. This is useful + * to initialize the allocator with preallocated objects which must be set-up + * before the range allocator can be set-up, e.g. when taking over a firmware + * framebuffer. + * + * Returns: + * 0 on success, -ENOSPC if there's no hole where @node is. + */ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node) { struct drm_mm_node *hole; @@ -185,9 +199,18 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node) EXPORT_SYMBOL(drm_mm_reserve_node); /** - * Search for free space and insert a preallocated memory node. Returns - * -ENOSPC if no suitable free area is available. The preallocated memory node - * must be cleared. + * drm_mm_insert_node_generic - search for space and insert @node + * @mm: drm_mm to allocate from + * @node: preallocate node to insert + * @size: size of the allocation + * @alignment: alignment of the allocation + * @color: opaque tag value to use for this node + * @flags: flags to fine-tune the allocation + * + * The preallocated node must be cleared to 0. + * + * Returns: + * 0 on success, -ENOSPC if there's no suitable hole. */ int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node, unsigned long size, unsigned alignment, @@ -259,9 +282,20 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, } /** - * Search for free space and insert a preallocated memory node. Returns - * -ENOSPC if no suitable free area is available. This is for range - * restricted allocations. The preallocated memory node must be cleared. + * drm_mm_insert_node_in_range_generic - ranged search for space and insert @node + * @mm: drm_mm to allocate from + * @node: preallocate node to insert + * @size: size of the allocation + * @alignment: alignment of the allocation + * @color: opaque tag value to use for this node + * @start: start of the allowed range for this node + * @end: end of the allowed range for this node + * @flags: flags to fine-tune the allocation + * + * The preallocated node must be cleared to 0. + * + * Returns: + * 0 on success, -ENOSPC if there's no suitable hole. */ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node, unsigned long size, unsigned alignment, unsigned long color, @@ -284,7 +318,12 @@ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *n EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic); /** - * Remove a memory node from the allocator. + * drm_mm_remove_node - Remove a memory node from the allocator. + * @node: drm_mm_node to remove + * + * This just removes a node from its drm_mm allocator. The node does not need to + * be cleared again before it can be re-inserted into this or any other drm_mm + * allocator. It is a bug to call this function on a un-allocated node. */ void drm_mm_remove_node(struct drm_mm_node *node) { @@ -421,7 +460,13 @@ static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_ } /** - * Moves an allocation. To be used with embedded struct drm_mm_node. + * drm_mm_replace_node - move an allocation from @old to @new + * @old: drm_mm_node to remove from the allocator + * @new: drm_mm_node which should inherit @old's allocation + * + * This is useful for when drivers embed the drm_mm_node structure and hence + * can't move allocations by reassigning pointers. It's a combination of remove + * and insert with the guarantee that the allocation start will match. */ void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) { @@ -467,12 +512,18 @@ EXPORT_SYMBOL(drm_mm_replace_node); */ /** - * Initializa lru scanning. + * drm_mm_init_scan - initialize lru scanning + * @mm: drm_mm to scan + * @size: size of the allocation + * @alignment: alignment of the allocation + * @color: opaque tag value to use for the allocation * * This simply sets up the scanning routines with the parameters for the desired - * hole. + * hole. Note that there's no need to specify allocation flags, since they only + * change the place a node is allocated from within a suitable hole. * - * Warning: As long as the scan list is non-empty, no other operations than + * Warning: + * As long as the scan list is non-empty, no other operations than * adding/removing nodes to/from the scan list are allowed. */ void drm_mm_init_scan(struct drm_mm *mm, @@ -492,12 +543,20 @@ void drm_mm_init_scan(struct drm_mm *mm, EXPORT_SYMBOL(drm_mm_init_scan); /** - * Initializa lru scanning. + * drm_mm_init_scan - initialize range-restricted lru scanning + * @mm: drm_mm to scan + * @size: size of the allocation + * @alignment: alignment of the allocation + * @color: opaque tag value to use for the allocation + * @start: start of the allowed range for the allocation + * @end: end of the allowed range for the allocation * * This simply sets up the scanning routines with the parameters for the desired - * hole. This version is for range-restricted scans. + * hole. Note that there's no need to specify allocation flags, since they only + * change the place a node is allocated from within a suitable hole. * - * Warning: As long as the scan list is non-empty, no other operations than + * Warning: + * As long as the scan list is non-empty, no other operations than * adding/removing nodes to/from the scan list are allowed. */ void drm_mm_init_scan_with_range(struct drm_mm *mm, @@ -521,12 +580,16 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm, EXPORT_SYMBOL(drm_mm_init_scan_with_range); /** + * drm_mm_scan_add_block - add a node to the scan list + * @node: drm_mm_node to add + * * Add a node to the scan list that might be freed to make space for the desired * hole. * - * Returns non-zero, if a hole has been found, zero otherwise. + * Returns: + * True if a hole has been found, false otherwise. */ -int drm_mm_scan_add_block(struct drm_mm_node *node) +bool drm_mm_scan_add_block(struct drm_mm_node *node) { struct drm_mm *mm = node->mm; struct drm_mm_node *prev_node; @@ -566,15 +629,16 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) mm->scan_size, mm->scan_alignment)) { mm->scan_hit_start = hole_start; mm->scan_hit_end = hole_end; - return 1; + return true; } - return 0; + return false; } EXPORT_SYMBOL(drm_mm_scan_add_block); /** - * Remove a node from the scan list. + * drm_mm_scan_remove_block - remove a node from the scan list + * @node: drm_mm_node to remove * * Nodes _must_ be removed in the exact same order from the scan list as they * have been added, otherwise the internal state of the memory manager will be @@ -584,10 +648,11 @@ EXPORT_SYMBOL(drm_mm_scan_add_block); * immediately following drm_mm_search_free with !DRM_MM_SEARCH_BEST will then * return the just freed block (because its at the top of the free_stack list). * - * Returns one if this block should be evicted, zero otherwise. Will always - * return zero when no hole has been found. + * Returns: + * True if this block should be evicted, false otherwise. Will always + * return false when no hole has been found. */ -int drm_mm_scan_remove_block(struct drm_mm_node *node) +bool drm_mm_scan_remove_block(struct drm_mm_node *node) { struct drm_mm *mm = node->mm; struct drm_mm_node *prev_node; @@ -608,7 +673,15 @@ int drm_mm_scan_remove_block(struct drm_mm_node *node) } EXPORT_SYMBOL(drm_mm_scan_remove_block); -int drm_mm_clean(struct drm_mm * mm) +/** + * drm_mm_clean - checks whether an allocator is clean + * @mm: drm_mm allocator to check + * + * Returns: + * True if the allocator is completely free, false if there's still a node + * allocated in it. + */ +bool drm_mm_clean(struct drm_mm * mm) { struct list_head *head = &mm->head_node.node_list; @@ -616,6 +689,14 @@ int drm_mm_clean(struct drm_mm * mm) } EXPORT_SYMBOL(drm_mm_clean); +/** + * drm_mm_init - initialize a drm-mm allocator + * @mm: the drm_mm structure to initialize + * @start: start of the range managed by @mm + * @size: end of the range managed by @mm + * + * Note that @mm must be cleared to 0 before calling this function. + */ void drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) { INIT_LIST_HEAD(&mm->hole_stack); @@ -637,6 +718,13 @@ void drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) } EXPORT_SYMBOL(drm_mm_init); +/** + * drm_mm_takedown - clean up a drm_mm allocator + * @mm: drm_mm allocator to clean up + * + * Note that it is a bug to call this function on an allocator which is not + * clean. + */ void drm_mm_takedown(struct drm_mm * mm) { WARN(!list_empty(&mm->head_node.node_list), @@ -662,6 +750,11 @@ static unsigned long drm_mm_debug_hole(struct drm_mm_node *entry, return 0; } +/** + * drm_mm_debug_table - dump allocator state to dmesg + * @mm: drm_mm allocator to dump + * @prefix: prefix to use for dumping to dmesg + */ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) { struct drm_mm_node *entry; @@ -700,6 +793,11 @@ static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *en return 0; } +/** + * drm_mm_dump_table - dump allocator state to a seq_file + * @m: seq_file to dump to + * @mm: drm_mm allocator to dump + */ int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) { struct drm_mm_node *entry; -- cgit v1.2.1 From 69fa5293bf8d0ade3fd726848c7af925227e9180 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 23 Jan 2014 01:28:49 +0100 Subject: drm/kms: rip out drm_mode_connector_detach_encoder It's only used by imx, and that one gets it wrong - there's no need to deteach the encoder before removing it. And really, neither current drm modesetting code nor all the userspace we have can handle dynamic changes in the set of possible encoders for a given connector. So let's just remove this before someone starts doing something really nasty with it. As a plus, one less kerneldoc comment to write. Cc: Sascha Hauer Cc: Russell King Cc: Greg Kroah-Hartman Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 35ea15d5ffff..ea620f4cf6c7 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3506,21 +3506,6 @@ int drm_mode_connector_attach_encoder(struct drm_connector *connector, } EXPORT_SYMBOL(drm_mode_connector_attach_encoder); -void drm_mode_connector_detach_encoder(struct drm_connector *connector, - struct drm_encoder *encoder) -{ - int i; - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] == encoder->base.id) { - connector->encoder_ids[i] = 0; - if (connector->encoder == encoder) - connector->encoder = NULL; - break; - } - } -} -EXPORT_SYMBOL(drm_mode_connector_detach_encoder); - int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size) { -- cgit v1.2.1 From 3ec0db819315c765b3c7bbf7e9dee2fe1f186f47 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 23 Jan 2014 15:06:15 +0100 Subject: drm/doc: Integrate drm_modes.c kerneldoc And clean it up so that there's no kerneldoc warnings. There's still a lot to do with this one here. Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_modes.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index b0733153dfd2..4892194937f3 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -39,12 +39,11 @@ #include