summaryrefslogtreecommitdiff
path: root/include/drm
diff options
context:
space:
mode:
Diffstat (limited to 'include/drm')
-rw-r--r--include/drm/bridge/ptn3460.h37
-rw-r--r--include/drm/drmP.h243
-rw-r--r--include/drm/drm_crtc.h225
-rw-r--r--include/drm/drm_crtc_helper.h6
-rw-r--r--include/drm/drm_dp_helper.h125
-rw-r--r--include/drm/drm_fb_helper.h6
-rw-r--r--include/drm/drm_gem_cma_helper.h2
-rw-r--r--include/drm/drm_mipi_dsi.h6
-rw-r--r--include/drm/drm_mm.h182
-rw-r--r--include/drm/drm_modes.h237
-rw-r--r--include/drm/drm_plane_helper.h49
-rw-r--r--include/drm/drm_vma_manager.h6
-rw-r--r--include/drm/gma_drm.h70
-rw-r--r--include/drm/ttm/ttm_bo_driver.h49
-rw-r--r--include/drm/ttm/ttm_object.h4
-rw-r--r--include/drm/ttm/ttm_placement.h3
16 files changed, 820 insertions, 430 deletions
diff --git a/include/drm/bridge/ptn3460.h b/include/drm/bridge/ptn3460.h
new file mode 100644
index 000000000000..ff62344fec6c
--- /dev/null
+++ b/include/drm/bridge/ptn3460.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DRM_BRIDGE_PTN3460_H_
+#define _DRM_BRIDGE_PTN3460_H_
+
+struct drm_device;
+struct drm_encoder;
+struct i2c_client;
+struct device_node;
+
+#if defined(CONFIG_DRM_PTN3460) || defined(CONFIG_DRM_PTN3460_MODULE)
+
+int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
+ struct i2c_client *client, struct device_node *node);
+#else
+
+static inline int ptn3460_init(struct drm_device *dev,
+ struct drm_encoder *encoder, struct i2c_client *client,
+ struct device_node *node)
+{
+ return 0;
+}
+
+#endif
+
+#endif
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 04a7f31301f8..a7c2a862b4f4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -43,6 +43,7 @@
#include <asm/current.h>
#endif /* __alpha__ */
#include <linux/kernel.h>
+#include <linux/kref.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/init.h>
@@ -87,46 +88,41 @@ struct videomode;
#include <drm/drm_hashtab.h>
#include <drm/drm_mm.h>
-#define DRM_UT_CORE 0x01
-#define DRM_UT_DRIVER 0x02
-#define DRM_UT_KMS 0x04
-#define DRM_UT_PRIME 0x08
/*
- * Three debug levels are defined.
- * drm_core, drm_driver, drm_kms
- * drm_core level can be used in the generic drm code. For example:
- * drm_ioctl, drm_mm, drm_memory
- * The macro definition of DRM_DEBUG is used.
- * DRM_DEBUG(fmt, args...)
- * The debug info by using the DRM_DEBUG can be obtained by adding
- * the boot option of "drm.debug=1".
+ * 4 debug categories are defined:
+ *
+ * CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c, drm_memory.c, ...
+ * This is the category used by the DRM_DEBUG() macro.
+ *
+ * DRIVER: Used in the vendor specific part of the driver: i915, radeon, ...
+ * This is the category used by the DRM_DEBUG_DRIVER() macro.
+ *
+ * KMS: used in the modesetting code.
+ * This is the category used by the DRM_DEBUG_KMS() macro.
+ *
+ * PRIME: used in the prime code.
+ * This is the category used by the DRM_DEBUG_PRIME() macro.
*
- * drm_driver level can be used in the specific drm driver. It is used
- * to add the debug info related with the drm driver. For example:
- * i915_drv, i915_dma, i915_gem, radeon_drv,
- * The macro definition of DRM_DEBUG_DRIVER can be used.
- * DRM_DEBUG_DRIVER(fmt, args...)
- * The debug info by using the DRM_DEBUG_DRIVER can be obtained by
- * adding the boot option of "drm.debug=0x02"
+ * Enabling verbose debug messages is done through the drm.debug parameter,
+ * each category being enabled by a bit.
*
- * drm_kms level can be used in the KMS code related with specific drm driver.
- * It is used to add the debug info related with KMS mode. For example:
- * the connector/crtc ,
- * The macro definition of DRM_DEBUG_KMS can be used.
- * DRM_DEBUG_KMS(fmt, args...)
- * The debug info by using the DRM_DEBUG_KMS can be obtained by
- * adding the boot option of "drm.debug=0x04"
+ * drm.debug=0x1 will enable CORE messages
+ * drm.debug=0x2 will enable DRIVER messages
+ * drm.debug=0x3 will enable CORE and DRIVER messages
+ * ...
+ * drm.debug=0xf will enable all messages
*
- * If we add the boot option of "drm.debug=0x06", we can get the debug info by
- * using the DRM_DEBUG_KMS and DRM_DEBUG_DRIVER.
- * If we add the boot option of "drm.debug=0x05", we can get the debug info by
- * using the DRM_DEBUG_KMS and DRM_DEBUG.
+ * An interesting feature is that it's possible to enable verbose logging at
+ * run-time by echoing the debug value in its sysfs node:
+ * # echo 0xf > /sys/module/drm/parameters/debug
*/
+#define DRM_UT_CORE 0x01
+#define DRM_UT_DRIVER 0x02
+#define DRM_UT_KMS 0x04
+#define DRM_UT_PRIME 0x08
-extern __printf(4, 5)
-void drm_ut_debug_printk(unsigned int request_level,
- const char *prefix,
- const char *function_name,
+extern __printf(2, 3)
+void drm_ut_debug_printk(const char *function_name,
const char *format, ...);
extern __printf(2, 3)
int drm_err(const char *func, const char *format, ...);
@@ -211,55 +207,30 @@ int drm_err(const char *func, const char *format, ...);
#if DRM_DEBUG_CODE
#define DRM_DEBUG(fmt, args...) \
do { \
- drm_ut_debug_printk(DRM_UT_CORE, DRM_NAME, \
- __func__, fmt, ##args); \
+ if (unlikely(drm_debug & DRM_UT_CORE)) \
+ drm_ut_debug_printk(__func__, fmt, ##args); \
} while (0)
#define DRM_DEBUG_DRIVER(fmt, args...) \
do { \
- drm_ut_debug_printk(DRM_UT_DRIVER, DRM_NAME, \
- __func__, fmt, ##args); \
+ if (unlikely(drm_debug & DRM_UT_DRIVER)) \
+ drm_ut_debug_printk(__func__, fmt, ##args); \
} while (0)
-#define DRM_DEBUG_KMS(fmt, args...) \
+#define DRM_DEBUG_KMS(fmt, args...) \
do { \
- drm_ut_debug_printk(DRM_UT_KMS, DRM_NAME, \
- __func__, fmt, ##args); \
+ if (unlikely(drm_debug & DRM_UT_KMS)) \
+ drm_ut_debug_printk(__func__, fmt, ##args); \
} while (0)
#define DRM_DEBUG_PRIME(fmt, args...) \
do { \
- drm_ut_debug_printk(DRM_UT_PRIME, DRM_NAME, \
- __func__, fmt, ##args); \
- } while (0)
-#define DRM_LOG(fmt, args...) \
- do { \
- drm_ut_debug_printk(DRM_UT_CORE, NULL, \
- NULL, fmt, ##args); \
- } while (0)
-#define DRM_LOG_KMS(fmt, args...) \
- do { \
- drm_ut_debug_printk(DRM_UT_KMS, NULL, \
- NULL, fmt, ##args); \
- } while (0)
-#define DRM_LOG_MODE(fmt, args...) \
- do { \
- drm_ut_debug_printk(DRM_UT_MODE, NULL, \
- NULL, fmt, ##args); \
- } while (0)
-#define DRM_LOG_DRIVER(fmt, args...) \
- do { \
- drm_ut_debug_printk(DRM_UT_DRIVER, NULL, \
- NULL, fmt, ##args); \
+ if (unlikely(drm_debug & DRM_UT_PRIME)) \
+ drm_ut_debug_printk(__func__, fmt, ##args); \
} while (0)
#else
#define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0)
#define DRM_DEBUG_KMS(fmt, args...) do { } while (0)
#define DRM_DEBUG_PRIME(fmt, args...) do { } while (0)
#define DRM_DEBUG(fmt, arg...) do { } while (0)
-#define DRM_LOG(fmt, arg...) do { } while (0)
-#define DRM_LOG_KMS(fmt, args...) do { } while (0)
-#define DRM_LOG_MODE(fmt, arg...) do { } while (0)
-#define DRM_LOG_DRIVER(fmt, arg...) do { } while (0)
-
#endif
/*@}*/
@@ -434,9 +405,15 @@ struct drm_prime_file_private {
struct drm_file {
unsigned always_authenticated :1;
unsigned authenticated :1;
- unsigned is_master :1; /* this file private is a master for a minor */
+ /* Whether we're master for a minor. Protected by master_mutex */
+ unsigned is_master :1;
/* true when the client has asked us to expose stereo 3D mode flags */
unsigned stereo_allowed :1;
+ /*
+ * true if client understands CRTC primary planes and cursor planes
+ * in the plane list
+ */
+ unsigned universal_planes:1;
struct pid *pid;
kuid_t uid;
@@ -713,29 +690,29 @@ struct drm_gem_object {
#include <drm/drm_crtc.h>
-/* per-master structure */
+/**
+ * struct drm_master - drm master structure
+ *
+ * @refcount: Refcount for this master object.
+ * @minor: Link back to minor char device we are master for. Immutable.
+ * @unique: Unique identifier: e.g. busid. Protected by drm_global_mutex.
+ * @unique_len: Length of unique field. Protected by drm_global_mutex.
+ * @unique_size: Amount allocated. Protected by drm_global_mutex.
+ * @magiclist: Hash of used authentication tokens. Protected by struct_mutex.
+ * @magicfree: List of used authentication tokens. Protected by struct_mutex.
+ * @lock: DRI lock information.
+ * @driver_priv: Pointer to driver-private information.
+ */
struct drm_master {
-
- struct kref refcount; /* refcount for this master */
-
- struct list_head head; /**< each minor contains a list of masters */
- struct drm_minor *minor; /**< link back to minor we are a master for */
-
- char *unique; /**< Unique identifier: e.g., busid */
- int unique_len; /**< Length of unique field */
- int unique_size; /**< amount allocated */
-
- int blocked; /**< Blocked due to VC switch? */
-
- /** \name Authentication */
- /*@{ */
+ struct kref refcount;
+ struct drm_minor *minor;
+ char *unique;
+ int unique_len;
+ int unique_size;
struct drm_open_hash magiclist;
struct list_head magicfree;
- /*@} */
-
- struct drm_lock_data lock; /**< Information on hardware lock */
-
- void *driver_priv; /**< Private structure for driver to use */
+ struct drm_lock_data lock;
+ void *driver_priv;
};
/* Size of ringbuffer for vblank timestamps. Just double-buffer
@@ -1008,10 +985,12 @@ struct drm_driver {
struct list_head legacy_dev_list;
};
-#define DRM_MINOR_UNASSIGNED 0
-#define DRM_MINOR_LEGACY 1
-#define DRM_MINOR_CONTROL 2
-#define DRM_MINOR_RENDER 3
+enum drm_minor_type {
+ DRM_MINOR_LEGACY,
+ DRM_MINOR_CONTROL,
+ DRM_MINOR_RENDER,
+ DRM_MINOR_CNT,
+};
/**
* Info file list entry. This structure represents a debugfs or proc file to
@@ -1040,7 +1019,6 @@ struct drm_info_node {
struct drm_minor {
int index; /**< Minor device number */
int type; /**< Control or render */
- dev_t device; /**< Device number for mknod */
struct device *kdev; /**< Linux device */
struct drm_device *dev;
@@ -1049,26 +1027,11 @@ struct drm_minor {
struct list_head debugfs_list;
struct mutex debugfs_lock; /* Protects debugfs_list. */
- struct drm_master *master; /* currently active master for this node */
- struct list_head master_list;
+ /* currently active master for this node. Protected by master_mutex */
+ struct drm_master *master;
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_event base;
@@ -1098,10 +1061,24 @@ struct drm_device {
char *devname; /**< For /proc/interrupts */
int if_version; /**< Highest interface version set */
+ /** \name Lifetime Management */
+ /*@{ */
+ struct kref ref; /**< Object ref-count */
+ struct device *dev; /**< Device structure of bus-device */
+ struct drm_driver *driver; /**< DRM driver managing the device */
+ void *dev_private; /**< DRM driver private data */
+ struct drm_minor *control; /**< Control node */
+ struct drm_minor *primary; /**< Primary node */
+ struct drm_minor *render; /**< Render node */
+ atomic_t unplugged; /**< Flag whether dev is dead */
+ struct inode *anon_inode; /**< inode for private address-space */
+ /*@} */
+
/** \name Locks */
/*@{ */
spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */
struct mutex struct_mutex; /**< For others */
+ struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */
/*@} */
/** \name Usage Counters */
@@ -1171,7 +1148,6 @@ struct drm_device {
struct drm_agp_head *agp; /**< AGP data */
- struct device *dev; /**< Device structure */
struct pci_dev *pdev; /**< PCI device structure */
#ifdef __alpha__
struct pci_controller *hose;
@@ -1182,17 +1158,11 @@ struct drm_device {
struct drm_sg_mem *sg; /**< Scatter gather memory */
unsigned int num_crtcs; /**< Number of CRTCs on this device */
- void *dev_private; /**< device private data */
- struct address_space *dev_mapping;
struct drm_sigdata sigdata; /**< For block_all_signals */
sigset_t sigmask;
- struct drm_driver *driver;
struct drm_local_map *agp_buffer_map;
unsigned int agp_buffer_token;
- struct drm_minor *control; /**< Control node for card */
- struct drm_minor *primary; /**< render type primary screen head */
- struct drm_minor *render; /**< render node for card */
struct drm_mode_config mode_config; /**< Current mode config */
@@ -1203,8 +1173,6 @@ struct drm_device {
struct drm_vma_offset_manager *vma_offset_manager;
/*@} */
int switch_power_state;
-
- atomic_t unplugged; /* device has been unplugged or gone away */
};
#define DRM_SWITCH_POWER_ON 0
@@ -1241,11 +1209,21 @@ static inline bool drm_modeset_is_locked(struct drm_device *dev)
return mutex_is_locked(&dev->mode_config.mutex);
}
-static inline bool drm_is_render_client(struct drm_file *file_priv)
+static inline bool drm_is_render_client(const struct drm_file *file_priv)
{
return file_priv->minor->type == DRM_MINOR_RENDER;
}
+static inline bool drm_is_control_client(const struct drm_file *file_priv)
+{
+ return file_priv->minor->type == DRM_MINOR_CONTROL;
+}
+
+static inline bool drm_is_primary_client(const struct drm_file *file_priv)
+{
+ return file_priv->minor->type == DRM_MINOR_LEGACY;
+}
+
/******************************************************************/
/** \name Internal function definitions */
/*@{*/
@@ -1256,6 +1234,7 @@ extern long drm_ioctl(struct file *filp,
extern long drm_compat_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_lastclose(struct drm_device *dev);
+extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
/* Device support (drm_fops.h) */
extern struct mutex drm_global_mutex;
@@ -1411,20 +1390,6 @@ extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
extern void drm_calc_timestamping_constants(struct drm_crtc *crtc,
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 */
extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
@@ -1449,6 +1414,7 @@ extern void drm_put_dev(struct drm_device *dev);
extern void drm_unplug_dev(struct drm_device *dev);
extern unsigned int drm_debug;
extern unsigned int drm_rnodes;
+extern unsigned int drm_universal_planes;
extern unsigned int drm_vblank_offdelay;
extern unsigned int drm_timestamp_precision;
@@ -1661,9 +1627,14 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map)
struct drm_device *drm_dev_alloc(struct drm_driver *driver,
struct device *parent);
-void drm_dev_free(struct drm_device *dev);
+void drm_dev_ref(struct drm_device *dev);
+void drm_dev_unref(struct drm_device *dev);
int drm_dev_register(struct drm_device *dev, unsigned long flags);
void drm_dev_unregister(struct drm_device *dev);
+
+struct drm_minor *drm_minor_acquire(unsigned int minor_id);
+void drm_minor_release(struct drm_minor *minor);
+
/*@}*/
/* PCI section */
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 8f3dee097579..e55fccbe7c42 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -32,7 +32,6 @@
#include <linux/fb.h>
#include <linux/hdmi.h>
#include <drm/drm_mode.h>
-
#include <drm/drm_fourcc.h>
struct drm_device;
@@ -65,130 +64,14 @@ struct drm_object_properties {
uint64_t values[DRM_OBJECT_MAX_PROPERTY];
};
-/*
- * 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_size;
- int *private;
- int private_flags;
-
- int vrefresh; /* in Hz */
- int hsync; /* in kHz */
- enum hdmi_picture_aspect picture_aspect_ratio;
+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 */
};
-static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode)
-{
- return mode->flags & DRM_MODE_FLAG_3D_MASK;
-}
+#include <drm/drm_modes.h>
enum drm_connector_status {
connector_status_connected = 1,
@@ -387,6 +270,8 @@ struct drm_crtc_funcs {
* @dev: parent DRM device
* @head: list management
* @base: base KMS object for ID tracking etc.
+ * @primary: primary plane for this CRTC
+ * @cursor: cursor plane for this CRTC
* @enabled: is this CRTC enabled?
* @mode: current mode timings
* @hwmode: mode timings as programmed to hw regs
@@ -422,8 +307,9 @@ struct drm_crtc {
struct drm_mode_object base;
- /* framebuffer the connector is currently bound to */
- struct drm_framebuffer *fb;
+ /* primary and cursor planes for CRTC */
+ struct drm_plane *primary;
+ struct drm_plane *cursor;
/* Temporary tracking of the old fb while a modeset is ongoing. Used
* by drm_mode_set_config_internal to implement correct refcounting. */
@@ -540,13 +426,6 @@ struct drm_encoder {
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 */
/* hot plug detectable */
#define DRM_CONNECTOR_POLL_HPD (1 << 0)
@@ -665,6 +544,12 @@ struct drm_plane_funcs {
struct drm_property *property, uint64_t val);
};
+enum drm_plane_type {
+ DRM_PLANE_TYPE_OVERLAY,
+ DRM_PLANE_TYPE_PRIMARY,
+ DRM_PLANE_TYPE_CURSOR,
+};
+
/**
* drm_plane - central DRM plane control structure
* @dev: DRM device this plane belongs to
@@ -677,6 +562,7 @@ struct drm_plane_funcs {
* @fb: currently bound fb
* @funcs: helper functions
* @properties: property tracking for this plane
+ * @type: type of plane (overlay, primary, cursor)
*/
struct drm_plane {
struct drm_device *dev;
@@ -694,6 +580,8 @@ struct drm_plane {
const struct drm_plane_funcs *funcs;
struct drm_object_properties properties;
+
+ enum drm_plane_type type;
};
/**
@@ -856,7 +744,15 @@ struct drm_mode_config {
struct list_head bridge_list;
int num_encoder;
struct list_head encoder_list;
- int num_plane;
+
+ /*
+ * Track # of overlay planes separately from # of total planes. By
+ * default we only advertise overlay planes to userspace; if userspace
+ * sets the "universal plane" capability bit, we'll go ahead and
+ * expose all planes.
+ */
+ int num_overlay_plane;
+ int num_total_plane;
struct list_head plane_list;
int num_crtc;
@@ -878,6 +774,7 @@ struct drm_mode_config {
struct list_head property_blob_list;
struct drm_property *edid_property;
struct drm_property *dpms_property;
+ struct drm_property *plane_type_property;
/* DVI-I properties */
struct drm_property *dvi_i_subconnector_property;
@@ -930,6 +827,11 @@ extern void drm_modeset_lock_all(struct drm_device *dev);
extern void drm_modeset_unlock_all(struct drm_device *dev);
extern void drm_warn_on_modeset_not_all_locked(struct drm_device *dev);
+extern int drm_crtc_init_with_planes(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ struct drm_plane *primary,
+ void *cursor,
+ const struct drm_crtc_funcs *funcs);
extern int drm_crtc_init(struct drm_device *dev,
struct drm_crtc *crtc,
const struct drm_crtc_funcs *funcs);
@@ -981,19 +883,31 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
return !!(encoder->possible_crtcs & drm_crtc_mask(crtc));
}
+extern int drm_universal_plane_init(struct drm_device *dev,
+ struct drm_plane *plane,
+ unsigned long possible_crtcs,
+ const struct drm_plane_funcs *funcs,
+ const uint32_t *formats,
+ uint32_t format_count,
+ enum drm_plane_type type);
extern int drm_plane_init(struct drm_device *dev,
struct drm_plane *plane,
unsigned long possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats, uint32_t format_count,
- bool priv);
+ bool is_primary);
extern void drm_plane_cleanup(struct drm_plane *plane);
extern void drm_plane_force_disable(struct drm_plane *plane);
+extern int drm_crtc_check_viewport(const struct drm_crtc *crtc,
+ int x, int y,
+ const struct drm_display_mode *mode,
+ const struct drm_framebuffer *fb);
extern void drm_encoder_cleanup(struct drm_encoder *encoder);
extern const char *drm_get_connector_name(const struct drm_connector *connector);
extern const char *drm_get_connector_status_name(enum drm_connector_status status);
+extern const char *drm_get_subpixel_order_name(enum subpixel_order order);
extern const char *drm_get_dpms_name(int val);
extern const char *drm_get_dvi_i_subconnector_name(int val);
extern const char *drm_get_dvi_i_select_name(int val);
@@ -1006,34 +920,10 @@ extern struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter);
extern struct edid *drm_edid_duplicate(const 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_reset(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,
struct edid *edid);
extern int drm_object_property_set_value(struct drm_mode_object *obj,
@@ -1081,8 +971,6 @@ extern const char *drm_get_encoder_name(const struct drm_encoder *encoder);
extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
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,
int gamma_size);
extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
@@ -1137,16 +1025,6 @@ extern bool drm_detect_monitor_audio(struct edid *edid);
extern bool drm_rgb_quant_range_selectable(struct edid *edid);
extern int drm_mode_page_flip_ioctl(struct drm_device *dev,
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,
int hdisplay, int vdisplay);
extern void drm_set_preferred_mode(struct drm_connector *connector,
@@ -1195,4 +1073,9 @@ static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
return mo ? obj_to_encoder(mo) : NULL;
}
+/* Plane list iterator for legacy (overlay only) planes. */
+#define drm_for_each_legacy_plane(plane, planelist) \
+ list_for_each_entry(plane, planelist, head) \
+ if (plane->type == DRM_PLANE_TYPE_OVERLAY)
+
#endif /* __DRM_CRTC_H__ */
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index b1388b5fe7ac..0bb34ca2ad2b 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -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 int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
- struct drm_mode_fb_cmd2 *mode_cmd);
+extern void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
+ struct drm_mode_fb_cmd2 *mode_cmd);
static inline void drm_crtc_helper_add(struct drm_crtc *crtc,
const struct drm_crtc_helper_funcs *funcs)
@@ -160,7 +160,7 @@ static inline void drm_connector_helper_add(struct drm_connector *connector,
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_fini(struct drm_device *dev);
extern bool drm_helper_hpd_irq_event(struct drm_device *dev);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 1d09050a8c00..b4f58914bf7d 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -279,11 +279,21 @@
#define DP_TEST_PATTERN 0x221
+#define DP_TEST_CRC_R_CR 0x240
+#define DP_TEST_CRC_G_Y 0x242
+#define DP_TEST_CRC_B_CB 0x244
+
+#define DP_TEST_SINK_MISC 0x246
+#define DP_TEST_CRC_SUPPORTED (1 << 5)
+
#define DP_TEST_RESPONSE 0x260
# define DP_TEST_ACK (1 << 0)
# define DP_TEST_NAK (1 << 1)
# define DP_TEST_EDID_CHECKSUM_WRITE (1 << 2)
+#define DP_TEST_SINK 0x270
+#define DP_TEST_SINK_START (1 << 0)
+
#define DP_SOURCE_OUI 0x300
#define DP_SINK_OUI 0x400
#define DP_BRANCH_OUI 0x500
@@ -291,6 +301,7 @@
#define DP_SET_POWER 0x600
# define DP_SET_POWER_D0 0x1
# define DP_SET_POWER_D3 0x2
+# define DP_SET_POWER_MASK 0x3
#define DP_PSR_ERROR_STATUS 0x2006 /* XXX 1.2? */
# define DP_PSR_LINK_CRC_ERROR (1 << 0)
@@ -398,4 +409,118 @@ drm_dp_enhanced_frame_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
(dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP);
}
+/*
+ * DisplayPort AUX channel
+ */
+
+/**
+ * struct drm_dp_aux_msg - DisplayPort AUX channel transaction
+ * @address: address of the (first) register to access
+ * @request: contains the type of transaction (see DP_AUX_* macros)
+ * @reply: upon completion, contains the reply type of the transaction
+ * @buffer: pointer to a transmission or reception buffer
+ * @size: size of @buffer
+ */
+struct drm_dp_aux_msg {
+ unsigned int address;
+ u8 request;
+ u8 reply;
+ void *buffer;
+ size_t size;
+};
+
+/**
+ * struct drm_dp_aux - DisplayPort AUX channel
+ * @ddc: I2C adapter that can be used for I2C-over-AUX communication
+ * @dev: pointer to struct device that is the parent for this AUX channel
+ * @transfer: transfers a message representing a single AUX transaction
+ *
+ * The .dev field should be set to a pointer to the device that implements
+ * the AUX channel.
+ *
+ * The .name field may be used to specify the name of the I2C adapter. If set to
+ * NULL, dev_name() of .dev will be used.
+ *
+ * Drivers provide a hardware-specific implementation of how transactions
+ * are executed via the .transfer() function. A pointer to a drm_dp_aux_msg
+ * structure describing the transaction is passed into this function. Upon
+ * success, the implementation should return the number of payload bytes
+ * that were transferred, or a negative error-code on failure. Helpers
+ * propagate errors from the .transfer() function, with the exception of
+ * the -EBUSY error, which causes a transaction to be retried. On a short,
+ * helpers will return -EPROTO to make it simpler to check for failure.
+ *
+ * An AUX channel can also be used to transport I2C messages to a sink. A
+ * typical application of that is to access an EDID that's present in the
+ * sink device. The .transfer() function can also be used to execute such
+ * transactions. The drm_dp_aux_register_i2c_bus() function registers an
+ * I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers
+ * should call drm_dp_aux_unregister_i2c_bus() to remove the I2C adapter.
+ */
+struct drm_dp_aux {
+ const char *name;
+ struct i2c_adapter ddc;
+ struct device *dev;
+
+ ssize_t (*transfer)(struct drm_dp_aux *aux,
+ struct drm_dp_aux_msg *msg);
+};
+
+ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
+ void *buffer, size_t size);
+ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
+ void *buffer, size_t size);
+
+/**
+ * drm_dp_dpcd_readb() - read a single byte from the DPCD
+ * @aux: DisplayPort AUX channel
+ * @offset: address of the register to read
+ * @valuep: location where the value of the register will be stored
+ *
+ * Returns the number of bytes transferred (1) on success, or a negative
+ * error code on failure.
+ */
+static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux,
+ unsigned int offset, u8 *valuep)
+{
+ return drm_dp_dpcd_read(aux, offset, valuep, 1);
+}
+
+/**
+ * drm_dp_dpcd_writeb() - write a single byte to the DPCD
+ * @aux: DisplayPort AUX channel
+ * @offset: address of the register to write
+ * @value: value to write to the register
+ *
+ * Returns the number of bytes transferred (1) on success, or a negative
+ * error code on failure.
+ */
+static inline ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux,
+ unsigned int offset, u8 value)
+{
+ return drm_dp_dpcd_write(aux, offset, &value, 1);
+}
+
+int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
+ u8 status[DP_LINK_STATUS_SIZE]);
+
+/*
+ * DisplayPort link
+ */
+#define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
+
+struct drm_dp_link {
+ unsigned char revision;
+ unsigned int rate;
+ unsigned int num_lanes;
+ unsigned long capabilities;
+};
+
+int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link);
+int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link);
+int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link);
+
+int drm_dp_aux_register_i2c_bus(struct drm_dp_aux *aux);
+void drm_dp_aux_unregister_i2c_bus(struct drm_dp_aux *aux);
+
#endif /* _DRM_DP_HELPER_H_ */
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 0145b948b147..6e622f7d481d 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -121,5 +121,11 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
int drm_fb_helper_debug_enter(struct fb_info *info);
int drm_fb_helper_debug_leave(struct fb_info *info);
+struct drm_display_mode *
+drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector,
+ int width, int height);
+struct drm_display_mode *
+drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
+ int width, int height);
#endif
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
index 89b4d7db1ebd..2a3cea91606d 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
@@ -1,6 +1,8 @@
#ifndef __DRM_GEM_CMA_HELPER_H__
#define __DRM_GEM_CMA_HELPER_H__
+#include <drm/drmP.h>
+
struct drm_gem_cma_object {
struct drm_gem_object base;
dma_addr_t paddr;
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index d32628acdd90..7209df15a3cd 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -17,6 +17,11 @@
struct mipi_dsi_host;
struct mipi_dsi_device;
+/* request ACK from peripheral */
+#define MIPI_DSI_MSG_REQ_ACK BIT(0)
+/* use Low Power Mode to transmit message */
+#define MIPI_DSI_MSG_USE_LPM BIT(1)
+
/**
* struct mipi_dsi_msg - read/write DSI buffer
* @channel: virtual channel id
@@ -29,6 +34,7 @@ struct mipi_dsi_device;
struct mipi_dsi_msg {
u8 channel;
u8 type;
+ u16 flags;
size_t tx_len;
const void *tx_buf;
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index cba67865d18f..a24addfdfcec 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -47,8 +47,17 @@
enum drm_mm_search_flags {
DRM_MM_SEARCH_DEFAULT = 0,
DRM_MM_SEARCH_BEST = 1 << 0,
+ DRM_MM_SEARCH_BELOW = 1 << 1,
};
+enum drm_mm_allocator_flags {
+ DRM_MM_CREATE_DEFAULT = 0,
+ DRM_MM_CREATE_TOP = 1 << 0,
+};
+
+#define DRM_MM_BOTTOMUP DRM_MM_SEARCH_DEFAULT, DRM_MM_CREATE_DEFAULT
+#define DRM_MM_TOPDOWN DRM_MM_SEARCH_BELOW, DRM_MM_CREATE_TOP
+
struct drm_mm_node {
struct list_head node_list;
struct list_head hole_stack;
@@ -85,11 +94,31 @@ struct drm_mm {
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)
{
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)
{
return mm->hole_stack.next;
@@ -100,6 +129,17 @@ static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_no
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)
{
BUG_ON(!hole_node->hole_follows);
@@ -112,18 +152,52 @@ static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node
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)
{
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, \
&(mm)->head_node.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
- * macro sane.
+/**
+ * drm_mm_for_each_hole - iterator to walk over all holes
+ * @entry: drm_mm_node used internally to track progress
+ * @mm: drm_mm allocator to walk
+ * @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.
+ *
+ * The __drm_mm_for_each_hole version is similar, but with added support for
+ * going backwards.
*/
#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); \
@@ -133,34 +207,79 @@ static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
1 : 0; \
entry = list_entry(entry->hole_stack.next, struct drm_mm_node, hole_stack))
+#define __drm_mm_for_each_hole(entry, mm, hole_start, hole_end, backwards) \
+ for (entry = list_entry((backwards) ? (mm)->hole_stack.prev : (mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
+ &entry->hole_stack != &(mm)->hole_stack ? \
+ hole_start = drm_mm_hole_node_start(entry), \
+ hole_end = drm_mm_hole_node_end(entry), \
+ 1 : 0; \
+ entry = list_entry((backwards) ? entry->hole_stack.prev : entry->hole_stack.next, struct drm_mm_node, hole_stack))
+
/*
* Basic range manager support (drm_mm.c)
*/
-extern 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,
- struct drm_mm_node *node,
- unsigned long size,
- unsigned alignment,
- unsigned long color,
- enum drm_mm_search_flags flags);
+int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node);
+
+int drm_mm_insert_node_generic(struct drm_mm *mm,
+ struct drm_mm_node *node,
+ unsigned long size,
+ unsigned alignment,
+ unsigned long color,
+ enum drm_mm_search_flags sflags,
+ enum drm_mm_allocator_flags aflags);
+/**
+ * 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,
struct drm_mm_node *node,
unsigned long size,
unsigned alignment,
enum drm_mm_search_flags flags)
{
- return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags);
+ return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags,
+ DRM_MM_CREATE_DEFAULT);
}
-extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
- struct drm_mm_node *node,
- unsigned long size,
- unsigned alignment,
- unsigned long color,
- unsigned long start,
- unsigned long end,
- enum drm_mm_search_flags flags);
+int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
+ struct drm_mm_node *node,
+ unsigned long size,
+ unsigned alignment,
+ unsigned long color,
+ unsigned long start,
+ unsigned long end,
+ enum drm_mm_search_flags sflags,
+ enum drm_mm_allocator_flags aflags);
+/**
+ * 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,
struct drm_mm_node *node,
unsigned long size,
@@ -170,16 +289,17 @@ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
enum drm_mm_search_flags flags)
{
return drm_mm_insert_node_in_range_generic(mm, node, size, alignment,
- 0, start, end, flags);
+ 0, start, end, flags,
+ DRM_MM_CREATE_DEFAULT);
}
-extern 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);
-extern void drm_mm_init(struct drm_mm *mm,
- unsigned long start,
- unsigned long size);
-extern void drm_mm_takedown(struct drm_mm *mm);
-extern int drm_mm_clean(struct drm_mm *mm);
+void drm_mm_remove_node(struct drm_mm_node *node);
+void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
+void drm_mm_init(struct drm_mm *mm,
+ unsigned long start,
+ unsigned long size);
+void drm_mm_takedown(struct drm_mm *mm);
+bool drm_mm_clean(struct drm_mm *mm);
void drm_mm_init_scan(struct drm_mm *mm,
unsigned long size,
@@ -191,10 +311,10 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm,
unsigned long color,
unsigned long start,
unsigned long end);
-int 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_add_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
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
#endif
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
new file mode 100644
index 000000000000..2dbbf9976669
--- /dev/null
+++ b/include/drm/drm_modes.h
@@ -0,0 +1,237 @@
+/*
+ * 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__ */
diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h
new file mode 100644
index 000000000000..09824becee3e
--- /dev/null
+++ b/include/drm/drm_plane_helper.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011-2013 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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_PLANE_HELPER_H
+#define DRM_PLANE_HELPER_H
+
+/**
+ * DOC: plane helpers
+ *
+ * Helper functions to assist with creation and handling of CRTC primary
+ * planes.
+ */
+
+extern int drm_primary_helper_update(struct drm_plane *plane,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h);
+extern int drm_primary_helper_disable(struct drm_plane *plane);
+extern void drm_primary_helper_destroy(struct drm_plane *plane);
+extern const struct drm_plane_funcs drm_primary_helper_funcs;
+extern struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev,
+ uint32_t *formats,
+ int num_formats);
+
+
+#endif
diff --git a/include/drm/drm_vma_manager.h b/include/drm/drm_vma_manager.h
index c18a593d1744..8cd402c73a5f 100644
--- a/include/drm/drm_vma_manager.h
+++ b/include/drm/drm_vma_manager.h
@@ -221,8 +221,8 @@ static inline __u64 drm_vma_node_offset_addr(struct drm_vma_offset_node *node)
* @file_mapping: Address space to unmap @node from
*
* Unmap all userspace mappings for a given offset node. The mappings must be
- * associated with the @file_mapping address-space. If no offset exists or
- * the address-space is invalid, nothing is done.
+ * associated with the @file_mapping address-space. If no offset exists
+ * nothing is done.
*
* This call is unlocked. The caller must guarantee that drm_vma_offset_remove()
* is not called on this node concurrently.
@@ -230,7 +230,7 @@ static inline __u64 drm_vma_node_offset_addr(struct drm_vma_offset_node *node)
static inline void drm_vma_node_unmap(struct drm_vma_offset_node *node,
struct address_space *file_mapping)
{
- if (file_mapping && drm_vma_node_has_offset(node))
+ if (drm_vma_node_has_offset(node))
unmap_mapping_range(file_mapping,
drm_vma_node_offset_addr(node),
drm_vma_node_size(node) << PAGE_SHIFT, 1);
diff --git a/include/drm/gma_drm.h b/include/drm/gma_drm.h
index 884613ee00ad..87ac5e6ca551 100644
--- a/include/drm/gma_drm.h
+++ b/include/drm/gma_drm.h
@@ -19,73 +19,7 @@
*
**************************************************************************/
-#ifndef _PSB_DRM_H_
-#define _PSB_DRM_H_
-
-/*
- * Manage the LUT for an output
- */
-struct drm_psb_dpst_lut_arg {
- uint8_t lut[256];
- int output_id;
-};
-
-/*
- * Validate modes
- */
-struct drm_psb_mode_operation_arg {
- u32 obj_id;
- u16 operation;
- struct drm_mode_modeinfo mode;
- u64 data;
-};
-
-/*
- * Query the stolen memory for smarter management of
- * memory by the server
- */
-struct drm_psb_stolen_memory_arg {
- u32 base;
- u32 size;
-};
-
-struct drm_psb_get_pipe_from_crtc_id_arg {
- /** ID of CRTC being requested **/
- u32 crtc_id;
- /** pipe of requested CRTC **/
- u32 pipe;
-};
-
-struct drm_psb_gem_create {
- __u64 size;
- __u32 handle;
- __u32 flags;
-#define GMA_GEM_CREATE_STOLEN 1 /* Stolen memory can be used */
-};
-
-struct drm_psb_gem_mmap {
- __u32 handle;
- __u32 pad;
- /**
- * Fake offset to use for subsequent mmap call
- *
- * This is a fixed-size type for 32/64 compatibility.
- */
- __u64 offset;
-};
-
-/* Controlling the kernel modesetting buffers */
-
-#define DRM_GMA_GEM_CREATE 0x00 /* Create a GEM object */
-#define DRM_GMA_GEM_MMAP 0x01 /* Map GEM memory */
-#define DRM_GMA_STOLEN_MEMORY 0x02 /* Report stolen memory */
-#define DRM_GMA_2D_OP 0x03 /* Will be merged later */
-#define DRM_GMA_GAMMA 0x04 /* Set gamma table */
-#define DRM_GMA_ADB 0x05 /* Get backlight */
-#define DRM_GMA_DPST_BL 0x06 /* Set backlight */
-#define DRM_GMA_MODE_OPERATION 0x07 /* Mode validation/DC set */
-#define PSB_MODE_OPERATION_MODE_VALID 0x01
-#define DRM_GMA_GET_PIPE_FROM_CRTC_ID 0x08 /* CRTC to physical pipe# */
-
+#ifndef _GMA_DRM_H_
+#define _GMA_DRM_H_
#endif
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 32d34ebf0706..a5183da3ef92 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -747,6 +747,7 @@ extern int ttm_bo_device_release(struct ttm_bo_device *bdev);
* @bdev: A pointer to a struct ttm_bo_device to initialize.
* @glob: A pointer to an initialized struct ttm_bo_global.
* @driver: A pointer to a struct ttm_bo_driver set up by the caller.
+ * @mapping: The address space to use for this bo.
* @file_page_offset: Offset into the device address space that is available
* for buffer data. This ensures compatibility with other users of the
* address space.
@@ -758,6 +759,7 @@ extern int ttm_bo_device_release(struct ttm_bo_device *bdev);
extern int ttm_bo_device_init(struct ttm_bo_device *bdev,
struct ttm_bo_global *glob,
struct ttm_bo_driver *driver,
+ struct address_space *mapping,
uint64_t file_page_offset, bool need_dma32);
/**
@@ -786,7 +788,7 @@ extern void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo);
extern void ttm_bo_add_to_lru(struct ttm_buffer_object *bo);
/**
- * ttm_bo_reserve_nolru:
+ * __ttm_bo_reserve:
*
* @bo: A pointer to a struct ttm_buffer_object.
* @interruptible: Sleep interruptible if waiting.
@@ -807,10 +809,10 @@ extern void ttm_bo_add_to_lru(struct ttm_buffer_object *bo);
* -EALREADY: Bo already reserved using @ticket. This error code will only
* be returned if @use_ticket is set to true.
*/
-static inline int ttm_bo_reserve_nolru(struct ttm_buffer_object *bo,
- bool interruptible,
- bool no_wait, bool use_ticket,
- struct ww_acquire_ctx *ticket)
+static inline int __ttm_bo_reserve(struct ttm_buffer_object *bo,
+ bool interruptible,
+ bool no_wait, bool use_ticket,
+ struct ww_acquire_ctx *ticket)
{
int ret = 0;
@@ -886,8 +888,7 @@ static inline int ttm_bo_reserve(struct ttm_buffer_object *bo,
WARN_ON(!atomic_read(&bo->kref.refcount));
- ret = ttm_bo_reserve_nolru(bo, interruptible, no_wait, use_ticket,
- ticket);
+ ret = __ttm_bo_reserve(bo, interruptible, no_wait, use_ticket, ticket);
if (likely(ret == 0))
ttm_bo_del_sub_from_lru(bo);
@@ -927,20 +928,14 @@ static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
}
/**
- * ttm_bo_unreserve_ticket
+ * __ttm_bo_unreserve
* @bo: A pointer to a struct ttm_buffer_object.
- * @ticket: ww_acquire_ctx used for reserving
*
- * Unreserve a previous reservation of @bo made with @ticket.
+ * Unreserve a previous reservation of @bo where the buffer object is
+ * already on lru lists.
*/
-static inline void ttm_bo_unreserve_ticket(struct ttm_buffer_object *bo,
- struct ww_acquire_ctx *t)
+static inline void __ttm_bo_unreserve(struct ttm_buffer_object *bo)
{
- if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
- spin_lock(&bo->glob->lru_lock);
- ttm_bo_add_to_lru(bo);
- spin_unlock(&bo->glob->lru_lock);
- }
ww_mutex_unlock(&bo->resv->lock);
}
@@ -953,7 +948,25 @@ static inline void ttm_bo_unreserve_ticket(struct ttm_buffer_object *bo,
*/
static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo)
{
- ttm_bo_unreserve_ticket(bo, NULL);
+ if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
+ spin_lock(&bo->glob->lru_lock);
+ ttm_bo_add_to_lru(bo);
+ spin_unlock(&bo->glob->lru_lock);
+ }
+ __ttm_bo_unreserve(bo);
+}
+
+/**
+ * ttm_bo_unreserve_ticket
+ * @bo: A pointer to a struct ttm_buffer_object.
+ * @ticket: ww_acquire_ctx used for reserving
+ *
+ * Unreserve a previous reservation of @bo made with @ticket.
+ */
+static inline void ttm_bo_unreserve_ticket(struct ttm_buffer_object *bo,
+ struct ww_acquire_ctx *t)
+{
+ ttm_bo_unreserve(bo);
}
/*
diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h
index 0097cc03034e..ed953f98f0e1 100644
--- a/include/drm/ttm/ttm_object.h
+++ b/include/drm/ttm/ttm_object.h
@@ -244,6 +244,10 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base);
extern int ttm_ref_object_add(struct ttm_object_file *tfile,
struct ttm_base_object *base,
enum ttm_ref_type ref_type, bool *existed);
+
+extern bool ttm_ref_object_exists(struct ttm_object_file *tfile,
+ struct ttm_base_object *base);
+
/**
* ttm_ref_object_base_unref
*
diff --git a/include/drm/ttm/ttm_placement.h b/include/drm/ttm/ttm_placement.h
index c84ff153a564..8ed44f9bbdfb 100644
--- a/include/drm/ttm/ttm_placement.h
+++ b/include/drm/ttm/ttm_placement.h
@@ -65,6 +65,8 @@
* reference the buffer.
* TTM_PL_FLAG_NO_EVICT means that the buffer may never
* be evicted to make room for other buffers.
+ * TTM_PL_FLAG_TOPDOWN requests to be placed from the
+ * top of the memory area, instead of the bottom.
*/
#define TTM_PL_FLAG_CACHED (1 << 16)
@@ -72,6 +74,7 @@
#define TTM_PL_FLAG_WC (1 << 18)
#define TTM_PL_FLAG_SHARED (1 << 20)
#define TTM_PL_FLAG_NO_EVICT (1 << 21)
+#define TTM_PL_FLAG_TOPDOWN (1 << 22)
#define TTM_PL_MASK_CACHING (TTM_PL_FLAG_CACHED | \
TTM_PL_FLAG_UNCACHED | \