Commit 978c6050 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-docs' of ssh://people.freedesktop.org/~danvet/drm into drm-next

Here's my drm documentation update and driver api polish pull request.
Alex reviewed the entire pile, I've applied a little bit of spelling
polish in a few places since then and otherwise the Usual Suspects (David,
Rob, ...) don't seem up to have another look at it (I've poked them on
irc). So I think it's as good as it gets ;-)

Note that I've dropped the final imx breaker patch since that's blocked on
imx getting sane. Once that's landed I'll ping you to pick up that
straggler.

* 'drm-docs' of ssh://people.freedesktop.org/~danvet/drm: (34 commits)
  drm/imx: remove drm_mode_connector_detach_encoder harder
  drm: kerneldoc polish for drm_crtc.c
  drm: kerneldoc polish for drm_crtc_helper.c
  drm: drop error code for drm_helper_resume_force_mode
  drm/crtc-helper: remove LOCKING from kerneldoc
  drm: remove return value from drm_helper_mode_fill_fb_struct
  drm/doc: Fix misplaced </para>
  drm: remove drm_display_mode->private_size
  drm: polish function kerneldoc for drm_modes.[hc]
  drm/modes: drop maxPitch from drm_mode_validate_size
  drm/modes: drop return value from drm_display_mode_from_videomode
  drm/modes: remove drm_mode_height/width
  drm: extract drm_modes.h for drm_crtc.h functions
  drm: move drm_mode related functions into drm_modes.c
  drm/doc: Repleace LOCKING kerneldoc sections in drm_modes.c
  drm/doc: Integrate drm_modes.c kerneldoc
  drm/kms: rip out drm_mode_connector_detach_encoder
  drm/doc: Add function reference documentation for drm_mm.c
  drm/doc: Overview documentation for drm_mm.c
  drm/mm: Remove MM_UNUSED_TARGET
  ...
parents 8ad2bc97 fc1645ac
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright © 2006 Keith Packard
* Copyright © 2007-2008 Dave Airlie
* Copyright © 2007-2008 Intel Corporation
* Jesse Barnes <jesse.barnes@intel.com>
* Copyright © 2014 Intel Corporation
* Daniel Vetter <daniel.vetter@ffwll.ch>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* This header file contains mode setting related functions and definitions
* which are only used within the drm module as internal implementation details
* and are not exported to drivers.
*/
int drm_mode_object_get(struct drm_device *dev,
struct drm_mode_object *obj, uint32_t obj_type);
void drm_mode_object_put(struct drm_device *dev,
struct drm_mode_object *object);
...@@ -1098,10 +1098,14 @@ EXPORT_SYMBOL(drm_edid_is_valid); ...@@ -1098,10 +1098,14 @@ EXPORT_SYMBOL(drm_edid_is_valid);
/** /**
* Get EDID information via I2C. * Get EDID information via I2C.
* *
* \param adapter : i2c device adaptor * @adapter : i2c device adaptor
* \param buf : EDID data buffer to be filled * @buf: EDID data buffer to be filled
* \param len : EDID data buffer length * @block: 128 byte EDID block to start fetching from
* \return 0 on success or -1 on failure. * @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. * Try to fetch EDID information by calling i2c driver function.
*/ */
...@@ -1243,9 +1247,11 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) ...@@ -1243,9 +1247,11 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
/** /**
* Probe DDC presence. * Probe DDC presence.
* @adapter: i2c adapter to probe
*
* Returns:
* *
* \param adapter : i2c device adaptor * 1 on success
* \return 1 on success
*/ */
bool bool
drm_probe_ddc(struct i2c_adapter *adapter) drm_probe_ddc(struct i2c_adapter *adapter)
...@@ -1586,8 +1592,10 @@ bad_std_timing(u8 a, u8 b) ...@@ -1586,8 +1592,10 @@ bad_std_timing(u8 a, u8 b)
/** /**
* drm_mode_std - convert standard mode info (width, height, refresh) into mode * 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 * @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) * Take the standard timing params (in this case width, aspect, and refresh)
* and convert them into a real mode using CVT/GTF/DMT. * and convert them into a real mode using CVT/GTF/DMT.
...@@ -2132,6 +2140,7 @@ do_established_modes(struct detailed_timing *timing, void *c) ...@@ -2132,6 +2140,7 @@ do_established_modes(struct detailed_timing *timing, void *c)
/** /**
* add_established_modes - get est. modes from EDID and add them * add_established_modes - get est. modes from EDID and add them
* @connector: connector of for the EDID block
* @edid: EDID block to scan * @edid: EDID block to scan
* *
* Each EDID block contains a bitmap of the supported "established modes" list * 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) ...@@ -2194,6 +2203,7 @@ do_standard_modes(struct detailed_timing *timing, void *c)
/** /**
* add_standard_modes - get std. modes from EDID and add them * add_standard_modes - get std. modes from EDID and add them
* @connector: connector of for the EDID block
* @edid: EDID block to scan * @edid: EDID block to scan
* *
* Standard modes can be calculated using the appropriate standard (DMT, * Standard modes can be calculated using the appropriate standard (DMT,
...@@ -3300,6 +3310,7 @@ EXPORT_SYMBOL(drm_detect_hdmi_monitor); ...@@ -3300,6 +3310,7 @@ EXPORT_SYMBOL(drm_detect_hdmi_monitor);
/** /**
* drm_detect_monitor_audio - check monitor audio capability * drm_detect_monitor_audio - check monitor audio capability
* @edid: EDID block to scan
* *
* Monitor should have CEA extension block. * Monitor should have CEA extension block.
* If monitor has 'basic audio', but no CEA audio blocks, it's 'basic * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic
...@@ -3345,6 +3356,7 @@ EXPORT_SYMBOL(drm_detect_monitor_audio); ...@@ -3345,6 +3356,7 @@ EXPORT_SYMBOL(drm_detect_monitor_audio);
/** /**
* drm_rgb_quant_range_selectable - is RGB quantization range selectable? * 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 * Check whether the monitor reports the RGB quantization range selection
* as supported. The AVI infoframe can then be used to inform the monitor * as supported. The AVI infoframe can then be used to inform the monitor
...@@ -3564,8 +3576,8 @@ void drm_set_preferred_mode(struct drm_connector *connector, ...@@ -3564,8 +3576,8 @@ void drm_set_preferred_mode(struct drm_connector *connector,
struct drm_display_mode *mode; struct drm_display_mode *mode;
list_for_each_entry(mode, &connector->probed_modes, head) { list_for_each_entry(mode, &connector->probed_modes, head) {
if (drm_mode_width(mode) == hpref && if (mode->hdisplay == hpref &&
drm_mode_height(mode) == vpref) mode->vdisplay == vpref)
mode->type |= DRM_MODE_TYPE_PREFERRED; mode->type |= DRM_MODE_TYPE_PREFERRED;
} }
} }
......
...@@ -1141,8 +1141,8 @@ struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector * ...@@ -1141,8 +1141,8 @@ struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector *
struct drm_display_mode *mode; struct drm_display_mode *mode;
list_for_each_entry(mode, &fb_connector->connector->modes, head) { list_for_each_entry(mode, &fb_connector->connector->modes, head) {
if (drm_mode_width(mode) > width || if (mode->hdisplay > width ||
drm_mode_height(mode) > height) mode->vdisplay > height)
continue; continue;
if (mode->type & DRM_MODE_TYPE_PREFERRED) if (mode->type & DRM_MODE_TYPE_PREFERRED)
return mode; return mode;
......
...@@ -85,9 +85,9 @@ ...@@ -85,9 +85,9 @@
#endif #endif
/** /**
* Initialize the GEM device fields * drm_gem_init - Initialize the GEM device fields
* @dev: drm_devic structure to initialize
*/ */
int int
drm_gem_init(struct drm_device *dev) drm_gem_init(struct drm_device *dev)
{ {
...@@ -120,6 +120,11 @@ drm_gem_destroy(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 * Initialize an already allocated GEM object of the specified size with
* shmfs backing store. * shmfs backing store.
*/ */
...@@ -141,6 +146,11 @@ int drm_gem_object_init(struct drm_device *dev, ...@@ -141,6 +146,11 @@ int drm_gem_object_init(struct drm_device *dev,
EXPORT_SYMBOL(drm_gem_object_init); 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 * Initialize an already allocated GEM object of the specified size with
* no GEM provided backing store. Instead the caller is responsible for * no GEM provided backing store. Instead the caller is responsible for
* backing the object and handling it. * backing the object and handling it.
...@@ -176,6 +186,9 @@ drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) ...@@ -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 * Called after the last handle to the object has been closed
* *
* Removes any name for the object. Note that this must be * 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) ...@@ -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 int
drm_gem_handle_delete(struct drm_file *filp, u32 handle) drm_gem_handle_delete(struct drm_file *filp, u32 handle)
...@@ -270,6 +288,9 @@ EXPORT_SYMBOL(drm_gem_handle_delete); ...@@ -270,6 +288,9 @@ EXPORT_SYMBOL(drm_gem_handle_delete);
/** /**
* drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers * 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 * This implements the ->dumb_destroy kms driver callback for drivers which use
* gem to manage their backing storage. * gem to manage their backing storage.
...@@ -284,6 +305,9 @@ EXPORT_SYMBOL(drm_gem_dumb_destroy); ...@@ -284,6 +305,9 @@ EXPORT_SYMBOL(drm_gem_dumb_destroy);
/** /**
* drm_gem_handle_create_tail - internal functions to create a handle * 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 * 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 * 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, ...@@ -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 * Create a handle for this object. This adds a handle reference
* to the object, which includes a regular reference count. Callers * to the object, which includes a regular reference count. Callers
* will likely want to dereference the object afterwards. * will likely want to dereference the object afterwards.
...@@ -536,6 +565,11 @@ drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, ...@@ -536,6 +565,11 @@ drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
EXPORT_SYMBOL(drm_gem_object_lookup); 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. * Releases the handle to an mm object.
*/ */
int int
...@@ -554,6 +588,11 @@ drm_gem_close_ioctl(struct drm_device *dev, void *data, ...@@ -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. * Create a global name for an object, returning the name.
* *
* Note that the name does not hold a reference; when the object * Note that the name does not hold a reference; when the object
...@@ -601,6 +640,11 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data, ...@@ -601,6 +640,11 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
} }
/** /**
* 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. * 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 * 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, ...@@ -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 * Called at device open time, sets up the structure for handling refcounting
* of mm objects. * of mm objects.
*/ */
...@@ -650,7 +698,7 @@ drm_gem_open(struct drm_device *dev, struct drm_file *file_private) ...@@ -650,7 +698,7 @@ drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
spin_lock_init(&file_private->table_lock); spin_lock_init(&file_private->table_lock);
} }
/** /*
* Called at device close to release the file's * Called at device close to release the file's
* handle references on objects. * handle references on objects.
*/ */
...@@ -674,6 +722,10 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) ...@@ -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. * Called at close time when the filp is going away.
* *
* Releases any remaining references on objects by this filp. * Releases any remaining references on objects by this filp.
...@@ -699,6 +751,9 @@ drm_gem_object_release(struct drm_gem_object *obj) ...@@ -699,6 +751,9 @@ drm_gem_object_release(struct drm_gem_object *obj)
EXPORT_SYMBOL(drm_gem_object_release); 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. * Called after the last reference to the object has been lost.
* Must be called holding struct_ mutex * Must be called holding struct_ mutex
* *
......
This diff is collapsed.
This diff is collapsed.
...@@ -68,7 +68,8 @@ struct drm_prime_attachment { ...@@ -68,7 +68,8 @@ struct drm_prime_attachment {
enum dma_data_direction dir; 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; struct drm_prime_member *member;
...@@ -174,7 +175,7 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr ...@@ -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, 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_prime_attachment *prime_attach = attach->priv;
struct drm_gem_object *obj = attach->dmabuf->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, ...@@ -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, 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 */ /* 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) void drm_gem_dmabuf_release(struct dma_buf *dma_buf)
{ {
struct drm_gem_object *obj = dma_buf->priv; 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) ...@@ -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, static void *drm_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf,
unsigned long page_num) unsigned long page_num)
{ {
return NULL; return NULL;
} }
static void drm_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, 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, static void *drm_gem_dmabuf_kmap(struct dma_buf *dma_buf,
unsigned long page_num) unsigned long page_num)
{ {
return NULL; return NULL;
} }
static void drm_gem_dmabuf_kunmap(struct dma_buf *dma_buf, 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, 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_gem_object *obj = dma_buf->priv;
struct drm_device *dev = obj->dev; struct drm_device *dev = obj->dev;
...@@ -315,6 +324,15 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { ...@@ -315,6 +324,15 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
* driver's scatter/gather table * 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 dma_buf *drm_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags) struct drm_gem_object *obj, int flags)
{ {
...@@ -355,9 +373,23 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, ...@@ -355,9 +373,23 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev,
return dmabuf; 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, int drm_gem_prime_handle_to_fd(struct drm_device *dev,
struct drm_file *file_priv, uint32_t handle, uint32_t flags, struct drm_file *file_priv, uint32_t handle,
int *prime_fd) uint32_t flags,
int *prime_fd)
{ {
struct drm_gem_object *obj; struct drm_gem_object *obj;
int ret = 0; int ret = 0;
...@@ -441,6 +473,14 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, ...@@ -441,6 +473,14 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
} }
EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); 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 drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
struct dma_buf *dma_buf) struct dma_buf *dma_buf)
{ {
...@@ -496,8 +536,21 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, ...@@ -496,8 +536,21 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
} }
EXPORT_SYMBOL(drm_gem_prime_import); 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, 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 dma_buf *dma_buf;
struct drm_gem_object *obj; struct drm_gem_object *obj;
...@@ -598,12 +651,14 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, ...@@ -598,12 +651,14 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
args->fd, &args->handle); 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 * 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) struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages)
{ {
...@@ -628,9 +683,16 @@ struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) ...@@ -628,9 +683,16 @@ struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages)
} }
EXPORT_SYMBOL(drm_prime_pages_to_sg); 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 * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array
handling */ * @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, int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
dma_addr_t *addrs, int max_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, ...@@ -663,7 +725,15 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
return 0; return 0;
} }
EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays); 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) void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg)
{ {
struct dma_buf_attachment *attach; struct dma_buf_attachment *attach;
...@@ -683,11 +753,9 @@ void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) ...@@ -683,11 +753,9 @@ void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv)
INIT_LIST_HEAD(&prime_fpriv->head); INIT_LIST_HEAD(&prime_fpriv->head);
mutex_init(&prime_fpriv->lock); 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) 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 */ /* by now drm_gem_release should've made sure the list is empty */
WARN_ON(!list_empty(&prime_fpriv->head)); WARN_ON(!list_empty(&prime_fpriv->head));
} }
EXPORT_SYMBOL(drm_prime_destroy_file_private);
...@@ -1883,7 +1883,6 @@ static int imx_hdmi_platform_remove(struct platform_device *pdev) ...@@ -1883,7 +1883,6 @@ static int imx_hdmi_platform_remove(struct platform_device *pdev)
struct drm_connector *connector = &hdmi->connector; struct drm_connector *connector = &hdmi->connector;
struct drm_encoder *encoder = &hdmi->encoder; struct drm_encoder *encoder = &hdmi->encoder;
drm_mode_connector_detach_encoder(connector, encoder);
imx_drm_remove_connector(hdmi->imx_drm_connector); imx_drm_remove_connector(hdmi->imx_drm_connector);
imx_drm_remove_encoder(hdmi->imx_drm_encoder); imx_drm_remove_encoder(hdmi->imx_drm_encoder);
......
...@@ -595,8 +595,6 @@ static int imx_ldb_remove(struct platform_device *pdev) ...@@ -595,8 +595,6 @@ static int imx_ldb_remove(struct platform_device *pdev)
struct drm_connector *connector = &channel->connector; struct drm_connector *connector = &channel->connector;
struct drm_encoder *encoder = &channel->encoder; struct drm_encoder *encoder = &channel->encoder;
drm_mode_connector_detach_encoder(connector, encoder);
imx_drm_remove_connector(channel->imx_drm_connector); imx_drm_remove_connector(channel->imx_drm_connector);
imx_drm_remove_encoder(channel->imx_drm_encoder); imx_drm_remove_encoder(channel->imx_drm_encoder);
} }
......
...@@ -709,8 +709,6 @@ static int imx_tve_remove(struct platform_device *pdev) ...@@ -709,8 +709,6 @@ static int imx_tve_remove(struct platform_device *pdev)
struct drm_connector *connector = &tve->connector; struct drm_connector *connector = &tve->connector;
struct drm_encoder *encoder = &tve->encoder; struct drm_encoder *encoder = &tve->encoder;
drm_mode_connector_detach_encoder(connector, encoder);
imx_drm_remove_connector(tve->imx_drm_connector); imx_drm_remove_connector(tve->imx_drm_connector);
imx_drm_remove_encoder(tve->imx_drm_encoder); imx_drm_remove_encoder(tve->imx_drm_encoder);
......
...@@ -244,8 +244,6 @@ static int imx_pd_remove(struct platform_device *pdev) ...@@ -244,8 +244,6 @@ static int imx_pd_remove(struct platform_device *pdev)
struct drm_connector *connector = &imxpd->connector; struct drm_connector *connector = &imxpd->connector;
struct drm_encoder *encoder = &imxpd->encoder; struct drm_encoder *encoder = &imxpd->encoder;
drm_mode_connector_detach_encoder(connector, encoder);
imx_drm_remove_connector(imxpd->imx_drm_connector); imx_drm_remove_connector(imxpd->imx_drm_connector);
imx_drm_remove_encoder(imxpd->imx_drm_encoder); imx_drm_remove_encoder(imxpd->imx_drm_encoder);
......
...@@ -1056,21 +1056,6 @@ struct drm_minor { ...@@ -1056,21 +1056,6 @@ struct drm_minor {
struct drm_mode_group mode_group; struct drm_mode_group mode_group;
}; };
/* mode specified on the command line */
struct drm_cmdline_mode {
bool specified;
bool refresh_specified;
bool bpp_specified;
int xres, yres;
int bpp;
int refresh;
bool rb;
bool interlace;
bool cvt;
bool margins;
enum drm_connector_force force;
};
struct drm_pending_vblank_event { struct drm_pending_vblank_event {
struct drm_pending_event base; struct drm_pending_event base;
...@@ -1417,20 +1402,6 @@ extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, ...@@ -1417,20 +1402,6 @@ extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
extern void drm_calc_timestamping_constants(struct drm_crtc *crtc, extern void drm_calc_timestamping_constants(struct drm_crtc *crtc,
const struct drm_display_mode *mode); const struct drm_display_mode *mode);
extern bool
drm_mode_parse_command_line_for_connector(const char *mode_option,
struct drm_connector *connector,
struct drm_cmdline_mode *mode);
extern struct drm_display_mode *
drm_mode_create_from_cmdline_mode(struct drm_device *dev,
struct drm_cmdline_mode *cmd);
extern int drm_display_mode_from_videomode(const struct videomode *vm,
struct drm_display_mode *dmode);
extern int of_get_drm_display_mode(struct device_node *np,
struct drm_display_mode *dmode,
int index);
/* Modesetting support */ /* Modesetting support */
extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
......
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/hdmi.h> #include <linux/hdmi.h>
#include <drm/drm_mode.h> #include <drm/drm_mode.h>
#include <drm/drm_fourcc.h> #include <drm/drm_fourcc.h>
struct drm_device; struct drm_device;
...@@ -65,130 +64,14 @@ struct drm_object_properties { ...@@ -65,130 +64,14 @@ struct drm_object_properties {
uint64_t values[DRM_OBJECT_MAX_PROPERTY]; uint64_t values[DRM_OBJECT_MAX_PROPERTY];
}; };
/* enum drm_connector_force {
* Note on terminology: here, for brevity and convenience, we refer to connector DRM_FORCE_UNSPECIFIED,
* control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS, DRM_FORCE_OFF,
* DVI, etc. And 'screen' refers to the whole of the visible display, which DRM_FORCE_ON, /* force on analog part normally */
* may span multiple monitors (and therefore multiple CRTC and connector DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */
* structures).
*/
enum drm_mode_status {
MODE_OK = 0, /* Mode OK */
MODE_HSYNC, /* hsync out of range */
MODE_VSYNC, /* vsync out of range */
MODE_H_ILLEGAL, /* mode has illegal horizontal timings */
MODE_V_ILLEGAL, /* mode has illegal horizontal timings */
MODE_BAD_WIDTH, /* requires an unsupported linepitch */
MODE_NOMODE, /* no mode with a matching name */
MODE_NO_INTERLACE, /* interlaced mode not supported */
MODE_NO_DBLESCAN, /* doublescan mode not supported */
MODE_NO_VSCAN, /* multiscan mode not supported */
MODE_MEM, /* insufficient video memory */
MODE_VIRTUAL_X, /* mode width too large for specified virtual size */
MODE_VIRTUAL_Y, /* mode height too large for specified virtual size */
MODE_MEM_VIRT, /* insufficient video memory given virtual size */
MODE_NOCLOCK, /* no fixed clock available */
MODE_CLOCK_HIGH, /* clock required is too high */
MODE_CLOCK_LOW, /* clock required is too low */
MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */
MODE_BAD_HVALUE, /* horizontal timing was out of range */
MODE_BAD_VVALUE, /* vertical timing was out of range */
MODE_BAD_VSCAN, /* VScan value out of range */
MODE_HSYNC_NARROW, /* horizontal sync too narrow */
MODE_HSYNC_WIDE, /* horizontal sync too wide */
MODE_HBLANK_NARROW, /* horizontal blanking too narrow */
MODE_HBLANK_WIDE, /* horizontal blanking too wide */
MODE_VSYNC_NARROW, /* vertical sync too narrow */
MODE_VSYNC_WIDE, /* vertical sync too wide */
MODE_VBLANK_NARROW, /* vertical blanking too narrow */
MODE_VBLANK_WIDE, /* vertical blanking too wide */
MODE_PANEL, /* exceeds panel dimensions */
MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */
MODE_ONE_WIDTH, /* only one width is supported */
MODE_ONE_HEIGHT, /* only one height is supported */
MODE_ONE_SIZE, /* only one resolution is supported */
MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */
MODE_NO_STEREO, /* stereo modes not supported */
MODE_UNVERIFIED = -3, /* mode needs to reverified */
MODE_BAD = -2, /* unspecified reason */
MODE_ERROR = -1 /* error condition */
};
#define DRM_MODE_TYPE_CLOCK_CRTC_C (DRM_MODE_TYPE_CLOCK_C | \
DRM_MODE_TYPE_CRTC_C)
#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \
.name = nm, .status = 0, .type = (t), .clock = (c), \
.hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
.htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
.vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
.vscan = (vs), .flags = (f), \
.base.type = DRM_MODE_OBJECT_MODE
#define CRTC_INTERLACE_HALVE_V (1 << 0) /* halve V values for interlacing */
#define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */
#define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF
struct drm_display_mode {
/* Header */
struct list_head head;
struct drm_mode_object base;
char name[DRM_DISPLAY_MODE_LEN];
enum drm_mode_status status;
unsigned int type;
/* Proposed mode values */
int clock; /* in kHz */
int hdisplay;
int hsync_start;
int hsync_end;
int htotal;
int hskew;
int vdisplay;
int vsync_start;
int vsync_end;
int vtotal;
int vscan;
unsigned int flags;
/* Addressable image size (may be 0 for projectors, etc.) */
int width_mm;
int height_mm;
/* Actual mode we give to hw */
int crtc_clock; /* in KHz */
int crtc_hdisplay;
int crtc_hblank_start;
int crtc_hblank_end;
int crtc_hsync_start;
int crtc_hsync_end;
int crtc_htotal;
int crtc_hskew;
int crtc_vdisplay;
int crtc_vblank_start;
int crtc_vblank_end;
int crtc_vsync_start;
int crtc_vsync_end;
int crtc_vtotal;
/* Driver private mode info */
int private_size;
int *private;
int private_flags;
int vrefresh; /* in Hz */
int hsync; /* in kHz */
enum hdmi_picture_aspect picture_aspect_ratio;
}; };
static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode) #include <drm/drm_modes.h>
{
return mode->flags & DRM_MODE_FLAG_3D_MASK;
}
enum drm_connector_status { enum drm_connector_status {
connector_status_connected = 1, connector_status_connected = 1,
...@@ -540,13 +423,6 @@ struct drm_encoder { ...@@ -540,13 +423,6 @@ struct drm_encoder {
void *helper_private; void *helper_private;
}; };
enum drm_connector_force {
DRM_FORCE_UNSPECIFIED,
DRM_FORCE_OFF,
DRM_FORCE_ON, /* force on analog part normally */
DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */
};
/* should we poll this connector for connects and disconnects */ /* should we poll this connector for connects and disconnects */
/* hot plug detectable */ /* hot plug detectable */
#define DRM_CONNECTOR_POLL_HPD (1 << 0) #define DRM_CONNECTOR_POLL_HPD (1 << 0)
...@@ -1007,34 +883,10 @@ extern struct edid *drm_get_edid(struct drm_connector *connector, ...@@ -1007,34 +883,10 @@ extern struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter); struct i2c_adapter *adapter);
extern struct edid *drm_edid_duplicate(const struct edid *edid); extern struct edid *drm_edid_duplicate(const struct edid *edid);
extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
extern void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src);
extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
const struct drm_display_mode *mode);
extern void drm_mode_debug_printmodeline(const struct drm_display_mode *mode);
extern void drm_mode_config_init(struct drm_device *dev); extern void drm_mode_config_init(struct drm_device *dev);
extern void drm_mode_config_reset(struct drm_device *dev); extern void drm_mode_config_reset(struct drm_device *dev);
extern void drm_mode_config_cleanup(struct drm_device *dev); extern void drm_mode_config_cleanup(struct drm_device *dev);
extern void drm_mode_set_name(struct drm_display_mode *mode);
extern bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2);
extern bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2);
extern int drm_mode_width(const struct drm_display_mode *mode);
extern int drm_mode_height(const struct drm_display_mode *mode);
/* for us by fb module */
extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);
extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
extern void drm_mode_validate_size(struct drm_device *dev,
struct list_head *mode_list,
int maxX, int maxY, int maxPitch);
extern void drm_mode_prune_invalid(struct drm_device *dev,
struct list_head *mode_list, bool verbose);
extern void drm_mode_sort(struct list_head *mode_list);
extern int drm_mode_hsync(const struct drm_display_mode *mode);
extern int drm_mode_vrefresh(const struct drm_display_mode *mode);
extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
int adjust_flags);
extern void drm_mode_connector_list_update(struct drm_connector *connector);
extern int drm_mode_connector_update_edid_property(struct drm_connector *connector, extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
struct edid *edid); struct edid *edid);
extern int drm_object_property_set_value(struct drm_mode_object *obj, extern int drm_object_property_set_value(struct drm_mode_object *obj,
...@@ -1082,8 +934,6 @@ extern const char *drm_get_encoder_name(const struct drm_encoder *encoder); ...@@ -1082,8 +934,6 @@ extern const char *drm_get_encoder_name(const struct drm_encoder *encoder);
extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
struct drm_encoder *encoder); struct drm_encoder *encoder);
extern void drm_mode_connector_detach_encoder(struct drm_connector *connector,
struct drm_encoder *encoder);
extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
int gamma_size); int gamma_size);
extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
...@@ -1138,16 +988,6 @@ extern bool drm_detect_monitor_audio(struct edid *edid); ...@@ -1138,16 +988,6 @@ extern bool drm_detect_monitor_audio(struct edid *edid);
extern bool drm_rgb_quant_range_selectable(struct edid *edid); extern bool drm_rgb_quant_range_selectable(struct edid *edid);
extern int drm_mode_page_flip_ioctl(struct drm_device *dev, extern int drm_mode_page_flip_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv); void *data, struct drm_file *file_priv);
extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
int hdisplay, int vdisplay, int vrefresh,
bool reduced, bool interlaced, bool margins);
extern struct drm_display_mode *drm_gtf_mode(struct drm_device *dev,
int hdisplay, int vdisplay, int vrefresh,
bool interlaced, int margins);
extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev,
int hdisplay, int vdisplay, int vrefresh,
bool interlaced, int margins, int GTF_M,
int GTF_2C, int GTF_K, int GTF_2J);
extern int drm_add_modes_noedid(struct drm_connector *connector, extern int drm_add_modes_noedid(struct drm_connector *connector,
int hdisplay, int vdisplay); int hdisplay, int vdisplay);
extern void drm_set_preferred_mode(struct drm_connector *connector, extern void drm_set_preferred_mode(struct drm_connector *connector,
......
...@@ -139,8 +139,8 @@ extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode) ...@@ -139,8 +139,8 @@ extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
extern void drm_helper_move_panel_connectors_to_head(struct drm_device *); extern void drm_helper_move_panel_connectors_to_head(struct drm_device *);
extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, extern void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
struct drm_mode_fb_cmd2 *mode_cmd); struct drm_mode_fb_cmd2 *mode_cmd);
static inline void drm_crtc_helper_add(struct drm_crtc *crtc, static inline void drm_crtc_helper_add(struct drm_crtc *crtc,
const struct drm_crtc_helper_funcs *funcs) const struct drm_crtc_helper_funcs *funcs)
...@@ -160,7 +160,7 @@ static inline void drm_connector_helper_add(struct drm_connector *connector, ...@@ -160,7 +160,7 @@ static inline void drm_connector_helper_add(struct drm_connector *connector,
connector->helper_private = (void *)funcs; connector->helper_private = (void *)funcs;
} }
extern int drm_helper_resume_force_mode(struct drm_device *dev); extern void drm_helper_resume_force_mode(struct drm_device *dev);
extern void drm_kms_helper_poll_init(struct drm_device *dev); extern void drm_kms_helper_poll_init(struct drm_device *dev);
extern void drm_kms_helper_poll_fini(struct drm_device *dev); extern void drm_kms_helper_poll_fini(struct drm_device *dev);
extern bool drm_helper_hpd_irq_event(struct drm_device *dev); extern bool drm_helper_hpd_irq_event(struct drm_device *dev);
......
...@@ -85,11 +85,31 @@ struct drm_mm { ...@@ -85,11 +85,31 @@ struct drm_mm {
unsigned long *start, unsigned long *end); unsigned long *start, unsigned long *end);
}; };
/**
* drm_mm_node_allocated - checks whether a node is allocated
* @node: drm_mm_node to check
*
* Drivers should use this helpers for proper encapusulation of drm_mm
* internals.
*
* Returns:
* True if the @node is allocated.
*/
static inline bool drm_mm_node_allocated(struct drm_mm_node *node) static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
{ {
return node->allocated; return node->allocated;
} }
/**
* drm_mm_initialized - checks whether an allocator is initialized
* @mm: drm_mm to check
*
* Drivers should use this helpers for proper encapusulation of drm_mm
* internals.
*
* Returns:
* True if the @mm is initialized.
*/
static inline bool drm_mm_initialized(struct drm_mm *mm) static inline bool drm_mm_initialized(struct drm_mm *mm)
{ {
return mm->hole_stack.next; return mm->hole_stack.next;
...@@ -100,6 +120,17 @@ static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_no ...@@ -100,6 +120,17 @@ static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_no
return hole_node->start + hole_node->size; return hole_node->start + hole_node->size;
} }
/**
* drm_mm_hole_node_start - computes the start of the hole following @node
* @hole_node: drm_mm_node which implicitly tracks the following hole
*
* This is useful for driver-sepific debug dumpers. Otherwise drivers should not
* inspect holes themselves. Drivers must check first whether a hole indeed
* follows by looking at node->hole_follows.
*
* Returns:
* Start of the subsequent hole.
*/
static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node) static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node)
{ {
BUG_ON(!hole_node->hole_follows); BUG_ON(!hole_node->hole_follows);
...@@ -112,18 +143,49 @@ static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node ...@@ -112,18 +143,49 @@ static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node
struct drm_mm_node, node_list)->start; struct drm_mm_node, node_list)->start;
} }
/**
* drm_mm_hole_node_end - computes the end of the hole following @node
* @hole_node: drm_mm_node which implicitly tracks the following hole
*
* This is useful for driver-sepific debug dumpers. Otherwise drivers should not
* inspect holes themselves. Drivers must check first whether a hole indeed
* follows by looking at node->hole_follows.
*
* Returns:
* End of the subsequent hole.
*/
static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
{ {
return __drm_mm_hole_node_end(hole_node); return __drm_mm_hole_node_end(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
*
* This iterator walks over all nodes in the range allocator. It is implemented
* with list_for_each, so not save against removal of elements.
*/
#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \ #define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
&(mm)->head_node.node_list, \ &(mm)->head_node.node_list, \
node_list) node_list)
/* Note that we need to unroll list_for_each_entry in order to inline /**
* setting hole_start and hole_end on each iteration and keep the * drm_mm_for_each_hole - iterator to walk over all holes
* macro sane. * @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
* internally and will not reflect a real drm_mm_node for the very first hole.
* Hence users of this iterator may not access it.
*
* Implementation Note:
* We need to inline list_for_each_entry in order to be able to set hole_start
* and hole_end on each iteration while keeping the macro sane.
*/ */
#define drm_mm_for_each_hole(entry, mm, hole_start, hole_end) \ #define drm_mm_for_each_hole(entry, mm, hole_start, hole_end) \
for (entry = list_entry((mm)->hole_stack.next, struct drm_mm_node, hole_stack); \ for (entry = list_entry((mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
...@@ -136,14 +198,30 @@ static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) ...@@ -136,14 +198,30 @@ static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
/* /*
* Basic range manager support (drm_mm.c) * Basic range manager support (drm_mm.c)
*/ */
extern int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node); int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node);
extern int drm_mm_insert_node_generic(struct drm_mm *mm, int drm_mm_insert_node_generic(struct drm_mm *mm,
struct drm_mm_node *node, struct drm_mm_node *node,
unsigned long size, unsigned long size,
unsigned alignment, unsigned alignment,
unsigned long color, unsigned long color,
enum drm_mm_search_flags flags); enum drm_mm_search_flags flags);
/**
* drm_mm_insert_node - 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
* @flags: flags to fine-tune the allocation
*
* This is a simplified version of drm_mm_insert_node_generic() with @color set
* to 0.
*
* The preallocated node must be cleared to 0.
*
* Returns:
* 0 on success, -ENOSPC if there's no suitable hole.
*/
static inline int drm_mm_insert_node(struct drm_mm *mm, static inline int drm_mm_insert_node(struct drm_mm *mm,
struct drm_mm_node *node, struct drm_mm_node *node,
unsigned long size, unsigned long size,
...@@ -153,14 +231,32 @@ static inline int drm_mm_insert_node(struct drm_mm *mm, ...@@ -153,14 +231,32 @@ static inline int drm_mm_insert_node(struct drm_mm *mm,
return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags); return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags);
} }
extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
struct drm_mm_node *node, struct drm_mm_node *node,
unsigned long size, unsigned long size,
unsigned alignment, unsigned alignment,
unsigned long color, unsigned long color,
unsigned long start, unsigned long start,
unsigned long end, unsigned long end,
enum drm_mm_search_flags flags); enum drm_mm_search_flags flags);
/**
* drm_mm_insert_node_in_range - 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
* @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
*
* This is a simplified version of drm_mm_insert_node_in_range_generic() with
* @color set to 0.
*
* The preallocated node must be cleared to 0.
*
* Returns:
* 0 on success, -ENOSPC if there's no suitable hole.
*/
static inline int drm_mm_insert_node_in_range(struct drm_mm *mm, static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
struct drm_mm_node *node, struct drm_mm_node *node,
unsigned long size, unsigned long size,
...@@ -173,13 +269,13 @@ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm, ...@@ -173,13 +269,13 @@ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
0, start, end, flags); 0, start, end, flags);
} }
extern void drm_mm_remove_node(struct drm_mm_node *node); void drm_mm_remove_node(struct drm_mm_node *node);
extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
extern void drm_mm_init(struct drm_mm *mm, void drm_mm_init(struct drm_mm *mm,
unsigned long start, unsigned long start,
unsigned long size); unsigned long size);
extern void drm_mm_takedown(struct drm_mm *mm); void drm_mm_takedown(struct drm_mm *mm);
extern int drm_mm_clean(struct drm_mm *mm); bool drm_mm_clean(struct drm_mm *mm);
void drm_mm_init_scan(struct drm_mm *mm, void drm_mm_init_scan(struct drm_mm *mm,
unsigned long size, unsigned long size,
...@@ -191,10 +287,10 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm, ...@@ -191,10 +287,10 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm,
unsigned long color, unsigned long color,
unsigned long start, unsigned long start,
unsigned long end); unsigned long end);
int drm_mm_scan_add_block(struct drm_mm_node *node); bool drm_mm_scan_add_block(struct drm_mm_node *node);
int drm_mm_scan_remove_block(struct drm_mm_node *node); bool drm_mm_scan_remove_block(struct drm_mm_node *node);
extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix); void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm); int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
#endif #endif
......
/*
* Copyright © 2006 Keith Packard
* Copyright © 2007-2008 Dave Airlie
* Copyright © 2007-2008 Intel Corporation
* Jesse Barnes <jesse.barnes@intel.com>
* Copyright © 2014 Intel Corporation
* Daniel Vetter <daniel.vetter@ffwll.ch>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __DRM_MODES_H__
#define __DRM_MODES_H__
/*
* Note on terminology: here, for brevity and convenience, we refer to connector
* control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS,
* DVI, etc. And 'screen' refers to the whole of the visible display, which
* may span multiple monitors (and therefore multiple CRTC and connector
* structures).
*/
enum drm_mode_status {
MODE_OK = 0, /* Mode OK */
MODE_HSYNC, /* hsync out of range */
MODE_VSYNC, /* vsync out of range */
MODE_H_ILLEGAL, /* mode has illegal horizontal timings */
MODE_V_ILLEGAL, /* mode has illegal horizontal timings */
MODE_BAD_WIDTH, /* requires an unsupported linepitch */
MODE_NOMODE, /* no mode with a matching name */
MODE_NO_INTERLACE, /* interlaced mode not supported */
MODE_NO_DBLESCAN, /* doublescan mode not supported */
MODE_NO_VSCAN, /* multiscan mode not supported */
MODE_MEM, /* insufficient video memory */
MODE_VIRTUAL_X, /* mode width too large for specified virtual size */
MODE_VIRTUAL_Y, /* mode height too large for specified virtual size */
MODE_MEM_VIRT, /* insufficient video memory given virtual size */
MODE_NOCLOCK, /* no fixed clock available */
MODE_CLOCK_HIGH, /* clock required is too high */
MODE_CLOCK_LOW, /* clock required is too low */
MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */
MODE_BAD_HVALUE, /* horizontal timing was out of range */
MODE_BAD_VVALUE, /* vertical timing was out of range */
MODE_BAD_VSCAN, /* VScan value out of range */
MODE_HSYNC_NARROW, /* horizontal sync too narrow */
MODE_HSYNC_WIDE, /* horizontal sync too wide */
MODE_HBLANK_NARROW, /* horizontal blanking too narrow */
MODE_HBLANK_WIDE, /* horizontal blanking too wide */
MODE_VSYNC_NARROW, /* vertical sync too narrow */
MODE_VSYNC_WIDE, /* vertical sync too wide */
MODE_VBLANK_NARROW, /* vertical blanking too narrow */
MODE_VBLANK_WIDE, /* vertical blanking too wide */
MODE_PANEL, /* exceeds panel dimensions */
MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */
MODE_ONE_WIDTH, /* only one width is supported */
MODE_ONE_HEIGHT, /* only one height is supported */
MODE_ONE_SIZE, /* only one resolution is supported */
MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */
MODE_NO_STEREO, /* stereo modes not supported */
MODE_UNVERIFIED = -3, /* mode needs to reverified */
MODE_BAD = -2, /* unspecified reason */
MODE_ERROR = -1 /* error condition */
};
#define DRM_MODE_TYPE_CLOCK_CRTC_C (DRM_MODE_TYPE_CLOCK_C | \
DRM_MODE_TYPE_CRTC_C)
#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \
.name = nm, .status = 0, .type = (t), .clock = (c), \
.hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
.htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
.vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
.vscan = (vs), .flags = (f), \
.base.type = DRM_MODE_OBJECT_MODE
#define CRTC_INTERLACE_HALVE_V (1 << 0) /* halve V values for interlacing */
#define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */
#define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF
struct drm_display_mode {
/* Header */
struct list_head head;
struct drm_mode_object base;
char name[DRM_DISPLAY_MODE_LEN];
enum drm_mode_status status;
unsigned int type;
/* Proposed mode values */
int clock; /* in kHz */
int hdisplay;
int hsync_start;
int hsync_end;
int htotal;
int hskew;
int vdisplay;
int vsync_start;
int vsync_end;
int vtotal;
int vscan;
unsigned int flags;
/* Addressable image size (may be 0 for projectors, etc.) */
int width_mm;
int height_mm;
/* Actual mode we give to hw */
int crtc_clock; /* in KHz */
int crtc_hdisplay;
int crtc_hblank_start;
int crtc_hblank_end;
int crtc_hsync_start;
int crtc_hsync_end;
int crtc_htotal;
int crtc_hskew;
int crtc_vdisplay;
int crtc_vblank_start;
int crtc_vblank_end;
int crtc_vsync_start;
int crtc_vsync_end;
int crtc_vtotal;
/* Driver private mode info */
int *private;
int private_flags;
int vrefresh; /* in Hz */
int hsync; /* in kHz */
enum hdmi_picture_aspect picture_aspect_ratio;
};
/* mode specified on the command line */
struct drm_cmdline_mode {
bool specified;
bool refresh_specified;
bool bpp_specified;
int xres, yres;
int bpp;
int refresh;
bool rb;
bool interlace;
bool cvt;
bool margins;
enum drm_connector_force force;
};
/**
* drm_mode_is_stereo - check for stereo mode flags
* @mode: drm_display_mode to check
*
* Returns:
* True if the mode is one of the stereo modes (like side-by-side), false if
* not.
*/
static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode)
{
return mode->flags & DRM_MODE_FLAG_3D_MASK;
}
struct drm_connector;
struct drm_cmdline_mode;
struct drm_display_mode *drm_mode_create(struct drm_device *dev);
void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
void drm_mode_debug_printmodeline(const struct drm_display_mode *mode);
struct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
int hdisplay, int vdisplay, int vrefresh,
bool reduced, bool interlaced,
bool margins);
struct drm_display_mode *drm_gtf_mode(struct drm_device *dev,
int hdisplay, int vdisplay, int vrefresh,
bool interlaced, int margins);
struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev,
int hdisplay, int vdisplay,
int vrefresh, bool interlaced,
int margins,
int GTF_M, int GTF_2C,
int GTF_K, int GTF_2J);
void drm_display_mode_from_videomode(const struct videomode *vm,
struct drm_display_mode *dmode);
int of_get_drm_display_mode(struct device_node *np,
struct drm_display_mode *dmode,
int index);
void drm_mode_set_name(struct drm_display_mode *mode);
int drm_mode_hsync(const struct drm_display_mode *mode);
int drm_mode_vrefresh(const struct drm_display_mode *mode);
void drm_mode_set_crtcinfo(struct drm_display_mode *p,
int adjust_flags);
void drm_mode_copy(struct drm_display_mode *dst,
const struct drm_display_mode *src);
struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
const struct drm_display_mode *mode);
bool drm_mode_equal(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2);
bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
const struct drm_display_mode *mode2);
/* for use by the crtc helper probe functions */
void drm_mode_validate_size(struct drm_device *dev,
struct list_head *mode_list,
int maxX, int maxY);
void drm_mode_prune_invalid(struct drm_device *dev,
struct list_head *mode_list, bool verbose);
void drm_mode_sort(struct list_head *mode_list);
void drm_mode_connector_list_update(struct drm_connector *connector);
/* parsing cmdline modes */
bool
drm_mode_parse_command_line_for_connector(const char *mode_option,
struct drm_connector *connector,
struct drm_cmdline_mode *mode);
struct drm_display_mode *
drm_mode_create_from_cmdline_mode(struct drm_device *dev,
struct drm_cmdline_mode *cmd);
#endif /* __DRM_MODES_H__ */
...@@ -262,6 +262,18 @@ union hdmi_vendor_any_infoframe { ...@@ -262,6 +262,18 @@ union hdmi_vendor_any_infoframe {
struct hdmi_vendor_infoframe hdmi; struct hdmi_vendor_infoframe hdmi;
}; };
/**
* union hdmi_infoframe - overall union of all abstract infoframe representations
* @any: generic infoframe
* @avi: avi infoframe
* @spd: spd infoframe
* @vendor: union of all vendor infoframes
* @audio: audio infoframe
*
* This is used by the generic pack function. This works since all infoframes
* have the same header which also indicates which type of infoframe should be
* packed.
*/
union hdmi_infoframe { union hdmi_infoframe {
struct hdmi_any_infoframe any; struct hdmi_any_infoframe any;
struct hdmi_avi_infoframe avi; struct hdmi_avi_infoframe avi;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment