drm-misc-next for 4.16:
Core Changes: - mostly doc updates and some fbdev improvements -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJaO+bMAAoJEEN0HIUfOBk0gVQQAIVnRSqyDRfP/1Erzp8vPtmr KKDL4hZsROHY2yzgqOPBbGZDUMUv2RcEl6H/p07VsW8c8Cqu/SgOlx9xlnRz+dEx Zjv7G6MjX1hG8dq0Qy2bKYfFJP2/+fx+Kz/lYMVpWvy2trxUJ8uB71cSl/wUWrkH iUqhAg/Jq80RADQTNG2j7oVYiRGGlcIGh8zmdIwfQyXRJJK+AHR7KU7g7PFut85u Z5fdGSn4Qs6LkKe7VzHrmlp0mpuPWy1bayoLjVGpjmrVYvieXwo/cOHVjCqL1fwU H5p4B2LYeBN27ejRyEFXTMCZJr2rbT0OGrlJ9/oghZwM6Of4BF8ZxO9v0yC0czlg +GHJsOZO7Y8enUSnGT4OyslGr49VuzYqtleK2QDAV43IImYzfNB7h6xx6qgWKynv VEl9zNJ99+WtOe5pZAUrPuumsOSKVbEU2wxmnODNLk1/XInhQ/oCHpFeCU93bqRD YR034QyMMev8e3fJe9xUWdfcTdmCFUGhs5wZn0Cu0ywbjTFnGC2WgTT2j3ln0NOQ xKUQO16oXkx0R4rJIIH8Z0olwcwfV4SBlWyD9sWAaAtxiWkm3mwj1Fs14zyHOg0C uJtCii0Nv4Lissljwk4uYSGNiHzQmu80INUxAhj+x3yR9RDABAm/9AOtK1LBGeL/ 7JRCXlKhZbqZeLZ8zBFt =AxYV -----END PGP SIGNATURE----- Merge tag 'drm-misc-next-2017-12-21' of git://anongit.freedesktop.org/drm/drm-misc into drm-next drm-misc-next for 4.16: Core Changes: - mostly doc updates and some fbdev improvements * tag 'drm-misc-next-2017-12-21' of git://anongit.freedesktop.org/drm/drm-misc: drm/framebuffer: Print task that allocated the fb in debug info. drm/fb-helper: Add drm_fb_helper_defio_init() drm/fb-helper: Update DOC with new helpers drm/docs: Add todo entry for drm_fb_helper_fbdev_setup() drm/fb-helper: Add drm_fb_helper_fbdev_setup/teardown() drm/fb-helper: Set/clear dev->fb_helper in dummy init/fini drm/stm: ltdc: Remove unnecessary platform_get_resource() error check drm/stm: dsi: Remove unnecessary platform_get_resource() error check drm/doc: Move legacy kms helpers to the very end drm/atomic: document how to handle driver private objects drm/syncobj: some kerneldoc polish drm/print: Unconfuse kerneldoc drm/edid: kerneldoc for is_hdmi2_sink
This commit is contained in:
commit
d50ce2ce51
@ -74,15 +74,6 @@ Helper Functions Reference
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_atomic_helper.c
|
||||
:export:
|
||||
|
||||
Legacy CRTC/Modeset Helper Functions Reference
|
||||
==============================================
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c
|
||||
:export:
|
||||
|
||||
Simple KMS Helper Reference
|
||||
===========================
|
||||
|
||||
@ -282,15 +273,6 @@ Flip-work Helper Reference
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_flip_work.c
|
||||
:export:
|
||||
|
||||
Plane Helper Reference
|
||||
======================
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c
|
||||
:export:
|
||||
|
||||
Auxiliary Modeset Helpers
|
||||
=========================
|
||||
|
||||
@ -308,3 +290,21 @@ Framebuffer GEM Helper Reference
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c
|
||||
:export:
|
||||
|
||||
Legacy Plane Helper Reference
|
||||
=============================
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_plane_helper.c
|
||||
:export:
|
||||
|
||||
Legacy CRTC/Modeset Helper Functions Reference
|
||||
==============================================
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_crtc_helper.c
|
||||
:export:
|
||||
|
@ -263,14 +263,20 @@ Taken all together there's two consequences for the atomic design:
|
||||
|
||||
- An atomic update is assembled and validated as an entirely free-standing pile
|
||||
of structures within the :c:type:`drm_atomic_state <drm_atomic_state>`
|
||||
container. Again drivers can subclass that container for their own state
|
||||
structure tracking needs. Only when a state is committed is it applied to the
|
||||
driver and modeset objects. This way rolling back an update boils down to
|
||||
releasing memory and unreferencing objects like framebuffers.
|
||||
container. Driver private state structures are also tracked in the same
|
||||
structure; see the next chapter. Only when a state is committed is it applied
|
||||
to the driver and modeset objects. This way rolling back an update boils down
|
||||
to releasing memory and unreferencing objects like framebuffers.
|
||||
|
||||
Read on in this chapter, and also in :ref:`drm_atomic_helper` for more detailed
|
||||
coverage of specific topics.
|
||||
|
||||
Handling Driver Private State
|
||||
-----------------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_atomic.c
|
||||
:doc: handling driver private state
|
||||
|
||||
Atomic Mode Setting Function Reference
|
||||
--------------------------------------
|
||||
|
||||
|
@ -194,6 +194,24 @@ drm_mode_config_helper_suspend/resume().
|
||||
|
||||
Contact: Maintainer of the driver you plan to convert
|
||||
|
||||
Convert drivers to use drm_fb_helper_fbdev_setup/teardown()
|
||||
-----------------------------------------------------------
|
||||
|
||||
Most drivers can use drm_fb_helper_fbdev_setup() except maybe:
|
||||
|
||||
- amdgpu which has special logic to decide whether to call
|
||||
drm_helper_disable_unused_functions()
|
||||
|
||||
- armada which isn't atomic and doesn't call
|
||||
drm_helper_disable_unused_functions()
|
||||
|
||||
- i915 which calls drm_fb_helper_initial_config() in a worker
|
||||
|
||||
Drivers that use drm_framebuffer_remove() to clean up the fbdev framebuffer can
|
||||
probably use drm_fb_helper_fbdev_teardown().
|
||||
|
||||
Contact: Maintainer of the driver you plan to convert
|
||||
|
||||
Core refactorings
|
||||
=================
|
||||
|
||||
|
@ -50,7 +50,8 @@ EXPORT_SYMBOL(__drm_crtc_commit_free);
|
||||
* @state: atomic state
|
||||
*
|
||||
* Free all the memory allocated by drm_atomic_state_init.
|
||||
* This is useful for drivers that subclass the atomic state.
|
||||
* This should only be used by drivers which are still subclassing
|
||||
* &drm_atomic_state and haven't switched to &drm_private_state yet.
|
||||
*/
|
||||
void drm_atomic_state_default_release(struct drm_atomic_state *state)
|
||||
{
|
||||
@ -67,7 +68,8 @@ EXPORT_SYMBOL(drm_atomic_state_default_release);
|
||||
* @state: atomic state
|
||||
*
|
||||
* Default implementation for filling in a new atomic state.
|
||||
* This is useful for drivers that subclass the atomic state.
|
||||
* This should only be used by drivers which are still subclassing
|
||||
* &drm_atomic_state and haven't switched to &drm_private_state yet.
|
||||
*/
|
||||
int
|
||||
drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
|
||||
@ -132,7 +134,8 @@ EXPORT_SYMBOL(drm_atomic_state_alloc);
|
||||
* @state: atomic state
|
||||
*
|
||||
* Default implementation for clearing atomic state.
|
||||
* This is useful for drivers that subclass the atomic state.
|
||||
* This should only be used by drivers which are still subclassing
|
||||
* &drm_atomic_state and haven't switched to &drm_private_state yet.
|
||||
*/
|
||||
void drm_atomic_state_default_clear(struct drm_atomic_state *state)
|
||||
{
|
||||
@ -946,6 +949,42 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
|
||||
plane->funcs->atomic_print_state(p, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* DOC: handling driver private state
|
||||
*
|
||||
* Very often the DRM objects exposed to userspace in the atomic modeset api
|
||||
* (&drm_connector, &drm_crtc and &drm_plane) do not map neatly to the
|
||||
* underlying hardware. Especially for any kind of shared resources (e.g. shared
|
||||
* clocks, scaler units, bandwidth and fifo limits shared among a group of
|
||||
* planes or CRTCs, and so on) it makes sense to model these as independent
|
||||
* objects. Drivers then need to do similar state tracking and commit ordering for
|
||||
* such private (since not exposed to userpace) objects as the atomic core and
|
||||
* helpers already provide for connectors, planes and CRTCs.
|
||||
*
|
||||
* To make this easier on drivers the atomic core provides some support to track
|
||||
* driver private state objects using struct &drm_private_obj, with the
|
||||
* associated state struct &drm_private_state.
|
||||
*
|
||||
* Similar to userspace-exposed objects, private state structures can be
|
||||
* acquired by calling drm_atomic_get_private_obj_state(). Since this function
|
||||
* does not take care of locking, drivers should wrap it for each type of
|
||||
* private state object they have with the required call to drm_modeset_lock()
|
||||
* for the corresponding &drm_modeset_lock.
|
||||
*
|
||||
* All private state structures contained in a &drm_atomic_state update can be
|
||||
* iterated using for_each_oldnew_private_obj_in_state(),
|
||||
* for_each_new_private_obj_in_state() and for_each_old_private_obj_in_state().
|
||||
* Drivers are recommended to wrap these for each type of driver private state
|
||||
* object they have, filtering on &drm_private_obj.funcs using for_each_if(), at
|
||||
* least if they want to iterate over all objects of a given type.
|
||||
*
|
||||
* An earlier way to handle driver private state was by subclassing struct
|
||||
* &drm_atomic_state. But since that encourages non-standard ways to implement
|
||||
* the check/commit split atomic requires (by using e.g. "check and rollback or
|
||||
* commit instead" of "duplicate state, check, then either commit or release
|
||||
* duplicated state) it is deprecated in favour of using &drm_private_state.
|
||||
*/
|
||||
|
||||
/**
|
||||
* drm_atomic_private_obj_init - initialize private object
|
||||
* @obj: private object
|
||||
|
@ -4871,6 +4871,11 @@ EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
|
||||
* @mode: DRM display mode
|
||||
* @rgb_quant_range: RGB quantization range (Q)
|
||||
* @rgb_quant_range_selectable: Sink support selectable RGB quantization range (QS)
|
||||
* @is_hdmi2_sink: HDMI 2.0 sink, which has different default recommendations
|
||||
*
|
||||
* Note that @is_hdmi2_sink can be derived by looking at the
|
||||
* &drm_scdc.supported flag stored in &drm_hdmi_info.scdc,
|
||||
* &drm_display_info.hdmi, which can be found in &drm_connector.display_info.
|
||||
*/
|
||||
void
|
||||
drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
|
||||
|
@ -66,19 +66,23 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
|
||||
* helper functions used by many drivers to implement the kernel mode setting
|
||||
* interfaces.
|
||||
*
|
||||
* Initialization is done as a four-step process with drm_fb_helper_prepare(),
|
||||
* drm_fb_helper_init(), drm_fb_helper_single_add_all_connectors() and
|
||||
* drm_fb_helper_initial_config(). Drivers with fancier requirements than the
|
||||
* default behaviour can override the third step with their own code.
|
||||
* Teardown is done with drm_fb_helper_fini() after the fbdev device is
|
||||
* unregisters using drm_fb_helper_unregister_fbi().
|
||||
* Setup fbdev emulation by calling drm_fb_helper_fbdev_setup() and tear it
|
||||
* down by calling drm_fb_helper_fbdev_teardown().
|
||||
*
|
||||
* At runtime drivers should restore the fbdev console by calling
|
||||
* drm_fb_helper_restore_fbdev_mode_unlocked() from their &drm_driver.lastclose
|
||||
* callback. They should also notify the fb helper code from updates to the
|
||||
* output configuration by calling drm_fb_helper_hotplug_event(). For easier
|
||||
* integration with the output polling code in drm_crtc_helper.c the modeset
|
||||
* code provides a &drm_mode_config_funcs.output_poll_changed callback.
|
||||
* Drivers that need to handle connector hotplugging (e.g. dp mst) can't use
|
||||
* the setup helper and will need to do the whole four-step setup process with
|
||||
* drm_fb_helper_prepare(), drm_fb_helper_init(),
|
||||
* drm_fb_helper_single_add_all_connectors(), enable hotplugging and
|
||||
* drm_fb_helper_initial_config() to avoid a possible race window.
|
||||
*
|
||||
* At runtime drivers should restore the fbdev console by using
|
||||
* drm_fb_helper_lastclose() as their &drm_driver.lastclose callback.
|
||||
* They should also notify the fb helper code from updates to the output
|
||||
* configuration by using drm_fb_helper_output_poll_changed() as their
|
||||
* &drm_mode_config_funcs.output_poll_changed callback.
|
||||
*
|
||||
* For suspend/resume consider using drm_mode_config_helper_suspend() and
|
||||
* drm_mode_config_helper_resume() which takes care of fbdev as well.
|
||||
*
|
||||
* All other functions exported by the fb helper library can be used to
|
||||
* implement the fbdev driver interface by the driver.
|
||||
@ -103,7 +107,8 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
|
||||
* always run in process context since the fb_*() function could be running in
|
||||
* atomic context. If drm_fb_helper_deferred_io() is used as the deferred_io
|
||||
* callback it will also schedule dirty_work with the damage collected from the
|
||||
* mmap page writes.
|
||||
* mmap page writes. Drivers can use drm_fb_helper_defio_init() to setup
|
||||
* deferred I/O (coupled with drm_fb_helper_fbdev_teardown()).
|
||||
*/
|
||||
|
||||
#define drm_fb_helper_for_each_connector(fbh, i__) \
|
||||
@ -1024,6 +1029,49 @@ void drm_fb_helper_deferred_io(struct fb_info *info,
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_deferred_io);
|
||||
|
||||
/**
|
||||
* drm_fb_helper_defio_init - fbdev deferred I/O initialization
|
||||
* @fb_helper: driver-allocated fbdev helper
|
||||
*
|
||||
* This function allocates &fb_deferred_io, sets callback to
|
||||
* drm_fb_helper_deferred_io(), delay to 50ms and calls fb_deferred_io_init().
|
||||
* It should be called from the &drm_fb_helper_funcs->fb_probe callback.
|
||||
* drm_fb_helper_fbdev_teardown() cleans up deferred I/O.
|
||||
*
|
||||
* NOTE: A copy of &fb_ops is made and assigned to &info->fbops. This is done
|
||||
* because fb_deferred_io_cleanup() clears &fbops->fb_mmap and would thereby
|
||||
* affect other instances of that &fb_ops.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper)
|
||||
{
|
||||
struct fb_info *info = fb_helper->fbdev;
|
||||
struct fb_deferred_io *fbdefio;
|
||||
struct fb_ops *fbops;
|
||||
|
||||
fbdefio = kzalloc(sizeof(*fbdefio), GFP_KERNEL);
|
||||
fbops = kzalloc(sizeof(*fbops), GFP_KERNEL);
|
||||
if (!fbdefio || !fbops) {
|
||||
kfree(fbdefio);
|
||||
kfree(fbops);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
info->fbdefio = fbdefio;
|
||||
fbdefio->delay = msecs_to_jiffies(50);
|
||||
fbdefio->deferred_io = drm_fb_helper_deferred_io;
|
||||
|
||||
*fbops = *info->fbops;
|
||||
info->fbops = fbops;
|
||||
|
||||
fb_deferred_io_init(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_defio_init);
|
||||
|
||||
/**
|
||||
* drm_fb_helper_sys_read - wrapper around fb_sys_read
|
||||
* @info: fb_info struct pointer
|
||||
@ -1848,6 +1896,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
strcpy(fb_helper->fb->comm, "[fbcon]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2729,6 +2778,120 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_hotplug_event);
|
||||
|
||||
/**
|
||||
* drm_fb_helper_fbdev_setup() - Setup fbdev emulation
|
||||
* @dev: DRM device
|
||||
* @fb_helper: fbdev helper structure to set up
|
||||
* @funcs: fbdev helper functions
|
||||
* @preferred_bpp: Preferred bits per pixel for the device.
|
||||
* @dev->mode_config.preferred_depth is used if this is zero.
|
||||
* @max_conn_count: Maximum number of connectors.
|
||||
* @dev->mode_config.num_connector is used if this is zero.
|
||||
*
|
||||
* This function sets up fbdev emulation and registers fbdev for access by
|
||||
* userspace. If all connectors are disconnected, setup is deferred to the next
|
||||
* time drm_fb_helper_hotplug_event() is called.
|
||||
* The caller must to provide a &drm_fb_helper_funcs->fb_probe callback
|
||||
* function.
|
||||
*
|
||||
* See also: drm_fb_helper_initial_config()
|
||||
*
|
||||
* Returns:
|
||||
* Zero on success or negative error code on failure.
|
||||
*/
|
||||
int drm_fb_helper_fbdev_setup(struct drm_device *dev,
|
||||
struct drm_fb_helper *fb_helper,
|
||||
const struct drm_fb_helper_funcs *funcs,
|
||||
unsigned int preferred_bpp,
|
||||
unsigned int max_conn_count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!preferred_bpp)
|
||||
preferred_bpp = dev->mode_config.preferred_depth;
|
||||
if (!preferred_bpp)
|
||||
preferred_bpp = 32;
|
||||
|
||||
if (!max_conn_count)
|
||||
max_conn_count = dev->mode_config.num_connector;
|
||||
if (!max_conn_count) {
|
||||
DRM_DEV_ERROR(dev->dev, "No connectors\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
drm_fb_helper_prepare(dev, fb_helper, funcs);
|
||||
|
||||
ret = drm_fb_helper_init(dev, fb_helper, max_conn_count);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(dev->dev, "Failed to initialize fbdev helper\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drm_fb_helper_single_add_all_connectors(fb_helper);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(dev->dev, "Failed to add connectors\n");
|
||||
goto err_drm_fb_helper_fini;
|
||||
}
|
||||
|
||||
if (!drm_drv_uses_atomic_modeset(dev))
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
ret = drm_fb_helper_initial_config(fb_helper, preferred_bpp);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(dev->dev, "Failed to set fbdev configuration\n");
|
||||
goto err_drm_fb_helper_fini;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_drm_fb_helper_fini:
|
||||
drm_fb_helper_fini(fb_helper);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_fbdev_setup);
|
||||
|
||||
/**
|
||||
* drm_fb_helper_fbdev_teardown - Tear down fbdev emulation
|
||||
* @dev: DRM device
|
||||
*
|
||||
* This function unregisters fbdev if not already done and cleans up the
|
||||
* associated resources including the &drm_framebuffer.
|
||||
* The driver is responsible for freeing the &drm_fb_helper structure which is
|
||||
* stored in &drm_device->fb_helper. Do note that this pointer has been cleared
|
||||
* when this function returns.
|
||||
*
|
||||
* In order to support device removal/unplug while file handles are still open,
|
||||
* drm_fb_helper_unregister_fbi() should be called on device removal and
|
||||
* drm_fb_helper_fbdev_teardown() in the &drm_driver->release callback when
|
||||
* file handles are closed.
|
||||
*/
|
||||
void drm_fb_helper_fbdev_teardown(struct drm_device *dev)
|
||||
{
|
||||
struct drm_fb_helper *fb_helper = dev->fb_helper;
|
||||
struct fb_ops *fbops = NULL;
|
||||
|
||||
if (!fb_helper)
|
||||
return;
|
||||
|
||||
/* Unregister if it hasn't been done already */
|
||||
if (fb_helper->fbdev && fb_helper->fbdev->dev)
|
||||
drm_fb_helper_unregister_fbi(fb_helper);
|
||||
|
||||
if (fb_helper->fbdev && fb_helper->fbdev->fbdefio) {
|
||||
fb_deferred_io_cleanup(fb_helper->fbdev);
|
||||
kfree(fb_helper->fbdev->fbdefio);
|
||||
fbops = fb_helper->fbdev->fbops;
|
||||
}
|
||||
|
||||
drm_fb_helper_fini(fb_helper);
|
||||
kfree(fbops);
|
||||
|
||||
if (fb_helper->fb)
|
||||
drm_framebuffer_remove(fb_helper->fb);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_fbdev_teardown);
|
||||
|
||||
/**
|
||||
* drm_fb_helper_lastclose - DRM driver lastclose helper for fbdev emulation
|
||||
* @dev: DRM device
|
||||
|
@ -664,6 +664,7 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
|
||||
INIT_LIST_HEAD(&fb->filp_head);
|
||||
|
||||
fb->funcs = funcs;
|
||||
strcpy(fb->comm, current->comm);
|
||||
|
||||
ret = __drm_mode_object_add(dev, &fb->base, DRM_MODE_OBJECT_FB,
|
||||
false, drm_framebuffer_free);
|
||||
@ -978,6 +979,7 @@ void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
|
||||
struct drm_format_name_buf format_name;
|
||||
unsigned int i;
|
||||
|
||||
drm_printf_indent(p, indent, "allocated by = %s\n", fb->comm);
|
||||
drm_printf_indent(p, indent, "refcount=%u\n",
|
||||
drm_framebuffer_read_refcount(fb));
|
||||
drm_printf_indent(p, indent, "format=%s\n",
|
||||
|
@ -29,9 +29,9 @@
|
||||
/**
|
||||
* DOC: Overview
|
||||
*
|
||||
* DRM synchronisation objects (syncobj) are a persistent objects,
|
||||
* that contain an optional fence. The fence can be updated with a new
|
||||
* fence, or be NULL.
|
||||
* DRM synchronisation objects (syncobj, see struct &drm_syncobj) are
|
||||
* persistent objects that contain an optional fence. The fence can be updated
|
||||
* with a new fence, or be NULL.
|
||||
*
|
||||
* syncobj's can be waited upon, where it will wait for the underlying
|
||||
* fence.
|
||||
@ -61,7 +61,8 @@
|
||||
* @file_private: drm file private pointer
|
||||
* @handle: sync object handle to lookup.
|
||||
*
|
||||
* Returns a reference to the syncobj pointed to by handle or NULL.
|
||||
* Returns a reference to the syncobj pointed to by handle or NULL. The
|
||||
* reference must be released by calling drm_syncobj_put().
|
||||
*/
|
||||
struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
|
||||
u32 handle)
|
||||
@ -229,6 +230,19 @@ static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_syncobj_find_fence - lookup and reference the fence in a sync object
|
||||
* @file_private: drm file private pointer
|
||||
* @handle: sync object handle to lookup.
|
||||
* @fence: out parameter for the fence
|
||||
*
|
||||
* This is just a convenience function that combines drm_syncobj_find() and
|
||||
* drm_syncobj_fence_get().
|
||||
*
|
||||
* Returns 0 on success or a negative error value on failure. On success @fence
|
||||
* contains a reference to the fence, which must be released by calling
|
||||
* dma_fence_put().
|
||||
*/
|
||||
int drm_syncobj_find_fence(struct drm_file *file_private,
|
||||
u32 handle,
|
||||
struct dma_fence **fence)
|
||||
@ -269,6 +283,12 @@ EXPORT_SYMBOL(drm_syncobj_free);
|
||||
* @out_syncobj: returned syncobj
|
||||
* @flags: DRM_SYNCOBJ_* flags
|
||||
* @fence: if non-NULL, the syncobj will represent this fence
|
||||
*
|
||||
* This is the first function to create a sync object. After creating, drivers
|
||||
* probably want to make it available to userspace, either through
|
||||
* drm_syncobj_get_handle() or drm_syncobj_get_fd().
|
||||
*
|
||||
* Returns 0 on success or a negative error value on failure.
|
||||
*/
|
||||
int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags,
|
||||
struct dma_fence *fence)
|
||||
@ -302,6 +322,14 @@ EXPORT_SYMBOL(drm_syncobj_create);
|
||||
|
||||
/**
|
||||
* drm_syncobj_get_handle - get a handle from a syncobj
|
||||
* @file_private: drm file private pointer
|
||||
* @syncobj: Sync object to export
|
||||
* @handle: out parameter with the new handle
|
||||
*
|
||||
* Exports a sync object created with drm_syncobj_create() as a handle on
|
||||
* @file_private to userspace.
|
||||
*
|
||||
* Returns 0 on success or a negative error value on failure.
|
||||
*/
|
||||
int drm_syncobj_get_handle(struct drm_file *file_private,
|
||||
struct drm_syncobj *syncobj, u32 *handle)
|
||||
@ -388,6 +416,15 @@ static int drm_syncobj_alloc_file(struct drm_syncobj *syncobj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_syncobj_get_fd - get a file descriptor from a syncobj
|
||||
* @syncobj: Sync object to export
|
||||
* @p_fd: out parameter with the new file descriptor
|
||||
*
|
||||
* Exports a sync object created with drm_syncobj_create() as a file descriptor.
|
||||
*
|
||||
* Returns 0 on success or a negative error value on failure.
|
||||
*/
|
||||
int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd)
|
||||
{
|
||||
int ret;
|
||||
|
@ -290,11 +290,6 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DRM_ERROR("Unable to get resource\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dsi->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(dsi->base)) {
|
||||
DRM_ERROR("Unable to get dsi registers\n");
|
||||
|
@ -901,12 +901,6 @@ int ltdc_load(struct drm_device *ddev)
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DRM_ERROR("Unable to get resource\n");
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ldev->regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(ldev->regs)) {
|
||||
DRM_ERROR("Unable to get ltdc registers\n");
|
||||
|
@ -189,12 +189,40 @@ struct drm_private_state_funcs {
|
||||
struct drm_private_state *state);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_private_obj - base struct for driver private atomic object
|
||||
*
|
||||
* A driver private object is initialized by calling
|
||||
* drm_atomic_private_obj_init() and cleaned up by calling
|
||||
* drm_atomic_private_obj_fini().
|
||||
*
|
||||
* Currently only tracks the state update functions and the opaque driver
|
||||
* private state itself, but in the future might also track which
|
||||
* &drm_modeset_lock is required to duplicate and update this object's state.
|
||||
*/
|
||||
struct drm_private_obj {
|
||||
/**
|
||||
* @state: Current atomic state for this driver private object.
|
||||
*/
|
||||
struct drm_private_state *state;
|
||||
|
||||
/**
|
||||
* @funcs:
|
||||
*
|
||||
* Functions to manipulate the state of this driver private object, see
|
||||
* &drm_private_state_funcs.
|
||||
*/
|
||||
const struct drm_private_state_funcs *funcs;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_private_state - base struct for driver private object state
|
||||
* @state: backpointer to global drm_atomic_state
|
||||
*
|
||||
* Currently only contains a backpointer to the overall atomic update, but in
|
||||
* the future also might hold synchronization information similar to e.g.
|
||||
* &drm_crtc.commit.
|
||||
*/
|
||||
struct drm_private_state {
|
||||
struct drm_atomic_state *state;
|
||||
};
|
||||
@ -218,6 +246,10 @@ struct __drm_private_objs_state {
|
||||
* @num_private_objs: size of the @private_objs array
|
||||
* @private_objs: pointer to array of private object pointers
|
||||
* @acquire_ctx: acquire context for this atomic modeset state update
|
||||
*
|
||||
* States are added to an atomic update by calling drm_atomic_get_crtc_state(),
|
||||
* drm_atomic_get_plane_state(), drm_atomic_get_connector_state(), or for
|
||||
* private state structures, drm_atomic_get_private_obj_state().
|
||||
*/
|
||||
struct drm_atomic_state {
|
||||
struct kref ref;
|
||||
|
@ -33,6 +33,7 @@
|
||||
struct drm_fb_helper;
|
||||
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_device.h>
|
||||
#include <linux/kgdb.h>
|
||||
|
||||
enum mode_set_atomic {
|
||||
@ -275,6 +276,7 @@ void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper);
|
||||
|
||||
void drm_fb_helper_deferred_io(struct fb_info *info,
|
||||
struct list_head *pagelist);
|
||||
int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper);
|
||||
|
||||
ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
@ -319,6 +321,13 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_
|
||||
int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
|
||||
struct drm_connector *connector);
|
||||
|
||||
int drm_fb_helper_fbdev_setup(struct drm_device *dev,
|
||||
struct drm_fb_helper *fb_helper,
|
||||
const struct drm_fb_helper_funcs *funcs,
|
||||
unsigned int preferred_bpp,
|
||||
unsigned int max_conn_count);
|
||||
void drm_fb_helper_fbdev_teardown(struct drm_device *dev);
|
||||
|
||||
void drm_fb_helper_lastclose(struct drm_device *dev);
|
||||
void drm_fb_helper_output_poll_changed(struct drm_device *dev);
|
||||
#else
|
||||
@ -332,11 +341,17 @@ static inline int drm_fb_helper_init(struct drm_device *dev,
|
||||
struct drm_fb_helper *helper,
|
||||
int max_conn)
|
||||
{
|
||||
/* So drivers can use it to free the struct */
|
||||
helper->dev = dev;
|
||||
dev->fb_helper = helper;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void drm_fb_helper_fini(struct drm_fb_helper *helper)
|
||||
{
|
||||
if (helper && helper->dev)
|
||||
helper->dev->fb_helper = NULL;
|
||||
}
|
||||
|
||||
static inline int drm_fb_helper_blank(int blank, struct fb_info *info)
|
||||
@ -409,6 +424,11 @@ static inline void drm_fb_helper_deferred_io(struct fb_info *info,
|
||||
{
|
||||
}
|
||||
|
||||
static inline int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline ssize_t drm_fb_helper_sys_read(struct fb_info *info,
|
||||
char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
@ -518,6 +538,24 @@ drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
drm_fb_helper_fbdev_setup(struct drm_device *dev,
|
||||
struct drm_fb_helper *fb_helper,
|
||||
const struct drm_fb_helper_funcs *funcs,
|
||||
unsigned int preferred_bpp,
|
||||
unsigned int max_conn_count)
|
||||
{
|
||||
/* So drivers can use it to free the struct */
|
||||
dev->fb_helper = fb_helper;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void drm_fb_helper_fbdev_teardown(struct drm_device *dev)
|
||||
{
|
||||
dev->fb_helper = NULL;
|
||||
}
|
||||
|
||||
static inline void drm_fb_helper_lastclose(struct drm_device *dev)
|
||||
{
|
||||
}
|
||||
|
@ -121,6 +121,12 @@ struct drm_framebuffer {
|
||||
* @base: base modeset object structure, contains the reference count.
|
||||
*/
|
||||
struct drm_mode_object base;
|
||||
|
||||
/**
|
||||
* @comm: Name of the process allocating the fb, used for fb dumping.
|
||||
*/
|
||||
char comm[TASK_COMM_LEN];
|
||||
|
||||
/**
|
||||
* @format: framebuffer format information
|
||||
*/
|
||||
|
@ -269,6 +269,9 @@ struct drm_mode_config_funcs {
|
||||
* state easily. If this hook is implemented, drivers must also
|
||||
* implement @atomic_state_clear and @atomic_state_free.
|
||||
*
|
||||
* Subclassing of &drm_atomic_state is deprecated in favour of using
|
||||
* &drm_private_state and &drm_private_obj.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* A new &drm_atomic_state on success or NULL on failure.
|
||||
@ -290,6 +293,9 @@ struct drm_mode_config_funcs {
|
||||
*
|
||||
* Drivers that implement this must call drm_atomic_state_default_clear()
|
||||
* to clear common state.
|
||||
*
|
||||
* Subclassing of &drm_atomic_state is deprecated in favour of using
|
||||
* &drm_private_state and &drm_private_obj.
|
||||
*/
|
||||
void (*atomic_state_clear)(struct drm_atomic_state *state);
|
||||
|
||||
@ -302,6 +308,9 @@ struct drm_mode_config_funcs {
|
||||
*
|
||||
* Drivers that implement this must call
|
||||
* drm_atomic_state_default_release() to release common resources.
|
||||
*
|
||||
* Subclassing of &drm_atomic_state is deprecated in favour of using
|
||||
* &drm_private_state and &drm_private_obj.
|
||||
*/
|
||||
void (*atomic_state_free)(struct drm_atomic_state *state);
|
||||
};
|
||||
|
@ -80,13 +80,13 @@ void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf);
|
||||
__printf(2, 3)
|
||||
void drm_printf(struct drm_printer *p, const char *f, ...);
|
||||
|
||||
__printf(2, 0)
|
||||
/**
|
||||
* drm_vprintf - print to a &drm_printer stream
|
||||
* @p: the &drm_printer
|
||||
* @fmt: format string
|
||||
* @va: the va_list
|
||||
*/
|
||||
__printf(2, 0)
|
||||
static inline void
|
||||
drm_vprintf(struct drm_printer *p, const char *fmt, va_list *va)
|
||||
{
|
||||
|
@ -33,36 +33,31 @@ struct drm_syncobj_cb;
|
||||
/**
|
||||
* struct drm_syncobj - sync object.
|
||||
*
|
||||
* This structure defines a generic sync object which wraps a dma fence.
|
||||
* This structure defines a generic sync object which wraps a &dma_fence.
|
||||
*/
|
||||
struct drm_syncobj {
|
||||
/**
|
||||
* @refcount:
|
||||
*
|
||||
* Reference count of this object.
|
||||
* @refcount: Reference count of this object.
|
||||
*/
|
||||
struct kref refcount;
|
||||
/**
|
||||
* @fence:
|
||||
* NULL or a pointer to the fence bound to this object.
|
||||
*
|
||||
* This field should not be used directly. Use drm_syncobj_fence_get
|
||||
* and drm_syncobj_replace_fence instead.
|
||||
* This field should not be used directly. Use drm_syncobj_fence_get()
|
||||
* and drm_syncobj_replace_fence() instead.
|
||||
*/
|
||||
struct dma_fence __rcu *fence;
|
||||
/**
|
||||
* @cb_list:
|
||||
* List of callbacks to call when the fence gets replaced
|
||||
* @cb_list: List of callbacks to call when the &fence gets replaced.
|
||||
*/
|
||||
struct list_head cb_list;
|
||||
/**
|
||||
* @lock:
|
||||
* locks cb_list and write-locks fence.
|
||||
* @lock: Protects &cb_list and write-locks &fence.
|
||||
*/
|
||||
spinlock_t lock;
|
||||
/**
|
||||
* @file:
|
||||
* a file backing for this syncobj.
|
||||
* @file: A file backing for this syncobj.
|
||||
*/
|
||||
struct file *file;
|
||||
};
|
||||
@ -73,7 +68,7 @@ typedef void (*drm_syncobj_func_t)(struct drm_syncobj *syncobj,
|
||||
/**
|
||||
* struct drm_syncobj_cb - callback for drm_syncobj_add_callback
|
||||
* @node: used by drm_syncob_add_callback to append this struct to
|
||||
* syncobj::cb_list
|
||||
* &drm_syncobj.cb_list
|
||||
* @func: drm_syncobj_func_t to call
|
||||
*
|
||||
* This struct will be initialized by drm_syncobj_add_callback, additional
|
||||
@ -92,7 +87,7 @@ void drm_syncobj_free(struct kref *kref);
|
||||
* drm_syncobj_get - acquire a syncobj reference
|
||||
* @obj: sync object
|
||||
*
|
||||
* This acquires additional reference to @obj. It is illegal to call this
|
||||
* This acquires an additional reference to @obj. It is illegal to call this
|
||||
* without already holding a reference. No locks required.
|
||||
*/
|
||||
static inline void
|
||||
@ -111,6 +106,17 @@ drm_syncobj_put(struct drm_syncobj *obj)
|
||||
kref_put(&obj->refcount, drm_syncobj_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_syncobj_fence_get - get a reference to a fence in a sync object
|
||||
* @syncobj: sync object.
|
||||
*
|
||||
* This acquires additional reference to &drm_syncobj.fence contained in @obj,
|
||||
* if not NULL. It is illegal to call this without already holding a reference.
|
||||
* No locks required.
|
||||
*
|
||||
* Returns:
|
||||
* Either the fence of @obj or NULL if there's none.
|
||||
*/
|
||||
static inline struct dma_fence *
|
||||
drm_syncobj_fence_get(struct drm_syncobj *syncobj)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user