Merge tag 'drm-misc-next-2017-01-09' of git://anongit.freedesktop.org/git/drm-misc into drm-next
Back to regular -misc pulls with reasonable sizes: - dma_fence error clarification (Chris) - drm_crtc_from_index helper (Shawn), pile more patches on the m-l to roll this out to drivers - mmu-less support for fbdev helpers from Benjamin - piles of kerneldoc work - some polish for crc support from Tomeu and Benjamin - odd misc stuff all over * tag 'drm-misc-next-2017-01-09' of git://anongit.freedesktop.org/git/drm-misc: (48 commits) dma-fence: Introduce drm_fence_set_error() helper dma-fence: Wrap querying the fence->status dma-fence: Clear fence->status during dma_fence_init() drm: fix compilations issues introduced by "drm: allow to use mmuless SoC" drm: Change the return type of the unload hook to void drm: add more document for drm_crtc_from_index() drm: remove useless parameters from drm_pick_cmdline_mode function drm: crc: Call wake_up_interruptible() each time there is a new CRC entry drm: allow to use mmuless SoC drm: compile drm_vm.c only when needed fbmem: add a default get_fb_unmapped_area function drm: crc: Wait for a frame before returning from open() drm: Move locking into drm_debugfs_crtc_crc_add drm/imx: imx-tve: Remove unused variable Revert "drm: nouveau: fix build when LEDS_CLASS=m" drm: Add kernel-doc for drm_crtc_commit_get/put drm/atomic: Fix outdated comment. drm: reference count event->completion gpu: drm: mgag200: mgag200_main:- Handle error from pci_iomap drm: Document deprecated load/unload hook ...
This commit is contained in:
@@ -360,6 +360,7 @@ struct drm_ioctl_desc {
|
||||
/* Event queued up for userspace to read */
|
||||
struct drm_pending_event {
|
||||
struct completion *completion;
|
||||
void (*completion_release)(struct completion *completion);
|
||||
struct drm_event *event;
|
||||
struct dma_fence *fence;
|
||||
struct list_head link;
|
||||
|
@@ -189,12 +189,31 @@ struct drm_atomic_state {
|
||||
struct work_struct commit_work;
|
||||
};
|
||||
|
||||
void drm_crtc_commit_put(struct drm_crtc_commit *commit);
|
||||
void __drm_crtc_commit_free(struct kref *kref);
|
||||
|
||||
/**
|
||||
* drm_crtc_commit_get - acquire a reference to the CRTC commit
|
||||
* @commit: CRTC commit
|
||||
*
|
||||
* Increases the reference of @commit.
|
||||
*/
|
||||
static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit)
|
||||
{
|
||||
kref_get(&commit->ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_crtc_commit_put - release a reference to the CRTC commmit
|
||||
* @commit: CRTC commit
|
||||
*
|
||||
* This releases a reference to @commit which is freed after removing the
|
||||
* final reference. No locking required and callable from any context.
|
||||
*/
|
||||
static inline void drm_crtc_commit_put(struct drm_crtc_commit *commit)
|
||||
{
|
||||
kref_put(&commit->ref, __drm_crtc_commit_free);
|
||||
}
|
||||
|
||||
struct drm_atomic_state * __must_check
|
||||
drm_atomic_state_alloc(struct drm_device *dev);
|
||||
void drm_atomic_state_clear(struct drm_atomic_state *state);
|
||||
@@ -398,7 +417,7 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
|
||||
* drm_atomic_crtc_needs_modeset - compute combined modeset need
|
||||
* @state: &drm_crtc_state for the CRTC
|
||||
*
|
||||
* To give drivers flexibility struct &drm_crtc_state has 3 booleans to track
|
||||
* To give drivers flexibility &struct drm_crtc_state has 3 booleans to track
|
||||
* whether the state CRTC changed enough to need a full modeset cycle:
|
||||
* connectors_changed, mode_changed and active_changed. This helper simply
|
||||
* combines these three to compute the overall need for a modeset for @state.
|
||||
|
@@ -48,7 +48,7 @@ struct drm_master {
|
||||
*/
|
||||
char *unique;
|
||||
/**
|
||||
* @unique_len: Length of unique field. Protected by struct &drm_device
|
||||
* @unique_len: Length of unique field. Protected by &struct drm_device
|
||||
* master_mutex.
|
||||
*/
|
||||
int unique_len;
|
||||
|
@@ -96,9 +96,10 @@ struct drm_bridge_funcs {
|
||||
* This callback should disable the bridge. It is called right before
|
||||
* the preceding element in the display pipe is disabled. If the
|
||||
* preceding element is a bridge this means it's called before that
|
||||
* bridge's ->disable() function. If the preceding element is a
|
||||
* &drm_encoder it's called right before the encoder's ->disable(),
|
||||
* ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs.
|
||||
* bridge's @disable vfunc. If the preceding element is a &drm_encoder
|
||||
* it's called right before the &drm_encoder_helper_funcs.disable,
|
||||
* &drm_encoder_helper_funcs.prepare or &drm_encoder_helper_funcs.dpms
|
||||
* hook.
|
||||
*
|
||||
* The bridge can assume that the display pipe (i.e. clocks and timing
|
||||
* signals) feeding it is still running when this callback is called.
|
||||
@@ -110,12 +111,13 @@ struct drm_bridge_funcs {
|
||||
/**
|
||||
* @post_disable:
|
||||
*
|
||||
* This callback should disable the bridge. It is called right after
|
||||
* the preceding element in the display pipe is disabled. If the
|
||||
* preceding element is a bridge this means it's called after that
|
||||
* bridge's ->post_disable() function. If the preceding element is a
|
||||
* &drm_encoder it's called right after the encoder's ->disable(),
|
||||
* ->prepare() or ->dpms() hook from struct &drm_encoder_helper_funcs.
|
||||
* This callback should disable the bridge. It is called right after the
|
||||
* preceding element in the display pipe is disabled. If the preceding
|
||||
* element is a bridge this means it's called after that bridge's
|
||||
* @post_disable function. If the preceding element is a &drm_encoder
|
||||
* it's called right after the encoder's
|
||||
* &drm_encoder_helper_funcs.disable, &drm_encoder_helper_funcs.prepare
|
||||
* or &drm_encoder_helper_funcs.dpms hook.
|
||||
*
|
||||
* The bridge must assume that the display pipe (i.e. clocks and timing
|
||||
* singals) feeding it is no longer running when this callback is
|
||||
@@ -129,9 +131,11 @@ struct drm_bridge_funcs {
|
||||
* @mode_set:
|
||||
*
|
||||
* This callback should set the given mode on the bridge. It is called
|
||||
* after the ->mode_set() callback for the preceding element in the
|
||||
* display pipeline has been called already. The display pipe (i.e.
|
||||
* clocks and timing signals) is off when this function is called.
|
||||
* after the @mode_set callback for the preceding element in the display
|
||||
* pipeline has been called already. If the bridge is the first element
|
||||
* then this would be &drm_encoder_helper_funcs.mode_set. The display
|
||||
* pipe (i.e. clocks and timing signals) is off when this function is
|
||||
* called.
|
||||
*/
|
||||
void (*mode_set)(struct drm_bridge *bridge,
|
||||
struct drm_display_mode *mode,
|
||||
@@ -142,9 +146,10 @@ struct drm_bridge_funcs {
|
||||
* This callback should enable the bridge. It is called right before
|
||||
* the preceding element in the display pipe is enabled. If the
|
||||
* preceding element is a bridge this means it's called before that
|
||||
* bridge's ->pre_enable() function. If the preceding element is a
|
||||
* &drm_encoder it's called right before the encoder's ->enable(),
|
||||
* ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs.
|
||||
* bridge's @pre_enable function. If the preceding element is a
|
||||
* &drm_encoder it's called right before the encoder's
|
||||
* &drm_encoder_helper_funcs.enable, &drm_encoder_helper_funcs.commit or
|
||||
* &drm_encoder_helper_funcs.dpms hook.
|
||||
*
|
||||
* The display pipe (i.e. clocks and timing signals) feeding this bridge
|
||||
* will not yet be running when this callback is called. The bridge must
|
||||
@@ -161,9 +166,10 @@ struct drm_bridge_funcs {
|
||||
* This callback should enable the bridge. It is called right after
|
||||
* the preceding element in the display pipe is enabled. If the
|
||||
* preceding element is a bridge this means it's called after that
|
||||
* bridge's ->enable() function. If the preceding element is a
|
||||
* &drm_encoder it's called right after the encoder's ->enable(),
|
||||
* ->commit() or ->dpms() hook from struct &drm_encoder_helper_funcs.
|
||||
* bridge's @enable function. If the preceding element is a
|
||||
* &drm_encoder it's called right after the encoder's
|
||||
* &drm_encoder_helper_funcs.enable, &drm_encoder_helper_funcs.commit or
|
||||
* &drm_encoder_helper_funcs.dpms hook.
|
||||
*
|
||||
* The bridge can assume that the display pipe (i.e. clocks and timing
|
||||
* signals) feeding it is running when this callback is called. This
|
||||
|
@@ -94,7 +94,7 @@ enum subpixel_order {
|
||||
*
|
||||
* Describes a given display (e.g. CRT or flat panel) and its limitations. For
|
||||
* fixed display sinks like built-in panels there's not much difference between
|
||||
* this and struct &drm_connector. But for sinks with a real cable this
|
||||
* this and &struct drm_connector. But for sinks with a real cable this
|
||||
* structure is meant to describe all the things at the other end of the cable.
|
||||
*
|
||||
* For sinks which provide an EDID this can be filled out by calling
|
||||
@@ -422,7 +422,7 @@ struct drm_connector_funcs {
|
||||
* &drm_mode_config_funcs) will be cleaned up by calling the
|
||||
* @atomic_destroy_state hook in this structure.
|
||||
*
|
||||
* Atomic drivers which don't subclass struct &drm_connector_state should use
|
||||
* Atomic drivers which don't subclass &struct drm_connector_state should use
|
||||
* drm_atomic_helper_connector_duplicate_state(). Drivers that subclass the
|
||||
* state structure to extend it with driver-private state should use
|
||||
* __drm_atomic_helper_connector_duplicate_state() to make sure shared state is
|
||||
@@ -525,7 +525,7 @@ struct drm_connector_funcs {
|
||||
/**
|
||||
* @atomic_print_state:
|
||||
*
|
||||
* If driver subclasses struct &drm_connector_state, it should implement
|
||||
* If driver subclasses &struct drm_connector_state, it should implement
|
||||
* this optional hook for printing additional driver specific state.
|
||||
*
|
||||
* Do not call this directly, use drm_atomic_connector_print_state()
|
||||
@@ -875,11 +875,7 @@ void drm_mode_put_tile_group(struct drm_device *dev,
|
||||
* deprecated. Use drm_for_each_connector_iter() instead.
|
||||
*/
|
||||
#define drm_for_each_connector(connector, dev) \
|
||||
for (assert_drm_connector_list_read_locked(&(dev)->mode_config), \
|
||||
connector = list_first_entry(&(dev)->mode_config.connector_list, \
|
||||
struct drm_connector, head); \
|
||||
&connector->head != (&(dev)->mode_config.connector_list); \
|
||||
connector = list_next_entry(connector, head))
|
||||
list_for_each_entry(connector, &(dev)->mode_config.connector_list, head)
|
||||
|
||||
/**
|
||||
* struct drm_connector_list_iter - connector_list iterator
|
||||
@@ -904,8 +900,8 @@ void drm_connector_list_iter_put(struct drm_connector_list_iter *iter);
|
||||
|
||||
/**
|
||||
* drm_for_each_connector_iter - connector_list iterator macro
|
||||
* @connector: struct &drm_connector pointer used as cursor
|
||||
* @iter: struct &drm_connector_list_iter
|
||||
* @connector: &struct drm_connector pointer used as cursor
|
||||
* @iter: &struct drm_connector_list_iter
|
||||
*
|
||||
* Note that @connector is only valid within the list body, if you want to use
|
||||
* @connector after calling drm_connector_list_iter_put() then you need to grab
|
||||
|
@@ -315,7 +315,7 @@ struct drm_crtc_funcs {
|
||||
*
|
||||
* This is the main legacy entry point to change the modeset state on a
|
||||
* CRTC. All the details of the desired configuration are passed in a
|
||||
* struct &drm_mode_set - see there for details.
|
||||
* &struct drm_mode_set - see there for details.
|
||||
*
|
||||
* Drivers implementing atomic modeset should use
|
||||
* drm_atomic_helper_set_config() to implement this hook.
|
||||
@@ -346,7 +346,7 @@ struct drm_crtc_funcs {
|
||||
* shared dma-buf.
|
||||
*
|
||||
* An application can request to be notified when the page flip has
|
||||
* completed. The drm core will supply a struct &drm_event in the event
|
||||
* completed. The drm core will supply a &struct drm_event in the event
|
||||
* parameter in this case. This can be handled by the
|
||||
* drm_crtc_send_vblank_event() function, which the driver should call on
|
||||
* the provided event upon completion of the flip. Note that if
|
||||
@@ -431,7 +431,7 @@ struct drm_crtc_funcs {
|
||||
* &drm_mode_config_funcs) will be cleaned up by calling the
|
||||
* @atomic_destroy_state hook in this structure.
|
||||
*
|
||||
* Atomic drivers which don't subclass struct &drm_crtc should use
|
||||
* Atomic drivers which don't subclass &struct drm_crtc should use
|
||||
* drm_atomic_helper_crtc_duplicate_state(). Drivers that subclass the
|
||||
* state structure to extend it with driver-private state should use
|
||||
* __drm_atomic_helper_crtc_duplicate_state() to make sure shared state is
|
||||
@@ -583,7 +583,7 @@ struct drm_crtc_funcs {
|
||||
/**
|
||||
* @atomic_print_state:
|
||||
*
|
||||
* If driver subclasses struct &drm_crtc_state, it should implement
|
||||
* If driver subclasses &struct drm_crtc_state, it should implement
|
||||
* this optional hook for printing additional driver specific state.
|
||||
*
|
||||
* Do not call this directly, use drm_atomic_crtc_print_state()
|
||||
@@ -822,6 +822,7 @@ int drm_crtc_force_disable(struct drm_crtc *crtc);
|
||||
int drm_crtc_force_disable_all(struct drm_device *dev);
|
||||
|
||||
int drm_mode_set_config_internal(struct drm_mode_set *set);
|
||||
struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx);
|
||||
|
||||
/* Helpers */
|
||||
static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
|
||||
@@ -835,18 +836,4 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
|
||||
#define drm_for_each_crtc(crtc, dev) \
|
||||
list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head)
|
||||
|
||||
static inline void
|
||||
assert_drm_connector_list_read_locked(struct drm_mode_config *mode_config)
|
||||
{
|
||||
/*
|
||||
* The connector hotadd/remove code currently grabs both locks when
|
||||
* updating lists. Hence readers need only hold either of them to be
|
||||
* safe and the check amounts to
|
||||
*
|
||||
* WARN_ON(not_holding(A) && not_holding(B)).
|
||||
*/
|
||||
WARN_ON(!mutex_is_locked(&mode_config->mutex) &&
|
||||
!drm_modeset_is_locked(&mode_config->connection_mutex));
|
||||
}
|
||||
|
||||
#endif /* __DRM_CRTC_H__ */
|
||||
|
@@ -64,13 +64,45 @@ struct drm_mode_create_dumb;
|
||||
* structure for GEM drivers.
|
||||
*/
|
||||
struct drm_driver {
|
||||
|
||||
/**
|
||||
* @load:
|
||||
*
|
||||
* Backward-compatible driver callback to complete
|
||||
* initialization steps after the driver is registered. For
|
||||
* this reason, may suffer from race conditions and its use is
|
||||
* deprecated for new drivers. It is therefore only supported
|
||||
* for existing drivers not yet converted to the new scheme.
|
||||
* See drm_dev_init() and drm_dev_register() for proper and
|
||||
* race-free way to set up a &struct drm_device.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Zero on success, non-zero value on failure.
|
||||
*/
|
||||
int (*load) (struct drm_device *, unsigned long flags);
|
||||
int (*firstopen) (struct drm_device *);
|
||||
int (*open) (struct drm_device *, struct drm_file *);
|
||||
void (*preclose) (struct drm_device *, struct drm_file *file_priv);
|
||||
void (*postclose) (struct drm_device *, struct drm_file *);
|
||||
void (*lastclose) (struct drm_device *);
|
||||
int (*unload) (struct drm_device *);
|
||||
|
||||
/**
|
||||
* @unload:
|
||||
*
|
||||
* Reverse the effects of the driver load callback. Ideally,
|
||||
* the clean up performed by the driver should happen in the
|
||||
* reverse order of the initialization. Similarly to the load
|
||||
* hook, this handler is deprecated and its usage should be
|
||||
* dropped in favor of an open-coded teardown function at the
|
||||
* driver layer. See drm_dev_unregister() and drm_dev_unref()
|
||||
* for the proper way to remove a &struct drm_device.
|
||||
*
|
||||
* The unload() hook is called right after unregistering
|
||||
* the device.
|
||||
*
|
||||
*/
|
||||
void (*unload) (struct drm_device *);
|
||||
int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
|
||||
int (*dma_quiescent) (struct drm_device *);
|
||||
int (*context_dtor) (struct drm_device *dev, int context);
|
||||
|
@@ -17,7 +17,7 @@ struct drm_plane_state;
|
||||
|
||||
struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev,
|
||||
unsigned int preferred_bpp, unsigned int num_crtc,
|
||||
unsigned int max_conn_count, const struct drm_fb_helper_funcs *funcs);
|
||||
unsigned int max_conn_count, const struct drm_framebuffer_funcs *funcs);
|
||||
struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,
|
||||
unsigned int preferred_bpp, unsigned int num_crtc,
|
||||
unsigned int max_conn_count);
|
||||
@@ -26,9 +26,6 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma);
|
||||
void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma);
|
||||
void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma);
|
||||
void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, int state);
|
||||
int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper,
|
||||
struct drm_fb_helper_surface_size *sizes,
|
||||
const struct drm_framebuffer_funcs *funcs);
|
||||
|
||||
void drm_fb_cma_destroy(struct drm_framebuffer *fb);
|
||||
int drm_fb_cma_create_handle(struct drm_framebuffer *fb,
|
||||
|
@@ -181,7 +181,7 @@ struct drm_fb_helper_connector {
|
||||
*
|
||||
* This is the main structure used by the fbdev helpers. Drivers supporting
|
||||
* fbdev emulation should embedded this into their overall driver structure.
|
||||
* Drivers must also fill out a struct &drm_fb_helper_funcs with a few
|
||||
* Drivers must also fill out a &struct drm_fb_helper_funcs with a few
|
||||
* operations.
|
||||
*/
|
||||
struct drm_fb_helper {
|
||||
@@ -295,8 +295,7 @@ struct drm_display_mode *
|
||||
drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
|
||||
int width, int height);
|
||||
struct drm_display_mode *
|
||||
drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
|
||||
int width, int height);
|
||||
drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn);
|
||||
|
||||
int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector);
|
||||
int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
|
||||
|
@@ -51,7 +51,7 @@ struct drm_framebuffer_funcs {
|
||||
* @create_handle:
|
||||
*
|
||||
* Create a buffer handle in the driver-specific buffer manager (either
|
||||
* GEM or TTM) valid for the passed-in struct &drm_file. This is used by
|
||||
* GEM or TTM) valid for the passed-in &struct drm_file. This is used by
|
||||
* the core to implement the GETFB IOCTL, which returns (for
|
||||
* sufficiently priviledged user) also a native buffer handle. This can
|
||||
* be used for seamless transitions between modesetting clients by
|
||||
@@ -149,7 +149,7 @@ struct drm_framebuffer {
|
||||
*
|
||||
* This should not be used to specifiy x/y pixel offsets into the buffer
|
||||
* data (even for linear buffers). Specifying an x/y pixel offset is
|
||||
* instead done through the source rectangle in struct &drm_plane_state.
|
||||
* instead done through the source rectangle in &struct drm_plane_state.
|
||||
*/
|
||||
unsigned int offsets[4];
|
||||
/**
|
||||
@@ -187,7 +187,7 @@ struct drm_framebuffer {
|
||||
*/
|
||||
int hot_y;
|
||||
/**
|
||||
* @filp_head: Placed on struct &drm_file fbs list_head, protected by
|
||||
* @filp_head: Placed on &struct drm_file fbs list_head, protected by
|
||||
* fbs_lock in the same structure.
|
||||
*/
|
||||
struct list_head filp_head;
|
||||
|
@@ -53,6 +53,23 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
|
||||
|
||||
extern const struct vm_operations_struct drm_gem_cma_vm_ops;
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
unsigned long drm_gem_cma_get_unmapped_area(struct file *filp,
|
||||
unsigned long addr,
|
||||
unsigned long len,
|
||||
unsigned long pgoff,
|
||||
unsigned long flags);
|
||||
#else
|
||||
static inline unsigned long drm_gem_cma_get_unmapped_area(struct file *filp,
|
||||
unsigned long addr,
|
||||
unsigned long len,
|
||||
unsigned long pgoff,
|
||||
unsigned long flags)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void drm_gem_cma_describe(struct drm_gem_cma_object *obj, struct seq_file *m);
|
||||
#endif
|
||||
|
@@ -51,8 +51,8 @@ struct drm_pending_vblank_event {
|
||||
*
|
||||
* Note that for historical reasons - the vblank handling code is still shared
|
||||
* with legacy/non-kms drivers - this is a free-standing structure not directly
|
||||
* connected to struct &drm_crtc. But all public interface functions are taking
|
||||
* a struct &drm_crtc to hide this implementation detail.
|
||||
* connected to &struct drm_crtc. But all public interface functions are taking
|
||||
* a &struct drm_crtc to hide this implementation detail.
|
||||
*/
|
||||
struct drm_vblank_crtc {
|
||||
/**
|
||||
|
@@ -42,12 +42,10 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#include <linux/seq_file.h>
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_DEBUG_MM
|
||||
#include <linux/stackdepot.h>
|
||||
#endif
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#ifdef CONFIG_DRM_DEBUG_MM
|
||||
#define DRM_MM_BUG_ON(expr) BUG_ON(expr)
|
||||
@@ -69,16 +67,29 @@ enum drm_mm_allocator_flags {
|
||||
#define DRM_MM_BOTTOMUP DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT
|
||||
#define DRM_MM_TOPDOWN DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP
|
||||
|
||||
/**
|
||||
* struct drm_mm_node - allocated block in the DRM allocator
|
||||
*
|
||||
* This represents an allocated block in a &drm_mm allocator. Except for
|
||||
* pre-reserved nodes inserted using drm_mm_reserve_node() the structure is
|
||||
* entirely opaque and should only be accessed through the provided funcions.
|
||||
* Since allocation of these nodes is entirely handled by the driver they can be
|
||||
* embedded.
|
||||
*/
|
||||
struct drm_mm_node {
|
||||
/** @color: Opaque driver-private tag. */
|
||||
unsigned long color;
|
||||
/** @start: Start address of the allocated block. */
|
||||
u64 start;
|
||||
/** @size: Size of the allocated block. */
|
||||
u64 size;
|
||||
/* private: */
|
||||
struct list_head node_list;
|
||||
struct list_head hole_stack;
|
||||
struct rb_node rb;
|
||||
unsigned hole_follows : 1;
|
||||
unsigned allocated : 1;
|
||||
bool scanned_block : 1;
|
||||
unsigned long color;
|
||||
u64 start;
|
||||
u64 size;
|
||||
u64 __subtree_last;
|
||||
struct drm_mm *mm;
|
||||
#ifdef CONFIG_DRM_DEBUG_MM
|
||||
@@ -86,7 +97,29 @@ struct drm_mm_node {
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_mm - DRM allocator
|
||||
*
|
||||
* DRM range allocator with a few special functions and features geared towards
|
||||
* managing GPU memory. Except for the @color_adjust callback the structure is
|
||||
* entirely opaque and should only be accessed through the provided functions
|
||||
* and macros. This structure can be embedded into larger driver structures.
|
||||
*/
|
||||
struct drm_mm {
|
||||
/**
|
||||
* @color_adjust:
|
||||
*
|
||||
* Optional driver callback to further apply restrictions on a hole. The
|
||||
* node argument points at the node containing the hole from which the
|
||||
* block would be allocated (see drm_mm_hole_follows() and friends). The
|
||||
* other arguments are the size of the block to be allocated. The driver
|
||||
* can adjust the start and end as needed to e.g. insert guard pages.
|
||||
*/
|
||||
void (*color_adjust)(const struct drm_mm_node *node,
|
||||
unsigned long color,
|
||||
u64 *start, u64 *end);
|
||||
|
||||
/* private: */
|
||||
/* List of all memory nodes that immediately precede a free hole. */
|
||||
struct list_head hole_stack;
|
||||
/* head_node.node_list is the list of all memory nodes, ordered
|
||||
@@ -95,14 +128,20 @@ struct drm_mm {
|
||||
/* Keep an interval_tree for fast lookup of drm_mm_nodes by address. */
|
||||
struct rb_root interval_tree;
|
||||
|
||||
void (*color_adjust)(const struct drm_mm_node *node,
|
||||
unsigned long color,
|
||||
u64 *start, u64 *end);
|
||||
|
||||
unsigned long scan_active;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_mm_scan - DRM allocator eviction roaster data
|
||||
*
|
||||
* This structure tracks data needed for the eviction roaster set up using
|
||||
* drm_mm_scan_init(), and used with drm_mm_scan_add_block() and
|
||||
* drm_mm_scan_remove_block(). The structure is entirely opaque and should only
|
||||
* be accessed through the provided functions and macros. It is meant to be
|
||||
* allocated temporarily by the driver on the stack.
|
||||
*/
|
||||
struct drm_mm_scan {
|
||||
/* private: */
|
||||
struct drm_mm *mm;
|
||||
|
||||
u64 size;
|
||||
@@ -161,7 +200,8 @@ static inline bool drm_mm_initialized(const struct drm_mm *mm)
|
||||
*
|
||||
* Holes are embedded into the drm_mm using the tail of a drm_mm_node.
|
||||
* If you wish to know whether a hole follows this particular node,
|
||||
* query this function.
|
||||
* query this function. See also drm_mm_hole_node_start() and
|
||||
* drm_mm_hole_node_end().
|
||||
*
|
||||
* Returns:
|
||||
* True if a hole follows the @node.
|
||||
@@ -230,23 +270,23 @@ static inline u64 drm_mm_hole_node_end(const struct drm_mm_node *hole_node)
|
||||
|
||||
/**
|
||||
* drm_mm_for_each_node - iterator to walk over all allocated nodes
|
||||
* @entry: drm_mm_node structure to assign to in each iteration step
|
||||
* @mm: drm_mm allocator to walk
|
||||
* @entry: &struct drm_mm_node to assign to in each iteration step
|
||||
* @mm: &drm_mm allocator to walk
|
||||
*
|
||||
* This iterator walks over all nodes in the range allocator. It is implemented
|
||||
* with list_for_each, so not save against removal of elements.
|
||||
* with list_for_each(), so not save against removal of elements.
|
||||
*/
|
||||
#define drm_mm_for_each_node(entry, mm) \
|
||||
list_for_each_entry(entry, drm_mm_nodes(mm), node_list)
|
||||
|
||||
/**
|
||||
* drm_mm_for_each_node_safe - iterator to walk over all allocated nodes
|
||||
* @entry: drm_mm_node structure to assign to in each iteration step
|
||||
* @next: drm_mm_node structure to store the next step
|
||||
* @mm: drm_mm allocator to walk
|
||||
* @entry: &struct drm_mm_node to assign to in each iteration step
|
||||
* @next: &struct drm_mm_node to store the next step
|
||||
* @mm: &drm_mm allocator to walk
|
||||
*
|
||||
* This iterator walks over all nodes in the range allocator. It is implemented
|
||||
* with list_for_each_safe, so save against removal of elements.
|
||||
* with list_for_each_safe(), so save against removal of elements.
|
||||
*/
|
||||
#define drm_mm_for_each_node_safe(entry, next, mm) \
|
||||
list_for_each_entry_safe(entry, next, drm_mm_nodes(mm), node_list)
|
||||
@@ -261,13 +301,13 @@ static inline u64 drm_mm_hole_node_end(const struct drm_mm_node *hole_node)
|
||||
|
||||
/**
|
||||
* drm_mm_for_each_hole - iterator to walk over all holes
|
||||
* @entry: drm_mm_node used internally to track progress
|
||||
* @mm: drm_mm allocator to walk
|
||||
* @entry: &drm_mm_node used internally to track progress
|
||||
* @mm: &drm_mm allocator to walk
|
||||
* @hole_start: ulong variable to assign the hole start to on each iteration
|
||||
* @hole_end: ulong variable to assign the hole end to on each iteration
|
||||
*
|
||||
* This iterator walks over all holes in the range allocator. It is implemented
|
||||
* with list_for_each, so not save against removal of elements. @entry is used
|
||||
* with list_for_each(), so not save against removal of elements. @entry is used
|
||||
* internally and will not reflect a real drm_mm_node for the very first hole.
|
||||
* Hence users of this iterator may not access it.
|
||||
*
|
||||
@@ -336,6 +376,9 @@ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
|
||||
* @sflags: flags to fine-tune the allocation search
|
||||
* @aflags: flags to fine-tune the allocation behavior
|
||||
*
|
||||
* This is a simplified version of drm_mm_insert_node_in_range_generic() with no
|
||||
* range restrictions applied.
|
||||
*
|
||||
* The preallocated node must be cleared to 0.
|
||||
*
|
||||
* Returns:
|
||||
@@ -436,6 +479,9 @@ void drm_mm_scan_init_with_range(struct drm_mm_scan *scan,
|
||||
* @color: opaque tag value to use for the allocation
|
||||
* @flags: flags to specify how the allocation will be performed afterwards
|
||||
*
|
||||
* This is a simplified version of drm_mm_scan_init_with_range() with no range
|
||||
* restrictions applied.
|
||||
*
|
||||
* This simply sets up the scanning routines with the parameters for the desired
|
||||
* hole.
|
||||
*
|
||||
@@ -462,9 +508,6 @@ bool drm_mm_scan_remove_block(struct drm_mm_scan *scan,
|
||||
struct drm_mm_node *node);
|
||||
struct drm_mm_node *drm_mm_scan_color_evict(struct drm_mm_scan *scan);
|
||||
|
||||
void drm_mm_debug_table(const struct drm_mm *mm, const char *prefix);
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
int drm_mm_dump_table(struct seq_file *m, const struct drm_mm *mm);
|
||||
#endif
|
||||
void drm_mm_print(const struct drm_mm *mm, struct drm_printer *p);
|
||||
|
||||
#endif
|
||||
|
@@ -47,7 +47,7 @@ struct drm_mode_config_funcs {
|
||||
*
|
||||
* Create a new framebuffer object. The core does basic checks on the
|
||||
* requested metadata, but most of that is left to the driver. See
|
||||
* struct &drm_mode_fb_cmd2 for details.
|
||||
* &struct drm_mode_fb_cmd2 for details.
|
||||
*
|
||||
* If the parameters are deemed valid and the backing storage objects in
|
||||
* the underlying memory manager all exist, then the driver allocates
|
||||
@@ -135,7 +135,7 @@ struct drm_mode_config_funcs {
|
||||
* error conditions which don't have to be checked at the
|
||||
* ->atomic_check() stage?
|
||||
*
|
||||
* See the documentation for struct &drm_atomic_state for how exactly
|
||||
* See the documentation for &struct drm_atomic_state for how exactly
|
||||
* an atomic modeset update is described.
|
||||
*
|
||||
* Drivers using the atomic helpers can implement this hook using
|
||||
@@ -171,7 +171,7 @@ struct drm_mode_config_funcs {
|
||||
* calling this function, and that nothing has been changed in the
|
||||
* interim.
|
||||
*
|
||||
* See the documentation for struct &drm_atomic_state for how exactly
|
||||
* See the documentation for &struct drm_atomic_state for how exactly
|
||||
* an atomic modeset update is described.
|
||||
*
|
||||
* Drivers using the atomic helpers can implement this hook using
|
||||
@@ -198,7 +198,7 @@ struct drm_mode_config_funcs {
|
||||
* completed. These events are per-CRTC and can be distinguished by the
|
||||
* CRTC index supplied in &drm_event to userspace.
|
||||
*
|
||||
* The drm core will supply a struct &drm_event in the event
|
||||
* The drm core will supply a &struct drm_event in the event
|
||||
* member of each CRTC's &drm_crtc_state structure. See the
|
||||
* documentation for &drm_crtc_state for more details about the precise
|
||||
* semantics of this event.
|
||||
@@ -381,7 +381,7 @@ struct drm_mode_config {
|
||||
/**
|
||||
* @connector_list: List of connector objects. Protected by
|
||||
* @connector_list_lock. Only use drm_for_each_connector_iter() and
|
||||
* struct &drm_connector_list_iter to walk this list.
|
||||
* &struct drm_connector_list_iter to walk this list.
|
||||
*/
|
||||
struct list_head connector_list;
|
||||
int num_encoder;
|
||||
|
@@ -726,7 +726,7 @@ struct drm_connector_helper_funcs {
|
||||
* fixed panel can also manually add specific modes using
|
||||
* drm_mode_probed_add(). Drivers which manually add modes should also
|
||||
* make sure that the @display_info, @width_mm and @height_mm fields of the
|
||||
* struct &drm_connector are filled in.
|
||||
* &struct drm_connector are filled in.
|
||||
*
|
||||
* Virtual drivers that just want some standard VESA mode with a given
|
||||
* resolution can call drm_add_modes_noedid(), and mark the preferred
|
||||
|
@@ -253,7 +253,7 @@ struct drm_plane_funcs {
|
||||
* &drm_mode_config_funcs) will be cleaned up by calling the
|
||||
* @atomic_destroy_state hook in this structure.
|
||||
*
|
||||
* Atomic drivers which don't subclass struct &drm_plane_state should use
|
||||
* Atomic drivers which don't subclass &struct drm_plane_state should use
|
||||
* drm_atomic_helper_plane_duplicate_state(). Drivers that subclass the
|
||||
* state structure to extend it with driver-private state should use
|
||||
* __drm_atomic_helper_plane_duplicate_state() to make sure shared state is
|
||||
@@ -381,7 +381,7 @@ struct drm_plane_funcs {
|
||||
/**
|
||||
* @atomic_print_state:
|
||||
*
|
||||
* If driver subclasses struct &drm_plane_state, it should implement
|
||||
* If driver subclasses &struct drm_plane_state, it should implement
|
||||
* this optional hook for printing additional driver specific state.
|
||||
*
|
||||
* Do not call this directly, use drm_atomic_plane_print_state()
|
||||
|
@@ -60,26 +60,27 @@
|
||||
|
||||
/**
|
||||
* struct drm_printer - drm output "stream"
|
||||
* @printfn: actual output fxn
|
||||
* @arg: output fxn specific data
|
||||
*
|
||||
* Do not use struct members directly. Use drm_printer_seq_file(),
|
||||
* drm_printer_info(), etc to initialize. And drm_printf() for output.
|
||||
*/
|
||||
struct drm_printer {
|
||||
/* private: */
|
||||
void (*printfn)(struct drm_printer *p, struct va_format *vaf);
|
||||
void *arg;
|
||||
const char *prefix;
|
||||
};
|
||||
|
||||
void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf);
|
||||
void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
|
||||
void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf);
|
||||
|
||||
void drm_printf(struct drm_printer *p, const char *f, ...);
|
||||
|
||||
|
||||
/**
|
||||
* drm_seq_file_printer - construct a &drm_printer that outputs to &seq_file
|
||||
* @f: the struct &seq_file to output to
|
||||
* @f: the &struct seq_file to output to
|
||||
*
|
||||
* RETURNS:
|
||||
* The &drm_printer object
|
||||
@@ -95,7 +96,7 @@ static inline struct drm_printer drm_seq_file_printer(struct seq_file *f)
|
||||
|
||||
/**
|
||||
* drm_info_printer - construct a &drm_printer that outputs to dev_printk()
|
||||
* @dev: the struct &device pointer
|
||||
* @dev: the &struct device pointer
|
||||
*
|
||||
* RETURNS:
|
||||
* The &drm_printer object
|
||||
@@ -109,4 +110,19 @@ static inline struct drm_printer drm_info_printer(struct device *dev)
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_debug_printer - construct a &drm_printer that outputs to pr_debug()
|
||||
* @prefix: debug output prefix
|
||||
*
|
||||
* RETURNS:
|
||||
* The &drm_printer object
|
||||
*/
|
||||
static inline struct drm_printer drm_debug_printer(const char *prefix)
|
||||
{
|
||||
struct drm_printer p = {
|
||||
.printfn = __drm_printfn_debug,
|
||||
.prefix = prefix
|
||||
};
|
||||
return p;
|
||||
}
|
||||
#endif /* DRM_PRINT_H_ */
|
||||
|
@@ -73,9 +73,9 @@ struct drm_simple_display_pipe_funcs {
|
||||
/**
|
||||
* @prepare_fb:
|
||||
*
|
||||
* Optional, called by struct &drm_plane_helper_funcs ->prepare_fb .
|
||||
* Optional, called by &struct drm_plane_helper_funcs ->prepare_fb .
|
||||
* Please read the documentation for the ->prepare_fb hook in
|
||||
* struct &drm_plane_helper_funcs for more details.
|
||||
* &struct drm_plane_helper_funcs for more details.
|
||||
*/
|
||||
int (*prepare_fb)(struct drm_simple_display_pipe *pipe,
|
||||
struct drm_plane_state *plane_state);
|
||||
@@ -83,9 +83,9 @@ struct drm_simple_display_pipe_funcs {
|
||||
/**
|
||||
* @cleanup_fb:
|
||||
*
|
||||
* Optional, called by struct &drm_plane_helper_funcs ->cleanup_fb .
|
||||
* Optional, called by &struct drm_plane_helper_funcs ->cleanup_fb .
|
||||
* Please read the documentation for the ->cleanup_fb hook in
|
||||
* struct &drm_plane_helper_funcs for more details.
|
||||
* &struct drm_plane_helper_funcs for more details.
|
||||
*/
|
||||
void (*cleanup_fb)(struct drm_simple_display_pipe *pipe,
|
||||
struct drm_plane_state *plane_state);
|
||||
|
@@ -66,8 +66,8 @@ struct dma_buf_ops {
|
||||
* is not the case, and the allocation cannot be moved, it should also
|
||||
* fail the attach operation.
|
||||
*
|
||||
* Any exporter-private housekeeping data can be stored in the priv
|
||||
* pointer of &dma_buf_attachment structure.
|
||||
* Any exporter-private housekeeping data can be stored in the
|
||||
* &dma_buf_attachment.priv pointer.
|
||||
*
|
||||
* This callback is optional.
|
||||
*
|
||||
@@ -106,7 +106,7 @@ struct dma_buf_ops {
|
||||
*
|
||||
* Note that any specific buffer attributes required for this function
|
||||
* should get added to device_dma_parameters accessible via
|
||||
* device->dma_params from the &dma_buf_attachment. The @attach callback
|
||||
* &device.dma_params from the &dma_buf_attachment. The @attach callback
|
||||
* should also check these constraints.
|
||||
*
|
||||
* If this is being called for the first time, the exporter can now
|
||||
@@ -278,7 +278,7 @@ struct dma_buf_ops {
|
||||
* Shared dma buffers are reference counted using dma_buf_put() and
|
||||
* get_dma_buf().
|
||||
*
|
||||
* Device DMA access is handled by the separate struct &dma_buf_attachment.
|
||||
* Device DMA access is handled by the separate &struct dma_buf_attachment.
|
||||
*/
|
||||
struct dma_buf {
|
||||
size_t size;
|
||||
@@ -355,7 +355,7 @@ struct dma_buf_export_info {
|
||||
* DEFINE_DMA_BUF_EXPORT_INFO - helper macro for exporters
|
||||
* @name: export-info name
|
||||
*
|
||||
* DEFINE_DMA_BUF_EXPORT_INFO macro defines the struct &dma_buf_export_info,
|
||||
* DEFINE_DMA_BUF_EXPORT_INFO macro defines the &struct dma_buf_export_info,
|
||||
* zeroes it out and pre-populates exp_name in it.
|
||||
*/
|
||||
#define DEFINE_DMA_BUF_EXPORT_INFO(name) \
|
||||
|
@@ -47,7 +47,7 @@ struct dma_fence_cb;
|
||||
* can be compared to decide which fence would be signaled later.
|
||||
* @flags: A mask of DMA_FENCE_FLAG_* defined below
|
||||
* @timestamp: Timestamp when the fence was signaled.
|
||||
* @status: Optional, only valid if < 0, must be set before calling
|
||||
* @error: Optional, only valid if < 0, must be set before calling
|
||||
* dma_fence_signal, indicates that the fence has completed with an error.
|
||||
*
|
||||
* the flags member must be manipulated and read using the appropriate
|
||||
@@ -79,7 +79,7 @@ struct dma_fence {
|
||||
unsigned seqno;
|
||||
unsigned long flags;
|
||||
ktime_t timestamp;
|
||||
int status;
|
||||
int error;
|
||||
};
|
||||
|
||||
enum dma_fence_flag_bits {
|
||||
@@ -133,7 +133,7 @@ struct dma_fence_cb {
|
||||
* or some failure occurred that made it impossible to enable
|
||||
* signaling. True indicates successful enabling.
|
||||
*
|
||||
* fence->status may be set in enable_signaling, but only when false is
|
||||
* fence->error may be set in enable_signaling, but only when false is
|
||||
* returned.
|
||||
*
|
||||
* Calling dma_fence_signal before enable_signaling is called allows
|
||||
@@ -145,7 +145,7 @@ struct dma_fence_cb {
|
||||
* the second time will be a noop since it was already signaled.
|
||||
*
|
||||
* Notes on signaled:
|
||||
* May set fence->status if returning true.
|
||||
* May set fence->error if returning true.
|
||||
*
|
||||
* Notes on wait:
|
||||
* Must not be NULL, set to dma_fence_default_wait for default implementation.
|
||||
@@ -378,6 +378,50 @@ static inline struct dma_fence *dma_fence_later(struct dma_fence *f1,
|
||||
return dma_fence_is_signaled(f2) ? NULL : f2;
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_fence_get_status_locked - returns the status upon completion
|
||||
* @fence: [in] the dma_fence to query
|
||||
*
|
||||
* Drivers can supply an optional error status condition before they signal
|
||||
* the fence (to indicate whether the fence was completed due to an error
|
||||
* rather than success). The value of the status condition is only valid
|
||||
* if the fence has been signaled, dma_fence_get_status_locked() first checks
|
||||
* the signal state before reporting the error status.
|
||||
*
|
||||
* Returns 0 if the fence has not yet been signaled, 1 if the fence has
|
||||
* been signaled without an error condition, or a negative error code
|
||||
* if the fence has been completed in err.
|
||||
*/
|
||||
static inline int dma_fence_get_status_locked(struct dma_fence *fence)
|
||||
{
|
||||
if (dma_fence_is_signaled_locked(fence))
|
||||
return fence->error ?: 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dma_fence_get_status(struct dma_fence *fence);
|
||||
|
||||
/**
|
||||
* dma_fence_set_error - flag an error condition on the fence
|
||||
* @fence: [in] the dma_fence
|
||||
* @error: [in] the error to store
|
||||
*
|
||||
* Drivers can supply an optional error status condition before they signal
|
||||
* the fence, to indicate that the fence was completed due to an error
|
||||
* rather than success. This must be set before signaling (so that the value
|
||||
* is visible before any waiters on the signal callback are woken). This
|
||||
* helper exists to help catching erroneous setting of #dma_fence.error.
|
||||
*/
|
||||
static inline void dma_fence_set_error(struct dma_fence *fence,
|
||||
int error)
|
||||
{
|
||||
BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags));
|
||||
BUG_ON(error >= 0 || error < -MAX_ERRNO);
|
||||
|
||||
fence->error = error;
|
||||
}
|
||||
|
||||
signed long dma_fence_wait_timeout(struct dma_fence *,
|
||||
bool intr, signed long timeout);
|
||||
signed long dma_fence_wait_any_timeout(struct dma_fence **fences,
|
||||
|
Reference in New Issue
Block a user