summaryrefslogtreecommitdiff
path: root/include/drm
diff options
context:
space:
mode:
Diffstat (limited to 'include/drm')
-rw-r--r--include/drm/bridge/analogix_dp.h3
-rw-r--r--include/drm/drmP.h133
-rw-r--r--include/drm/drm_atomic_helper.h18
-rw-r--r--include/drm/drm_connector.h747
-rw-r--r--include/drm/drm_crtc.h1056
-rw-r--r--include/drm/drm_crtc_helper.h6
-rw-r--r--include/drm/drm_dp_aux_dev.h62
-rw-r--r--include/drm/drm_encoder.h227
-rw-r--r--include/drm/drm_fb_helper.h28
-rw-r--r--include/drm/drm_fourcc.h3
-rw-r--r--include/drm/drm_framebuffer.h250
-rw-r--r--include/drm/drm_gem.h4
-rw-r--r--include/drm/drm_mode_object.h124
-rw-r--r--include/drm/drm_modes.h18
-rw-r--r--include/drm/drm_modeset_helper.h36
-rw-r--r--include/drm/drm_modeset_helper_vtables.h28
-rw-r--r--include/drm/drm_plane_helper.h4
-rw-r--r--include/drm/drm_property.h294
-rw-r--r--include/drm/drm_simple_kms_helper.h11
-rw-r--r--include/drm/i2c/tda998x.h29
-rw-r--r--include/drm/ttm/ttm_bo_api.h32
-rw-r--r--include/drm/ttm/ttm_bo_driver.h9
-rw-r--r--include/drm/ttm/ttm_memory.h1
-rw-r--r--include/drm/ttm/ttm_placement.h56
24 files changed, 1946 insertions, 1233 deletions
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 261b86d20e77..9cd8838e1ec3 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -38,6 +38,9 @@ struct analogix_dp_plat_data {
struct drm_connector *);
};
+int analogix_dp_enable_psr(struct device *dev);
+int analogix_dp_disable_psr(struct device *dev);
+
int analogix_dp_resume(struct device *dev);
int analogix_dp_suspend(struct device *dev);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 734e4fb11f52..e341e7f6eef5 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -127,6 +127,7 @@ struct dma_buf_attachment;
* run-time by echoing the debug value in its sysfs node:
* # echo 0xf > /sys/module/drm/parameters/debug
*/
+#define DRM_UT_NONE 0x00
#define DRM_UT_CORE 0x01
#define DRM_UT_DRIVER 0x02
#define DRM_UT_KMS 0x04
@@ -134,11 +135,15 @@ struct dma_buf_attachment;
#define DRM_UT_ATOMIC 0x10
#define DRM_UT_VBL 0x20
-extern __printf(2, 3)
-void drm_ut_debug_printk(const char *function_name,
- const char *format, ...);
-extern __printf(1, 2)
-void drm_err(const char *format, ...);
+extern __printf(6, 7)
+void drm_dev_printk(const struct device *dev, const char *level,
+ unsigned int category, const char *function_name,
+ const char *prefix, const char *format, ...);
+
+extern __printf(5, 6)
+void drm_printk(const char *level, unsigned int category,
+ const char *function_name, const char *prefix,
+ const char *format, ...);
/***********************************************************************/
/** \name DRM template customization defaults */
@@ -189,8 +194,12 @@ void drm_err(const char *format, ...);
* \param fmt printf() like format string.
* \param arg arguments
*/
-#define DRM_ERROR(fmt, ...) \
- drm_err(fmt, ##__VA_ARGS__)
+#define DRM_DEV_ERROR(dev, fmt, ...) \
+ drm_dev_printk(dev, KERN_ERR, DRM_UT_NONE, __func__, " *ERROR*",\
+ fmt, ##__VA_ARGS__)
+#define DRM_ERROR(fmt, ...) \
+ drm_printk(KERN_ERR, DRM_UT_NONE, __func__, " *ERROR*", fmt, \
+ ##__VA_ARGS__)
/**
* Rate limited error output. Like DRM_ERROR() but won't flood the log.
@@ -198,14 +207,29 @@ void drm_err(const char *format, ...);
* \param fmt printf() like format string.
* \param arg arguments
*/
-#define DRM_ERROR_RATELIMITED(fmt, ...) \
+#define DRM_DEV_ERROR_RATELIMITED(dev, fmt, ...) \
({ \
static DEFINE_RATELIMIT_STATE(_rs, \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
\
if (__ratelimit(&_rs)) \
- drm_err(fmt, ##__VA_ARGS__); \
+ DRM_DEV_ERROR(dev, fmt, ##__VA_ARGS__); \
+})
+#define DRM_ERROR_RATELIMITED(fmt, ...) \
+ DRM_DEV_ERROR_RATELIMITED(NULL, fmt, ##__VA_ARGS__)
+
+#define DRM_DEV_INFO(dev, fmt, ...) \
+ drm_dev_printk(dev, KERN_INFO, DRM_UT_NONE, __func__, "", fmt, \
+ ##__VA_ARGS__)
+
+#define DRM_DEV_INFO_ONCE(dev, fmt, ...) \
+({ \
+ static bool __print_once __read_mostly; \
+ if (!__print_once) { \
+ __print_once = true; \
+ DRM_DEV_INFO(dev, fmt, ##__VA_ARGS__); \
+ } \
})
/**
@@ -214,52 +238,51 @@ void drm_err(const char *format, ...);
* \param fmt printf() like format string.
* \param arg arguments
*/
+#define DRM_DEV_DEBUG(dev, fmt, args...) \
+ drm_dev_printk(dev, KERN_DEBUG, DRM_UT_CORE, __func__, "", fmt, \
+ ##args)
#define DRM_DEBUG(fmt, args...) \
- do { \
- if (unlikely(drm_debug & DRM_UT_CORE)) \
- drm_ut_debug_printk(__func__, fmt, ##args); \
- } while (0)
+ drm_printk(KERN_DEBUG, DRM_UT_CORE, __func__, "", fmt, ##args)
+#define DRM_DEV_DEBUG_DRIVER(dev, fmt, args...) \
+ drm_dev_printk(dev, KERN_DEBUG, DRM_UT_DRIVER, __func__, "", \
+ fmt, ##args)
#define DRM_DEBUG_DRIVER(fmt, args...) \
- do { \
- if (unlikely(drm_debug & DRM_UT_DRIVER)) \
- drm_ut_debug_printk(__func__, fmt, ##args); \
- } while (0)
+ drm_printk(KERN_DEBUG, DRM_UT_DRIVER, __func__, "", fmt, ##args)
+
+#define DRM_DEV_DEBUG_KMS(dev, fmt, args...) \
+ drm_dev_printk(dev, KERN_DEBUG, DRM_UT_KMS, __func__, "", fmt, \
+ ##args)
#define DRM_DEBUG_KMS(fmt, args...) \
- do { \
- if (unlikely(drm_debug & DRM_UT_KMS)) \
- drm_ut_debug_printk(__func__, fmt, ##args); \
- } while (0)
+ drm_printk(KERN_DEBUG, DRM_UT_KMS, __func__, "", fmt, ##args)
+
+#define DRM_DEV_DEBUG_PRIME(dev, fmt, args...) \
+ drm_dev_printk(dev, KERN_DEBUG, DRM_UT_PRIME, __func__, "", \
+ fmt, ##args)
#define DRM_DEBUG_PRIME(fmt, args...) \
- do { \
- if (unlikely(drm_debug & DRM_UT_PRIME)) \
- drm_ut_debug_printk(__func__, fmt, ##args); \
- } while (0)
+ drm_printk(KERN_DEBUG, DRM_UT_PRIME, __func__, "", fmt, ##args)
+
+#define DRM_DEV_DEBUG_ATOMIC(dev, fmt, args...) \
+ drm_dev_printk(dev, KERN_DEBUG, DRM_UT_ATOMIC, __func__, "", \
+ fmt, ##args)
#define DRM_DEBUG_ATOMIC(fmt, args...) \
- do { \
- if (unlikely(drm_debug & DRM_UT_ATOMIC)) \
- drm_ut_debug_printk(__func__, fmt, ##args); \
- } while (0)
+ drm_printk(KERN_DEBUG, DRM_UT_ATOMIC, __func__, "", fmt, ##args)
+
+#define DRM_DEV_DEBUG_VBL(dev, fmt, args...) \
+ drm_dev_printk(dev, KERN_DEBUG, DRM_UT_VBL, __func__, "", fmt, \
+ ##args)
#define DRM_DEBUG_VBL(fmt, args...) \
- do { \
- if (unlikely(drm_debug & DRM_UT_VBL)) \
- drm_ut_debug_printk(__func__, fmt, ##args); \
- } while (0)
+ drm_printk(KERN_DEBUG, DRM_UT_VBL, __func__, "", fmt, ##args)
-#define _DRM_DEFINE_DEBUG_RATELIMITED(level, fmt, args...) \
- do { \
- if (unlikely(drm_debug & DRM_UT_ ## level)) { \
- static DEFINE_RATELIMIT_STATE( \
- _rs, \
- DEFAULT_RATELIMIT_INTERVAL, \
- DEFAULT_RATELIMIT_BURST); \
- \
- if (__ratelimit(&_rs)) { \
- drm_ut_debug_printk(__func__, fmt, \
- ##args); \
- } \
- } \
- } while (0)
+#define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...) \
+({ \
+ static DEFINE_RATELIMIT_STATE(_rs, \
+ DEFAULT_RATELIMIT_INTERVAL, \
+ DEFAULT_RATELIMIT_BURST); \
+ if (__ratelimit(&_rs)) \
+ drm_dev_printk(dev, KERN_DEBUG, DRM_UT_ ## level, \
+ __func__, "", fmt, ##args); \
+})
/**
* Rate limited debug output. Like DRM_DEBUG() but won't flood the log.
@@ -267,14 +290,22 @@ void drm_err(const char *format, ...);
* \param fmt printf() like format string.
* \param arg arguments
*/
+#define DRM_DEV_DEBUG_RATELIMITED(dev, fmt, args...) \
+ DEV__DRM_DEFINE_DEBUG_RATELIMITED(dev, CORE, fmt, ##args)
#define DRM_DEBUG_RATELIMITED(fmt, args...) \
- _DRM_DEFINE_DEBUG_RATELIMITED(CORE, fmt, ##args)
+ DRM_DEV_DEBUG_RATELIMITED(NULL, fmt, ##args)
+#define DRM_DEV_DEBUG_DRIVER_RATELIMITED(dev, fmt, args...) \
+ _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRIVER, fmt, ##args)
#define DRM_DEBUG_DRIVER_RATELIMITED(fmt, args...) \
- _DRM_DEFINE_DEBUG_RATELIMITED(DRIVER, fmt, ##args)
+ DRM_DEV_DEBUG_DRIVER_RATELIMITED(NULL, fmt, ##args)
+#define DRM_DEV_DEBUG_KMS_RATELIMITED(dev, fmt, args...) \
+ _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, KMS, fmt, ##args)
#define DRM_DEBUG_KMS_RATELIMITED(fmt, args...) \
- _DRM_DEFINE_DEBUG_RATELIMITED(KMS, fmt, ##args)
+ DRM_DEV_DEBUG_KMS_RATELIMITED(NULL, fmt, ##args)
+#define DRM_DEV_DEBUG_PRIME_RATELIMITED(dev, fmt, args...) \
+ _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, PRIME, fmt, ##args)
#define DRM_DEBUG_PRIME_RATELIMITED(fmt, args...) \
- _DRM_DEFINE_DEBUG_RATELIMITED(PRIME, fmt, ##args)
+ DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##args)
/*@}*/
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index d86ae5dcd7b4..7ff92b09fd9c 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -29,6 +29,8 @@
#define DRM_ATOMIC_HELPER_H_
#include <drm/drm_crtc.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_modeset_helper.h>
struct drm_atomic_state;
@@ -43,8 +45,9 @@ int drm_atomic_helper_commit(struct drm_device *dev,
struct drm_atomic_state *state,
bool nonblock);
-void drm_atomic_helper_wait_for_fences(struct drm_device *dev,
- struct drm_atomic_state *state);
+int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
+ struct drm_atomic_state *state,
+ bool pre_swap);
bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev,
struct drm_atomic_state *old_state,
struct drm_crtc *crtc);
@@ -63,14 +66,19 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
int drm_atomic_helper_prepare_planes(struct drm_device *dev,
struct drm_atomic_state *state);
+
+#define DRM_PLANE_COMMIT_ACTIVE_ONLY BIT(0)
+#define DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET BIT(1)
+
void drm_atomic_helper_commit_planes(struct drm_device *dev,
struct drm_atomic_state *state,
- bool active_only);
+ uint32_t flags);
void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
struct drm_atomic_state *old_state);
void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state);
-void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc,
- bool atomic);
+void
+drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
+ bool atomic);
void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
bool stall);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
new file mode 100644
index 000000000000..66b7d6744dd2
--- /dev/null
+++ b/include/drm/drm_connector.h
@@ -0,0 +1,747 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef __DRM_CONNECTOR_H__
+#define __DRM_CONNECTOR_H__
+
+#include <linux/list.h>
+#include <linux/ctype.h>
+#include <drm/drm_mode_object.h>
+
+struct drm_connector_helper_funcs;
+struct drm_device;
+struct drm_crtc;
+struct drm_encoder;
+struct drm_property;
+struct drm_property_blob;
+struct edid;
+
+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 */
+};
+
+/**
+ * enum drm_connector_status - status for a &drm_connector
+ *
+ * This enum is used to track the connector status. There are no separate
+ * #defines for the uapi!
+ */
+enum drm_connector_status {
+ /**
+ * @connector_status_connected: The connector is definitely connected to
+ * a sink device, and can be enabled.
+ */
+ connector_status_connected = 1,
+ /**
+ * @connector_status_disconnected: The connector isn't connected to a
+ * sink device which can be autodetect. For digital outputs like DP or
+ * HDMI (which can be realiable probed) this means there's really
+ * nothing there. It is driver-dependent whether a connector with this
+ * status can be lit up or not.
+ */
+ connector_status_disconnected = 2,
+ /**
+ * @connector_status_unknown: The connector's status could not be
+ * reliably detected. This happens when probing would either cause
+ * flicker (like load-detection when the connector is in use), or when a
+ * hardware resource isn't available (like when load-detection needs a
+ * free CRTC). It should be possible to light up the connector with one
+ * of the listed fallback modes. For default configuration userspace
+ * should only try to light up connectors with unknown status when
+ * there's not connector with @connector_status_connected.
+ */
+ connector_status_unknown = 3,
+};
+
+enum subpixel_order {
+ SubPixelUnknown = 0,
+ SubPixelHorizontalRGB,
+ SubPixelHorizontalBGR,
+ SubPixelVerticalRGB,
+ SubPixelVerticalBGR,
+ SubPixelNone,
+};
+
+/**
+ * struct drm_display_info - runtime data about the connected sink
+ *
+ * Describes a given display (e.g. CRT or flat panel) and its limitations. For
+ * fixed display sinks like built-in panels there's not much difference between
+ * this and struct &drm_connector. But for sinks with a real cable this
+ * structure is meant to describe all the things at the other end of the cable.
+ *
+ * For sinks which provide an EDID this can be filled out by calling
+ * drm_add_edid_modes().
+ */
+struct drm_display_info {
+ /**
+ * @name: Name of the display.
+ */
+ char name[DRM_DISPLAY_INFO_LEN];
+
+ /**
+ * @width_mm: Physical width in mm.
+ */
+ unsigned int width_mm;
+ /**
+ * @height_mm: Physical height in mm.
+ */
+ unsigned int height_mm;
+
+ /**
+ * @pixel_clock: Maximum pixel clock supported by the sink, in units of
+ * 100Hz. This mismatches the clok in &drm_display_mode (which is in
+ * kHZ), because that's what the EDID uses as base unit.
+ */
+ unsigned int pixel_clock;
+ /**
+ * @bpc: Maximum bits per color channel. Used by HDMI and DP outputs.
+ */
+ unsigned int bpc;
+
+ /**
+ * @subpixel_order: Subpixel order of LCD panels.
+ */
+ enum subpixel_order subpixel_order;
+
+#define DRM_COLOR_FORMAT_RGB444 (1<<0)
+#define DRM_COLOR_FORMAT_YCRCB444 (1<<1)
+#define DRM_COLOR_FORMAT_YCRCB422 (1<<2)
+
+ /**
+ * @color_formats: HDMI Color formats, selects between RGB and YCrCb
+ * modes. Used DRM_COLOR_FORMAT\_ defines, which are _not_ the same ones
+ * as used to describe the pixel format in framebuffers, and also don't
+ * match the formats in @bus_formats which are shared with v4l.
+ */
+ u32 color_formats;
+
+ /**
+ * @bus_formats: Pixel data format on the wire, somewhat redundant with
+ * @color_formats. Array of size @num_bus_formats encoded using
+ * MEDIA_BUS_FMT\_ defines shared with v4l and media drivers.
+ */
+ const u32 *bus_formats;
+ /**
+ * @num_bus_formats: Size of @bus_formats array.
+ */
+ unsigned int num_bus_formats;
+
+#define DRM_BUS_FLAG_DE_LOW (1<<0)
+#define DRM_BUS_FLAG_DE_HIGH (1<<1)
+/* drive data on pos. edge */
+#define DRM_BUS_FLAG_PIXDATA_POSEDGE (1<<2)
+/* drive data on neg. edge */
+#define DRM_BUS_FLAG_PIXDATA_NEGEDGE (1<<3)
+
+ /**
+ * @bus_flags: Additional information (like pixel signal polarity) for
+ * the pixel data on the bus, using DRM_BUS_FLAGS\_ defines.
+ */
+ u32 bus_flags;
+
+ /**
+ * @edid_hdmi_dc_modes: Mask of supported hdmi deep color modes. Even
+ * more stuff redundant with @bus_formats.
+ */
+ u8 edid_hdmi_dc_modes;
+
+ /**
+ * @cea_rev: CEA revision of the HDMI sink.
+ */
+ u8 cea_rev;
+};
+
+int drm_display_info_set_bus_formats(struct drm_display_info *info,
+ const u32 *formats,
+ unsigned int num_formats);
+
+/**
+ * struct drm_connector_state - mutable connector state
+ * @connector: backpointer to the connector
+ * @crtc: CRTC to connect connector to, NULL if disabled
+ * @best_encoder: can be used by helpers and drivers to select the encoder
+ * @state: backpointer to global drm_atomic_state
+ */
+struct drm_connector_state {
+ struct drm_connector *connector;
+
+ struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_connector() */
+
+ struct drm_encoder *best_encoder;
+
+ struct drm_atomic_state *state;
+};
+
+/**
+ * struct drm_connector_funcs - control connectors on a given device
+ *
+ * Each CRTC may have one or more connectors attached to it. The functions
+ * below allow the core DRM code to control connectors, enumerate available modes,
+ * etc.
+ */
+struct drm_connector_funcs {
+ /**
+ * @dpms:
+ *
+ * Legacy entry point to set the per-connector DPMS state. Legacy DPMS
+ * is exposed as a standard property on the connector, but diverted to
+ * this callback in the drm core. Note that atomic drivers don't
+ * implement the 4 level DPMS support on the connector any more, but
+ * instead only have an on/off "ACTIVE" property on the CRTC object.
+ *
+ * Drivers implementing atomic modeset should use
+ * drm_atomic_helper_connector_dpms() to implement this hook.
+ *
+ * RETURNS:
+ *
+ * 0 on success or a negative error code on failure.
+ */
+ int (*dpms)(struct drm_connector *connector, int mode);
+
+ /**
+ * @reset:
+ *
+ * Reset connector hardware and software state to off. This function isn't
+ * called by the core directly, only through drm_mode_config_reset().
+ * It's not a helper hook only for historical reasons.
+ *
+ * Atomic drivers can use drm_atomic_helper_connector_reset() to reset
+ * atomic state using this hook.
+ */
+ void (*reset)(struct drm_connector *connector);
+
+ /**
+ * @detect:
+ *
+ * Check to see if anything is attached to the connector. The parameter
+ * force is set to false whilst polling, true when checking the
+ * connector due to a user request. force can be used by the driver to
+ * avoid expensive, destructive operations during automated probing.
+ *
+ * FIXME:
+ *
+ * Note that this hook is only called by the probe helper. It's not in
+ * the helper library vtable purely for historical reasons. The only DRM
+ * core entry point to probe connector state is @fill_modes.
+ *
+ * RETURNS:
+ *
+ * drm_connector_status indicating the connector's status.
+ */
+ enum drm_connector_status (*detect)(struct drm_connector *connector,
+ bool force);
+
+ /**
+ * @force:
+ *
+ * This function is called to update internal encoder state when the
+ * connector is forced to a certain state by userspace, either through
+ * the sysfs interfaces or on the kernel cmdline. In that case the
+ * @detect callback isn't called.
+ *
+ * FIXME:
+ *
+ * Note that this hook is only called by the probe helper. It's not in
+ * the helper library vtable purely for historical reasons. The only DRM
+ * core entry point to probe connector state is @fill_modes.
+ */
+ void (*force)(struct drm_connector *connector);
+
+ /**
+ * @fill_modes:
+ *
+ * Entry point for output detection and basic mode validation. The
+ * driver should reprobe the output if needed (e.g. when hotplug
+ * handling is unreliable), add all detected modes to connector->modes
+ * and filter out any the device can't support in any configuration. It
+ * also needs to filter out any modes wider or higher than the
+ * parameters max_width and max_height indicate.
+ *
+ * The drivers must also prune any modes no longer valid from
+ * connector->modes. Furthermore it must update connector->status and
+ * connector->edid. If no EDID has been received for this output
+ * connector->edid must be NULL.
+ *
+ * Drivers using the probe helpers should use
+ * drm_helper_probe_single_connector_modes() or
+ * drm_helper_probe_single_connector_modes_nomerge() to implement this
+ * function.
+ *
+ * RETURNS:
+ *
+ * The number of modes detected and filled into connector->modes.
+ */
+ int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
+
+ /**
+ * @set_property:
+ *
+ * This is the legacy entry point to update a property attached to the
+ * connector.
+ *
+ * Drivers implementing atomic modeset should use
+ * drm_atomic_helper_connector_set_property() to implement this hook.
+ *
+ * This callback is optional if the driver does not support any legacy
+ * driver-private properties.
+ *
+ * RETURNS:
+ *
+ * 0 on success or a negative error code on failure.
+ */
+ int (*set_property)(struct drm_connector *connector, struct drm_property *property,
+ uint64_t val);
+
+ /**
+ * @late_register:
+ *
+ * This optional hook can be used to register additional userspace
+ * interfaces attached to the connector, light backlight control, i2c,
+ * DP aux or similar interfaces. It is called late in the driver load
+ * sequence from drm_connector_register() when registering all the
+ * core drm connector interfaces. Everything added from this callback
+ * should be unregistered in the early_unregister callback.
+ *
+ * Returns:
+ *
+ * 0 on success, or a negative error code on failure.
+ */
+ int (*late_register)(struct drm_connector *connector);
+
+ /**
+ * @early_unregister:
+ *
+ * This optional hook should be used to unregister the additional
+ * userspace interfaces attached to the connector from
+ * late_unregister(). It is called from drm_connector_unregister(),
+ * early in the driver unload sequence to disable userspace access
+ * before data structures are torndown.
+ */
+ void (*early_unregister)(struct drm_connector *connector);
+
+ /**
+ * @destroy:
+ *
+ * Clean up connector resources. This is called at driver unload time
+ * through drm_mode_config_cleanup(). It can also be called at runtime
+ * when a connector is being hot-unplugged for drivers that support
+ * connector hotplugging (e.g. DisplayPort MST).
+ */
+ void (*destroy)(struct drm_connector *connector);
+
+ /**
+ * @atomic_duplicate_state:
+ *
+ * Duplicate the current atomic state for this connector and return it.
+ * The core and helpers gurantee that any atomic state duplicated with
+ * this hook and still owned by the caller (i.e. not transferred to the
+ * driver by calling ->atomic_commit() from struct
+ * &drm_mode_config_funcs) will be cleaned up by calling the
+ * @atomic_destroy_state hook in this structure.
+ *
+ * Atomic drivers which don't subclass struct &drm_connector_state should use
+ * drm_atomic_helper_connector_duplicate_state(). Drivers that subclass the
+ * state structure to extend it with driver-private state should use
+ * __drm_atomic_helper_connector_duplicate_state() to make sure shared state is
+ * duplicated in a consistent fashion across drivers.
+ *
+ * It is an error to call this hook before connector->state has been
+ * initialized correctly.
+ *
+ * NOTE:
+ *
+ * If the duplicate state references refcounted resources this hook must
+ * acquire a reference for each of them. The driver must release these
+ * references again in @atomic_destroy_state.
+ *
+ * RETURNS:
+ *
+ * Duplicated atomic state or NULL when the allocation failed.
+ */
+ struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector);
+
+ /**
+ * @atomic_destroy_state:
+ *
+ * Destroy a state duplicated with @atomic_duplicate_state and release
+ * or unreference all resources it references
+ */
+ void (*atomic_destroy_state)(struct drm_connector *connector,
+ struct drm_connector_state *state);
+
+ /**
+ * @atomic_set_property:
+ *
+ * Decode a driver-private property value and store the decoded value
+ * into the passed-in state structure. Since the atomic core decodes all
+ * standardized properties (even for extensions beyond the core set of
+ * properties which might not be implemented by all drivers) this
+ * requires drivers to subclass the state structure.
+ *
+ * Such driver-private properties should really only be implemented for
+ * truly hardware/vendor specific state. Instead it is preferred to
+ * standardize atomic extension and decode the properties used to expose
+ * such an extension in the core.
+ *
+ * Do not call this function directly, use
+ * drm_atomic_connector_set_property() instead.
+ *
+ * This callback is optional if the driver does not support any
+ * driver-private atomic properties.
+ *
+ * NOTE:
+ *
+ * This function is called in the state assembly phase of atomic
+ * modesets, which can be aborted for any reason (including on
+ * userspace's request to just check whether a configuration would be
+ * possible). Drivers MUST NOT touch any persistent state (hardware or
+ * software) or data structures except the passed in @state parameter.
+ *
+ * Also since userspace controls in which order properties are set this
+ * function must not do any input validation (since the state update is
+ * incomplete and hence likely inconsistent). Instead any such input
+ * validation must be done in the various atomic_check callbacks.
+ *
+ * RETURNS:
+ *
+ * 0 if the property has been found, -EINVAL if the property isn't
+ * implemented by the driver (which shouldn't ever happen, the core only
+ * asks for properties attached to this connector). No other validation
+ * is allowed by the driver. The core already checks that the property
+ * value is within the range (integer, valid enum value, ...) the driver
+ * set when registering the property.
+ */
+ int (*atomic_set_property)(struct drm_connector *connector,
+ struct drm_connector_state *state,
+ struct drm_property *property,
+ uint64_t val);
+
+ /**
+ * @atomic_get_property:
+ *
+ * Reads out the decoded driver-private property. This is used to
+ * implement the GETCONNECTOR IOCTL.
+ *
+ * Do not call this function directly, use
+ * drm_atomic_connector_get_property() instead.
+ *
+ * This callback is optional if the driver does not support any
+ * driver-private atomic properties.
+ *
+ * RETURNS:
+ *
+ * 0 on success, -EINVAL if the property isn't implemented by the
+ * driver (which shouldn't ever happen, the core only asks for
+ * properties attached to this connector).
+ */
+ int (*atomic_get_property)(struct drm_connector *connector,
+ const struct drm_connector_state *state,
+ struct drm_property *property,
+ uint64_t *val);
+};
+
+/* 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_connector - central DRM connector control structure
+ * @dev: parent DRM device
+ * @kdev: kernel device for sysfs attributes
+ * @attr: sysfs attributes
+ * @head: list management
+ * @base: base KMS object
+ * @name: human readable name, can be overwritten by the driver
+ * @connector_type: one of the DRM_MODE_CONNECTOR_<foo> types from drm_mode.h
+ * @connector_type_id: index into connector type enum
+ * @interlace_allowed: can this connector handle interlaced modes?
+ * @doublescan_allowed: can this connector handle doublescan?
+ * @stereo_allowed: can this connector handle stereo modes?
+ * @registered: is this connector exposed (registered) with userspace?
+ * @modes: modes available on this connector (from fill_modes() + user)
+ * @status: one of the drm_connector_status enums (connected, not, or unknown)
+ * @probed_modes: list of modes derived directly from the display
+ * @funcs: connector control functions
+ * @edid_blob_ptr: DRM property containing EDID if present
+ * @properties: property tracking for this connector
+ * @dpms: current dpms state
+ * @helper_private: mid-layer private data
+ * @cmdline_mode: mode line parsed from the kernel cmdline for this connector
+ * @force: a DRM_FORCE_<foo> state for forced mode sets
+ * @override_edid: has the EDID been overwritten through debugfs for testing?
+ * @encoder_ids: valid encoders for this connector
+ * @encoder: encoder driving this connector, if any
+ * @eld: EDID-like data, if present
+ * @dvi_dual: dual link DVI, if found
+ * @max_tmds_clock: max clock rate, if found
+ * @latency_present: AV delay info from ELD, if found
+ * @video_latency: video latency info from ELD, if found
+ * @audio_latency: audio latency info from ELD, if found
+ * @null_edid_counter: track sinks that give us all zeros for the EDID
+ * @bad_edid_counter: track sinks that give us an EDID with invalid checksum
+ * @edid_corrupt: indicates whether the last read EDID was corrupt
+ * @debugfs_entry: debugfs directory for this connector
+ * @state: current atomic state for this connector
+ * @has_tile: is this connector connected to a tiled monitor
+ * @tile_group: tile group for the connected monitor
+ * @tile_is_single_monitor: whether the tile is one monitor housing
+ * @num_h_tile: number of horizontal tiles in the tile group
+ * @num_v_tile: number of vertical tiles in the tile group
+ * @tile_h_loc: horizontal location of this tile
+ * @tile_v_loc: vertical location of this tile
+ * @tile_h_size: horizontal size of this tile.
+ * @tile_v_size: vertical size of this tile.
+ *
+ * Each connector may be connected to one or more CRTCs, or may be clonable by
+ * another connector if they can share a CRTC. Each connector also has a specific
+ * position in the broader display (referred to as a 'screen' though it could
+ * span multiple monitors).
+ */
+struct drm_connector {
+ struct drm_device *dev;
+ struct device *kdev;
+ struct device_attribute *attr;
+ struct list_head head;
+
+ struct drm_mode_object base;
+
+ char *name;
+
+ /**
+ * @index: Compacted connector index, which matches the position inside
+ * the mode_config.list for drivers not supporting hot-add/removing. Can
+ * be used as an array index. It is invariant over the lifetime of the
+ * connector.
+ */
+ unsigned index;
+
+ int connector_type;
+ int connector_type_id;
+ bool interlace_allowed;
+ bool doublescan_allowed;
+ bool stereo_allowed;
+ bool registered;
+ struct list_head modes; /* list of modes on this connector */
+
+ enum drm_connector_status status;
+
+ /* these are modes added by probing with DDC or the BIOS */
+ struct list_head probed_modes;
+
+ /**
+ * @display_info: Display information is filled from EDID information
+ * when a display is detected. For non hot-pluggable displays such as
+ * flat panels in embedded systems, the driver should initialize the
+ * display_info.width_mm and display_info.height_mm fields with the
+ * physical size of the display.
+ */
+ struct drm_display_info display_info;
+ const struct drm_connector_funcs *funcs;
+
+ struct drm_property_blob *edid_blob_ptr;
+ struct drm_object_properties properties;
+
+ /**
+ * @path_blob_ptr:
+ *
+ * DRM blob property data for the DP MST path property.
+ */
+ struct drm_property_blob *path_blob_ptr;
+
+ /**
+ * @tile_blob_ptr:
+ *
+ * DRM blob property data for the tile property (used mostly by DP MST).
+ * This is meant for screens which are driven through separate display
+ * pipelines represented by &drm_crtc, which might not be running with
+ * genlocked clocks. For tiled panels which are genlocked, like
+ * dual-link LVDS or dual-link DSI, the driver should try to not expose
+ * the tiling and virtualize both &drm_crtc and &drm_plane if needed.
+ */
+ struct drm_property_blob *tile_blob_ptr;
+
+/* should we poll this connector for connects and disconnects */
+/* hot plug detectable */
+#define DRM_CONNECTOR_POLL_HPD (1 << 0)
+/* poll for connections */
+#define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
+/* can cleanly poll for disconnections without flickering the screen */
+/* DACs should rarely do this without a lot of testing */
+#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
+
+ /**
+ * @polled:
+ *
+ * Connector polling mode, a combination of
+ *
+ * DRM_CONNECTOR_POLL_HPD
+ * The connector generates hotplug events and doesn't need to be
+ * periodically polled. The CONNECT and DISCONNECT flags must not
+ * be set together with the HPD flag.
+ *
+ * DRM_CONNECTOR_POLL_CONNECT
+ * Periodically poll the connector for connection.
+ *
+ * DRM_CONNECTOR_POLL_DISCONNECT
+ * Periodically poll the connector for disconnection.
+ *
+ * Set to 0 for connectors that don't support connection status
+ * discovery.
+ */
+ uint8_t polled;
+
+ /* requested DPMS state */
+ int dpms;
+
+ const struct drm_connector_helper_funcs *helper_private;
+
+ /* forced on connector */
+ struct drm_cmdline_mode cmdline_mode;
+ enum drm_connector_force force;
+ bool override_edid;
+
+#define DRM_CONNECTOR_MAX_ENCODER 3
+ uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
+ struct drm_encoder *encoder; /* currently active encoder */
+
+#define MAX_ELD_BYTES 128
+ /* EDID bits */
+ uint8_t eld[MAX_ELD_BYTES];
+ bool dvi_dual;
+ int max_tmds_clock; /* in MHz */
+ bool latency_present[2];
+ int video_latency[2]; /* [0]: progressive, [1]: interlaced */
+ int audio_latency[2];
+ int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */
+ unsigned bad_edid_counter;
+
+ /* Flag for raw EDID header corruption - used in Displayport
+ * compliance testing - * Displayport Link CTS Core 1.2 rev1.1 4.2.2.6
+ */
+ bool edid_corrupt;
+
+ struct dentry *debugfs_entry;
+
+ struct drm_connector_state *state;
+
+ /* DisplayID bits */
+ bool has_tile;
+ struct drm_tile_group *tile_group;
+ bool tile_is_single_monitor;
+
+ uint8_t num_h_tile, num_v_tile;
+ uint8_t tile_h_loc, tile_v_loc;
+ uint16_t tile_h_size, tile_v_size;
+};
+
+#define obj_to_connector(x) container_of(x, struct drm_connector, base)
+
+int drm_connector_init(struct drm_device *dev,
+ struct drm_connector *connector,
+ const struct drm_connector_funcs *funcs,
+ int connector_type);
+int drm_connector_register(struct drm_connector *connector);
+void drm_connector_unregister(struct drm_connector *connector);
+int drm_mode_connector_attach_encoder(struct drm_connector *connector,
+ struct drm_encoder *encoder);
+
+void drm_connector_cleanup(struct drm_connector *connector);
+static inline unsigned drm_connector_index(struct drm_connector *connector)
+{
+ return connector->index;
+}
+
+/**
+ * drm_connector_lookup - lookup connector object
+ * @dev: DRM device
+ * @id: connector object id
+ *
+ * This function looks up the connector object specified by id
+ * add takes a reference to it.
+ */
+static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev,
+ uint32_t id)
+{
+ struct drm_mode_object *mo;
+ mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR);
+ return mo ? obj_to_connector(mo) : NULL;
+}
+
+/**
+ * drm_connector_reference - incr the connector refcnt
+ * @connector: connector
+ *
+ * This function increments the connector's refcount.
+ */
+static inline void drm_connector_reference(struct drm_connector *connector)
+{
+ drm_mode_object_reference(&connector->base);
+}
+
+/**
+ * drm_connector_unreference - unref a connector
+ * @connector: connector to unref
+ *
+ * This function decrements the connector's refcount and frees it if it drops to zero.
+ */
+static inline void drm_connector_unreference(struct drm_connector *connector)
+{
+ drm_mode_object_unreference(&connector->base);
+}
+
+const char *drm_get_connector_status_name(enum drm_connector_status status);
+const char *drm_get_subpixel_order_name(enum subpixel_order order);
+const char *drm_get_dpms_name(int val);
+const char *drm_get_dvi_i_subconnector_name(int val);
+const char *drm_get_dvi_i_select_name(int val);
+const char *drm_get_tv_subconnector_name(int val);
+const char *drm_get_tv_select_name(int val);
+
+int drm_mode_create_dvi_i_properties(struct drm_device *dev);
+int drm_mode_create_tv_properties(struct drm_device *dev,
+ unsigned int num_modes,
+ const char * const modes[]);
+int drm_mode_create_scaling_mode_property(struct drm_device *dev);
+int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
+int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
+
+int drm_mode_connector_set_path_property(struct drm_connector *connector,
+ const char *path);
+int drm_mode_connector_set_tile_property(struct drm_connector *connector);
+int drm_mode_connector_update_edid_property(struct drm_connector *connector,
+ const struct edid *edid);
+#endif
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b618b506b04d..8ca71d66282b 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -36,40 +36,21 @@
#include <uapi/drm/drm_fourcc.h>
#include <drm/drm_modeset_lock.h>
#include <drm/drm_rect.h>
+#include <drm/drm_mode_object.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_encoder.h>
+#include <drm/drm_property.h>
struct drm_device;
struct drm_mode_set;
-struct drm_framebuffer;
-struct drm_object_properties;
struct drm_file;
struct drm_clip_rect;
struct device_node;
struct fence;
struct edid;
-struct drm_mode_object {
- uint32_t id;
- uint32_t type;
- struct drm_object_properties *properties;
- struct kref refcount;
- void (*free_cb)(struct kref *kref);
-};
-
-#define DRM_OBJECT_MAX_PROPERTY 24
-struct drm_object_properties {
- int count, atomic_count;
- /* NOTE: if we ever start dynamically destroying properties (ie.
- * not at drm_mode_config_cleanup() time), then we'd have to do
- * a better job of detaching property from mode objects to avoid
- * dangling property pointers:
- */
- struct drm_property *properties[DRM_OBJECT_MAX_PROPERTY];
- /* do not read/write values directly, but use drm_object_property_get_value()
- * and drm_object_property_set_value():
- */
- uint64_t values[DRM_OBJECT_MAX_PROPERTY];
-};
-
static inline int64_t U642I64(uint64_t val)
{
return (int64_t)*((int64_t *)&val);
@@ -94,70 +75,6 @@ static inline uint64_t I642U64(int64_t val)
#define DRM_REFLECT_Y BIT(5)
#define DRM_REFLECT_MASK (DRM_REFLECT_X | DRM_REFLECT_Y)
-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 */
-};
-
-#include <drm/drm_modes.h>
-
-enum drm_connector_status {
- connector_status_connected = 1,
- connector_status_disconnected = 2,
- connector_status_unknown = 3,
-};
-
-enum subpixel_order {
- SubPixelUnknown = 0,
- SubPixelHorizontalRGB,
- SubPixelHorizontalBGR,
- SubPixelVerticalRGB,
- SubPixelVerticalBGR,
- SubPixelNone,
-};
-
-#define DRM_COLOR_FORMAT_RGB444 (1<<0)
-#define DRM_COLOR_FORMAT_YCRCB444 (1<<1)
-#define DRM_COLOR_FORMAT_YCRCB422 (1<<2)
-
-#define DRM_BUS_FLAG_DE_LOW (1<<0)
-#define DRM_BUS_FLAG_DE_HIGH (1<<1)
-/* drive data on pos. edge */
-#define DRM_BUS_FLAG_PIXDATA_POSEDGE (1<<2)
-/* drive data on neg. edge */
-#define DRM_BUS_FLAG_PIXDATA_NEGEDGE (1<<3)
-
-/*
- * Describes a given display (e.g. CRT or flat panel) and its limitations.
- */
-struct drm_display_info {
- char name[DRM_DISPLAY_INFO_LEN];
-
- /* Physical size */
- unsigned int width_mm;
- unsigned int height_mm;
-
- /* Clock limits FIXME: storage format */
- unsigned int min_vfreq, max_vfreq;
- unsigned int min_hfreq, max_hfreq;
- unsigned int pixel_clock;
- unsigned int bpc;
-
- enum subpixel_order subpixel_order;
- u32 color_formats;
-
- const u32 *bus_formats;
- unsigned int num_bus_formats;
- u32 bus_flags;
-
- /* Mask of supported hdmi deep color modes */
- u8 edid_hdmi_dc_modes;
-
- u8 cea_rev;
-};
-
/* data corresponds to displayid vend/prod/serial */
struct drm_tile_group {
struct kref refcount;
@@ -166,130 +83,7 @@ struct drm_tile_group {
u8 group_data[8];
};
-/**
- * struct drm_framebuffer_funcs - framebuffer hooks
- */
-struct drm_framebuffer_funcs {
- /**
- * @destroy:
- *
- * Clean up framebuffer resources, specifically also unreference the
- * backing storage. The core guarantees to call this function for every
- * framebuffer successfully created by ->fb_create() in
- * &drm_mode_config_funcs. Drivers must also call
- * drm_framebuffer_cleanup() to release DRM core resources for this
- * framebuffer.
- */
- void (*destroy)(struct drm_framebuffer *framebuffer);
-
- /**
- * @create_handle:
- *
- * Create a buffer handle in the driver-specific buffer manager (either
- * GEM or TTM) valid for the passed-in struct &drm_file. This is used by
- * the core to implement the GETFB IOCTL, which returns (for
- * sufficiently priviledged user) also a native buffer handle. This can
- * be used for seamless transitions between modesetting clients by
- * copying the current screen contents to a private buffer and blending
- * between that and the new contents.
- *
- * GEM based drivers should call drm_gem_handle_create() to create the
- * handle.
- *
- * RETURNS:
- *
- * 0 on success or a negative error code on failure.
- */
- int (*create_handle)(struct drm_framebuffer *fb,
- struct drm_file *file_priv,
- unsigned int *handle);
- /**
- * @dirty:
- *
- * Optional callback for the dirty fb IOCTL.
- *
- * Userspace can notify the driver via this callback that an area of the
- * framebuffer has changed and should be flushed to the display
- * hardware. This can also be used internally, e.g. by the fbdev
- * emulation, though that's not the case currently.
- *
- * See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd
- * for more information as all the semantics and arguments have a one to
- * one mapping on this function.
- *
- * RETURNS:
- *
- * 0 on success or a negative error code on failure.
- */
- int (*dirty)(struct drm_framebuffer *framebuffer,
- struct drm_file *file_priv, unsigned flags,
- unsigned color, struct drm_clip_rect *clips,
- unsigned num_clips);
-};
-
-struct drm_framebuffer {
- struct drm_device *dev;
- /*
- * Note that the fb is refcounted for the benefit of driver internals,
- * for example some hw, disabling a CRTC/plane is asynchronous, and
- * scanout does not actually complete until the next vblank. So some
- * cleanup (like releasing the reference(s) on the backing GEM bo(s))
- * should be deferred. In cases like this, the driver would like to
- * hold a ref to the fb even though it has already been removed from
- * userspace perspective.
- * The refcount is stored inside the mode object.
- */
- /*
- * Place on the dev->mode_config.fb_list, access protected by
- * dev->mode_config.fb_lock.
- */
- struct list_head head;
- struct drm_mode_object base;
- const struct drm_framebuffer_funcs *funcs;
- unsigned int pitches[4];
- unsigned int offsets[4];
- uint64_t modifier[4];
- unsigned int width;
- unsigned int height;
- /* depth can be 15 or 16 */
- unsigned int depth;
- int bits_per_pixel;
- int flags;
- uint32_t pixel_format; /* fourcc format */
- int hot_x;
- int hot_y;
- struct list_head filp_head;
-};
-
-struct drm_property_blob {
- struct drm_mode_object base;
- struct drm_device *dev;
- struct list_head head_global;
- struct list_head head_file;
- size_t length;
- unsigned char data[];
-};
-
-struct drm_property_enum {
- uint64_t value;
- struct list_head head;
- char name[DRM_PROP_NAME_LEN];
-};
-
-struct drm_property {
- struct list_head head;
- struct drm_mode_object base;
- uint32_t flags;
- char name[DRM_PROP_NAME_LEN];
- uint32_t num_values;
- uint64_t *values;
- struct drm_device *dev;
-
- struct list_head enum_list;
-};
-
struct drm_crtc;
-struct drm_connector;
struct drm_encoder;
struct drm_pending_vblank_event;
struct drm_plane;
@@ -298,7 +92,6 @@ struct drm_atomic_state;
struct drm_crtc_helper_funcs;
struct drm_encoder_helper_funcs;
-struct drm_connector_helper_funcs;
struct drm_plane_helper_funcs;
/**
@@ -547,16 +340,6 @@ struct drm_crtc_funcs {
* counter and timestamp tracking though, e.g. if they have accurate
* timestamp registers in hardware.
*
- * FIXME:
- *
- * Up to that point drivers need to manage events themselves and can use
- * even->base.list freely for that. Specifically they need to ensure
- * that they don't send out page flip (or vblank) events for which the
- * corresponding drm file has been closed already. The drm core
- * unfortunately does not (yet) take care of that. Therefore drivers
- * currently must clean up and release pending events in their
- * ->preclose driver function.
- *
* This callback is optional.
*
* NOTE:
@@ -583,6 +366,24 @@ struct drm_crtc_funcs {
uint32_t flags);
/**
+ * @page_flip_target:
+ *
+ * Same as @page_flip but with an additional parameter specifying the
+ * absolute target vertical blank period (as reported by
+ * drm_crtc_vblank_count()) when the flip should take effect.
+ *
+ * Note that the core code calls drm_crtc_vblank_get before this entry
+ * point, and will call drm_crtc_vblank_put if this entry point returns
+ * any non-0 error code. It's the driver's responsibility to call
+ * drm_crtc_vblank_put after this entry point returns 0, typically when
+ * the flip completes.
+ */
+ int (*page_flip_target)(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t flags, uint32_t target);
+
+ /**
* @set_property:
*
* This is the legacy entry point to update a property attached to the
@@ -854,549 +655,6 @@ struct drm_crtc {
};
/**
- * struct drm_connector_state - mutable connector state
- * @connector: backpointer to the connector
- * @crtc: CRTC to connect connector to, NULL if disabled
- * @best_encoder: can be used by helpers and drivers to select the encoder
- * @state: backpointer to global drm_atomic_state
- */
-struct drm_connector_state {
- struct drm_connector *connector;
-
- struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_connector() */
-
- struct drm_encoder *best_encoder;
-
- struct drm_atomic_state *state;
-};
-
-/**
- * struct drm_connector_funcs - control connectors on a given device
- *
- * Each CRTC may have one or more connectors attached to it. The functions
- * below allow the core DRM code to control connectors, enumerate available modes,
- * etc.
- */
-struct drm_connector_funcs {
- /**
- * @dpms:
- *
- * Legacy entry point to set the per-connector DPMS state. Legacy DPMS
- * is exposed as a standard property on the connector, but diverted to
- * this callback in the drm core. Note that atomic drivers don't
- * implement the 4 level DPMS support on the connector any more, but
- * instead only have an on/off "ACTIVE" property on the CRTC object.
- *
- * Drivers implementing atomic modeset should use
- * drm_atomic_helper_connector_dpms() to implement this hook.
- *
- * RETURNS:
- *
- * 0 on success or a negative error code on failure.
- */
- int (*dpms)(struct drm_connector *connector, int mode);
-
- /**
- * @reset:
- *
- * Reset connector hardware and software state to off. This function isn't
- * called by the core directly, only through drm_mode_config_reset().
- * It's not a helper hook only for historical reasons.
- *
- * Atomic drivers can use drm_atomic_helper_connector_reset() to reset
- * atomic state using this hook.
- */
- void (*reset)(struct drm_connector *connector);
-
- /**
- * @detect:
- *
- * Check to see if anything is attached to the connector. The parameter
- * force is set to false whilst polling, true when checking the
- * connector due to a user request. force can be used by the driver to
- * avoid expensive, destructive operations during automated probing.
- *
- * FIXME:
- *
- * Note that this hook is only called by the probe helper. It's not in
- * the helper library vtable purely for historical reasons. The only DRM
- * core entry point to probe connector state is @fill_modes.
- *
- * RETURNS:
- *
- * drm_connector_status indicating the connector's status.
- */
- enum drm_connector_status (*detect)(struct drm_connector *connector,
- bool force);
-
- /**
- * @force:
- *
- * This function is called to update internal encoder state when the
- * connector is forced to a certain state by userspace, either through
- * the sysfs interfaces or on the kernel cmdline. In that case the
- * @detect callback isn't called.
- *
- * FIXME:
- *
- * Note that this hook is only called by the probe helper. It's not in
- * the helper library vtable purely for historical reasons. The only DRM
- * core entry point to probe connector state is @fill_modes.
- */
- void (*force)(struct drm_connector *connector);
-
- /**
- * @fill_modes:
- *
- * Entry point for output detection and basic mode validation. The
- * driver should reprobe the output if needed (e.g. when hotplug
- * handling is unreliable), add all detected modes to connector->modes
- * and filter out any the device can't support in any configuration. It
- * also needs to filter out any modes wider or higher than the
- * parameters max_width and max_height indicate.
- *
- * The drivers must also prune any modes no longer valid from
- * connector->modes. Furthermore it must update connector->status and
- * connector->edid. If no EDID has been received for this output
- * connector->edid must be NULL.
- *
- * Drivers using the probe helpers should use
- * drm_helper_probe_single_connector_modes() or
- * drm_helper_probe_single_connector_modes_nomerge() to implement this
- * function.
- *
- * RETURNS:
- *
- * The number of modes detected and filled into connector->modes.
- */
- int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
-
- /**
- * @set_property:
- *
- * This is the legacy entry point to update a property attached to the
- * connector.
- *
- * Drivers implementing atomic modeset should use
- * drm_atomic_helper_connector_set_property() to implement this hook.
- *
- * This callback is optional if the driver does not support any legacy
- * driver-private properties.
- *
- * RETURNS:
- *
- * 0 on success or a negative error code on failure.
- */
- int (*set_property)(struct drm_connector *connector, struct drm_property *property,
- uint64_t val);
-
- /**
- * @late_register:
- *
- * This optional hook can be used to register additional userspace
- * interfaces attached to the connector, light backlight control, i2c,
- * DP aux or similar interfaces. It is called late in the driver load
- * sequence from drm_connector_register() when registering all the
- * core drm connector interfaces. Everything added from this callback
- * should be unregistered in the early_unregister callback.
- *
- * Returns:
- *
- * 0 on success, or a negative error code on failure.
- */
- int (*late_register)(struct drm_connector *connector);
-
- /**
- * @early_unregister:
- *
- * This optional hook should be used to unregister the additional
- * userspace interfaces attached to the connector from
- * late_unregister(). It is called from drm_connector_unregister(),
- * early in the driver unload sequence to disable userspace access
- * before data structures are torndown.
- */
- void (*early_unregister)(struct drm_connector *connector);
-
- /**
- * @destroy:
- *
- * Clean up connector resources. This is called at driver unload time
- * through drm_mode_config_cleanup(). It can also be called at runtime
- * when a connector is being hot-unplugged for drivers that support
- * connector hotplugging (e.g. DisplayPort MST).
- */
- void (*destroy)(struct drm_connector *connector);
-
- /**
- * @atomic_duplicate_state:
- *
- * Duplicate the current atomic state for this connector and return it.
- * The core and helpers gurantee that any atomic state duplicated with
- * this hook and still owned by the caller (i.e. not transferred to the
- * driver by calling ->atomic_commit() from struct
- * &drm_mode_config_funcs) will be cleaned up by calling the
- * @atomic_destroy_state hook in this structure.
- *
- * Atomic drivers which don't subclass struct &drm_connector_state should use
- * drm_atomic_helper_connector_duplicate_state(). Drivers that subclass the
- * state structure to extend it with driver-private state should use
- * __drm_atomic_helper_connector_duplicate_state() to make sure shared state is
- * duplicated in a consistent fashion across drivers.
- *
- * It is an error to call this hook before connector->state has been
- * initialized correctly.
- *
- * NOTE:
- *
- * If the duplicate state references refcounted resources this hook must
- * acquire a reference for each of them. The driver must release these
- * references again in @atomic_destroy_state.
- *
- * RETURNS:
- *
- * Duplicated atomic state or NULL when the allocation failed.
- */
- struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector);
-
- /**
- * @atomic_destroy_state:
- *
- * Destroy a state duplicated with @atomic_duplicate_state and release
- * or unreference all resources it references
- */
- void (*atomic_destroy_state)(struct drm_connector *connector,
- struct drm_connector_state *state);
-
- /**
- * @atomic_set_property:
- *
- * Decode a driver-private property value and store the decoded value
- * into the passed-in state structure. Since the atomic core decodes all
- * standardized properties (even for extensions beyond the core set of
- * properties which might not be implemented by all drivers) this
- * requires drivers to subclass the state structure.
- *
- * Such driver-private properties should really only be implemented for
- * truly hardware/vendor specific state. Instead it is preferred to
- * standardize atomic extension and decode the properties used to expose
- * such an extension in the core.
- *
- * Do not call this function directly, use
- * drm_atomic_connector_set_property() instead.
- *
- * This callback is optional if the driver does not support any
- * driver-private atomic properties.
- *
- * NOTE:
- *
- * This function is called in the state assembly phase of atomic
- * modesets, which can be aborted for any reason (including on
- * userspace's request to just check whether a configuration would be
- * possible). Drivers MUST NOT touch any persistent state (hardware or
- * software) or data structures except the passed in @state parameter.
- *
- * Also since userspace controls in which order properties are set this
- * function must not do any input validation (since the state update is
- * incomplete and hence likely inconsistent). Instead any such input
- * validation must be done in the various atomic_check callbacks.
- *
- * RETURNS:
- *
- * 0 if the property has been found, -EINVAL if the property isn't
- * implemented by the driver (which shouldn't ever happen, the core only
- * asks for properties attached to this connector). No other validation
- * is allowed by the driver. The core already checks that the property
- * value is within the range (integer, valid enum value, ...) the driver
- * set when registering the property.
- */
- int (*atomic_set_property)(struct drm_connector *connector,
- struct drm_connector_state *state,
- struct drm_property *property,
- uint64_t val);
-
- /**
- * @atomic_get_property:
- *
- * Reads out the decoded driver-private property. This is used to
- * implement the GETCONNECTOR IOCTL.
- *
- * Do not call this function directly, use
- * drm_atomic_connector_get_property() instead.
- *
- * This callback is optional if the driver does not support any
- * driver-private atomic properties.
- *
- * RETURNS:
- *
- * 0 on success, -EINVAL if the property isn't implemented by the
- * driver (which shouldn't ever happen, the core only asks for
- * properties attached to this connector).
- */
- int (*atomic_get_property)(struct drm_connector *connector,
- const struct drm_connector_state *state,
- struct drm_property *property,
- uint64_t *val);
-};
-
-/**
- * struct drm_encoder_funcs - encoder controls
- *
- * Encoders sit between CRTCs and connectors.
- */
-struct drm_encoder_funcs {
- /**
- * @reset:
- *
- * Reset encoder hardware and software state to off. This function isn't
- * called by the core directly, only through drm_mode_config_reset().
- * It's not a helper hook only for historical reasons.
- */
- void (*reset)(struct drm_encoder *encoder);
-
- /**
- * @destroy:
- *
- * Clean up encoder resources. This is only called at driver unload time
- * through drm_mode_config_cleanup() since an encoder cannot be
- * hotplugged in DRM.
- */
- void (*destroy)(struct drm_encoder *encoder);
-
- /**
- * @late_register:
- *
- * This optional hook can be used to register additional userspace
- * interfaces attached to the encoder like debugfs interfaces.
- * It is called late in the driver load sequence from drm_dev_register().
- * Everything added from this callback should be unregistered in
- * the early_unregister callback.
- *
- * Returns:
- *
- * 0 on success, or a negative error code on failure.
- */
- int (*late_register)(struct drm_encoder *encoder);
-
- /**
- * @early_unregister:
- *
- * This optional hook should be used to unregister the additional
- * userspace interfaces attached to the encoder from
- * late_unregister(). It is called from drm_dev_unregister(),
- * early in the driver unload sequence to disable userspace access
- * before data structures are torndown.
- */
- void (*early_unregister)(struct drm_encoder *encoder);
-};
-
-#define DRM_CONNECTOR_MAX_ENCODER 3
-
-/**
- * struct drm_encoder - central DRM encoder structure
- * @dev: parent DRM device
- * @head: list management
- * @base: base KMS object
- * @name: human readable name, can be overwritten by the driver
- * @encoder_type: one of the %DRM_MODE_ENCODER_<foo> types in drm_mode.h
- * @possible_crtcs: bitmask of potential CRTC bindings
- * @possible_clones: bitmask of potential sibling encoders for cloning
- * @crtc: currently bound CRTC
- * @bridge: bridge associated to the encoder
- * @funcs: control functions
- * @helper_private: mid-layer private data
- *
- * CRTCs drive pixels to encoders, which convert them into signals
- * appropriate for a given connector or set of connectors.
- */
-struct drm_encoder {
- struct drm_device *dev;
- struct list_head head;
-
- struct drm_mode_object base;
- char *name;
- int encoder_type;
-
- /**
- * @index: Position inside the mode_config.list, can be used as an array
- * index. It is invariant over the lifetime of the encoder.
- */
- unsigned index;
-
- uint32_t possible_crtcs;
- uint32_t possible_clones;
-
- struct drm_crtc *crtc;
- struct drm_bridge *bridge;
- const struct drm_encoder_funcs *funcs;
- const struct drm_encoder_helper_funcs *helper_private;
-};
-
-/* should we poll this connector for connects and disconnects */
-/* hot plug detectable */
-#define DRM_CONNECTOR_POLL_HPD (1 << 0)
-/* poll for connections */
-#define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
-/* can cleanly poll for disconnections without flickering the screen */
-/* DACs should rarely do this without a lot of testing */
-#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
-
-#define MAX_ELD_BYTES 128
-
-/**
- * struct drm_connector - central DRM connector control structure
- * @dev: parent DRM device
- * @kdev: kernel device for sysfs attributes
- * @attr: sysfs attributes
- * @head: list management
- * @base: base KMS object
- * @name: human readable name, can be overwritten by the driver
- * @connector_type: one of the %DRM_MODE_CONNECTOR_<foo> types from drm_mode.h
- * @connector_type_id: index into connector type enum
- * @interlace_allowed: can this connector handle interlaced modes?
- * @doublescan_allowed: can this connector handle doublescan?
- * @stereo_allowed: can this connector handle stereo modes?
- * @registered: is this connector exposed (registered) with userspace?
- * @modes: modes available on this connector (from fill_modes() + user)
- * @status: one of the drm_connector_status enums (connected, not, or unknown)
- * @probed_modes: list of modes derived directly from the display
- * @display_info: information about attached display (e.g. from EDID)
- * @funcs: connector control functions
- * @edid_blob_ptr: DRM property containing EDID if present
- * @properties: property tracking for this connector
- * @polled: a %DRM_CONNECTOR_POLL_<foo> value for core driven polling
- * @dpms: current dpms state
- * @helper_private: mid-layer private data
- * @cmdline_mode: mode line parsed from the kernel cmdline for this connector
- * @force: a %DRM_FORCE_<foo> state for forced mode sets
- * @override_edid: has the EDID been overwritten through debugfs for testing?
- * @encoder_ids: valid encoders for this connector
- * @encoder: encoder driving this connector, if any
- * @eld: EDID-like data, if present
- * @dvi_dual: dual link DVI, if found
- * @max_tmds_clock: max clock rate, if found
- * @latency_present: AV delay info from ELD, if found
- * @video_latency: video latency info from ELD, if found
- * @audio_latency: audio latency info from ELD, if found
- * @null_edid_counter: track sinks that give us all zeros for the EDID
- * @bad_edid_counter: track sinks that give us an EDID with invalid checksum
- * @edid_corrupt: indicates whether the last read EDID was corrupt
- * @debugfs_entry: debugfs directory for this connector
- * @state: current atomic state for this connector
- * @has_tile: is this connector connected to a tiled monitor
- * @tile_group: tile group for the connected monitor
- * @tile_is_single_monitor: whether the tile is one monitor housing
- * @num_h_tile: number of horizontal tiles in the tile group
- * @num_v_tile: number of vertical tiles in the tile group
- * @tile_h_loc: horizontal location of this tile
- * @tile_v_loc: vertical location of this tile
- * @tile_h_size: horizontal size of this tile.
- * @tile_v_size: vertical size of this tile.
- *
- * Each connector may be connected to one or more CRTCs, or may be clonable by
- * another connector if they can share a CRTC. Each connector also has a specific
- * position in the broader display (referred to as a 'screen' though it could
- * span multiple monitors).
- */
-struct drm_connector {
- struct drm_device *dev;
- struct device *kdev;
- struct device_attribute *attr;
- struct list_head head;
-
- struct drm_mode_object base;
-
- char *name;
-
- /**
- * @index: Compacted connector index, which matches the position inside
- * the mode_config.list for drivers not supporting hot-add/removing. Can
- * be used as an array index. It is invariant over the lifetime of the
- * connector.
- */
- unsigned index;
-
- int connector_type;
- int connector_type_id;
- bool interlace_allowed;
- bool doublescan_allowed;
- bool stereo_allowed;
- bool registered;
- struct list_head modes; /* list of modes on this connector */
-
- enum drm_connector_status status;
-
- /* these are modes added by probing with DDC or the BIOS */
- struct list_head probed_modes;
-
- struct drm_display_info display_info;
- const struct drm_connector_funcs *funcs;
-
- struct drm_property_blob *edid_blob_ptr;
- struct drm_object_properties properties;
-
- /**
- * @path_blob_ptr:
- *
- * DRM blob property data for the DP MST path property.
- */
- struct drm_property_blob *path_blob_ptr;
-
- /**
- * @tile_blob_ptr:
- *
- * DRM blob property data for the tile property (used mostly by DP MST).
- * This is meant for screens which are driven through separate display
- * pipelines represented by &drm_crtc, which might not be running with
- * genlocked clocks. For tiled panels which are genlocked, like
- * dual-link LVDS or dual-link DSI, the driver should try to not expose
- * the tiling and virtualize both &drm_crtc and &drm_plane if needed.
- */
- struct drm_property_blob *tile_blob_ptr;
-
- uint8_t polled; /* DRM_CONNECTOR_POLL_* */
-
- /* requested DPMS state */
- int dpms;
-
- const struct drm_connector_helper_funcs *helper_private;
-
- /* forced on connector */
- struct drm_cmdline_mode cmdline_mode;
- enum drm_connector_force force;
- bool override_edid;
- uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
- struct drm_encoder *encoder; /* currently active encoder */
-
- /* EDID bits */
- uint8_t eld[MAX_ELD_BYTES];
- bool dvi_dual;
- int max_tmds_clock; /* in MHz */
- bool latency_present[2];
- int video_latency[2]; /* [0]: progressive, [1]: interlaced */
- int audio_latency[2];
- int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */
- unsigned bad_edid_counter;
-
- /* Flag for raw EDID header corruption - used in Displayport
- * compliance testing - * Displayport Link CTS Core 1.2 rev1.1 4.2.2.6
- */
- bool edid_corrupt;
-
- struct dentry *debugfs_entry;
-
- struct drm_connector_state *state;
-
- /* DisplayID bits */
- bool has_tile;
- struct drm_tile_group *tile_group;
- bool tile_is_single_monitor;
-
- uint8_t num_h_tile, num_v_tile;
- uint8_t tile_h_loc, tile_v_loc;
- uint16_t tile_h_size, tile_v_size;
-};
-
-/**
* struct drm_plane_state - mutable plane state
* @plane: backpointer to the plane
* @crtc: currently bound CRTC, NULL if disabled
@@ -1762,12 +1020,33 @@ struct drm_plane {
/**
* struct drm_bridge_funcs - drm_bridge control functions
- * @attach: Called during drm_bridge_attach
*/
struct drm_bridge_funcs {
+ /**
+ * @attach:
+ *
+ * This callback is invoked whenever our bridge is being attached to a
+ * &drm_encoder.
+ *
+ * The attach callback is optional.
+ *
+ * RETURNS:
+ *
+ * Zero on success, error code on failure.
+ */
int (*attach)(struct drm_bridge *bridge);
/**
+ * @detach:
+ *
+ * This callback is invoked whenever our bridge is being detached from a
+ * &drm_encoder.
+ *
+ * The detach callback is optional.
+ */
+ void (*detach)(struct drm_bridge *bridge);
+
+ /**
* @mode_fixup:
*
* This callback is used to validate and adjust a mode. The paramater
@@ -1781,6 +1060,8 @@ struct drm_bridge_funcs {
* this function passes all other callbacks must succeed for this
* configuration.
*
+ * The mode_fixup callback is optional.
+ *
* NOTE:
*
* This function is called in the check phase of atomic modesets, which
@@ -2650,12 +1931,6 @@ struct drm_mode_config {
*/
struct drm_property *aspect_ratio_property;
/**
- * @dirty_info_property: Optional connector property to give userspace a
- * hint that the DIRTY_FB ioctl should be used.
- */
- struct drm_property *dirty_info_property;
-
- /**
* @degamma_lut_property: Optional CRTC property to set the LUT used to
* convert the framebuffer's colors to linear gamma.
*/
@@ -2741,19 +2016,11 @@ struct drm_mode_config {
for_each_if ((encoder_mask) & (1 << drm_encoder_index(encoder)))
#define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
-#define obj_to_connector(x) container_of(x, struct drm_connector, base)
-#define obj_to_encoder(x) container_of(x, struct drm_encoder, base)
#define obj_to_mode(x) container_of(x, struct drm_display_mode, base)
#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)
-#define obj_to_property(x) container_of(x, struct drm_property, base)
#define obj_to_blob(x) container_of(x, struct drm_property_blob, base)
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
-struct drm_prop_enum_list {
- int type;
- char *name;
-};
-
extern __printf(6, 7)
int drm_crtc_init_with_planes(struct drm_device *dev,
struct drm_crtc *crtc,
@@ -2787,50 +2054,6 @@ static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc)
return 1 << drm_crtc_index(crtc);
}
-int drm_connector_init(struct drm_device *dev,
- struct drm_connector *connector,
- const struct drm_connector_funcs *funcs,
- int connector_type);
-int drm_connector_register(struct drm_connector *connector);
-void drm_connector_unregister(struct drm_connector *connector);
-
-extern void drm_connector_cleanup(struct drm_connector *connector);
-static inline unsigned drm_connector_index(struct drm_connector *connector)
-{
- return connector->index;
-}
-
-extern __printf(5, 6)
-int drm_encoder_init(struct drm_device *dev,
- struct drm_encoder *encoder,
- const struct drm_encoder_funcs *funcs,
- int encoder_type, const char *name, ...);
-
-/**
- * drm_encoder_index - find the index of a registered encoder
- * @encoder: encoder to find index for
- *
- * Given a registered encoder, return the index of that encoder within a DRM
- * device's list of encoders.
- */
-static inline unsigned int drm_encoder_index(struct drm_encoder *encoder)
-{
- return encoder->index;
-}
-
-/**
- * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
- * @encoder: encoder to test
- * @crtc: crtc to test
- *
- * Return false if @encoder can't be driven by @crtc, true otherwise.
- */
-static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
- struct drm_crtc *crtc)
-{
- return !!(encoder->possible_crtcs & drm_crtc_mask(crtc));
-}
-
extern __printf(8, 9)
int drm_universal_plane_init(struct drm_device *dev,
struct drm_plane *plane,
@@ -2866,105 +2089,15 @@ extern void drm_crtc_get_hv_timing(const struct drm_display_mode *mode,
extern int drm_crtc_force_disable(struct drm_crtc *crtc);
extern int drm_crtc_force_disable_all(struct drm_device *dev);
-extern void drm_encoder_cleanup(struct drm_encoder *encoder);
-
-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);
-extern const char *drm_get_tv_subconnector_name(int val);
-extern const char *drm_get_tv_select_name(int val);
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 int drm_mode_connector_set_path_property(struct drm_connector *connector,
- const char *path);
-int drm_mode_connector_set_tile_property(struct drm_connector *connector);
-extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
- const struct edid *edid);
-
-extern int drm_display_info_set_bus_formats(struct drm_display_info *info,
- const u32 *formats,
- unsigned int num_formats);
-
-static inline bool drm_property_type_is(struct drm_property *property,
- uint32_t type)
-{
- /* instanceof for props.. handles extended type vs original types: */
- if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
- return (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) == type;
- return property->flags & type;
-}
-
-extern int drm_object_property_set_value(struct drm_mode_object *obj,
- struct drm_property *property,
- uint64_t val);
-extern int drm_object_property_get_value(struct drm_mode_object *obj,
- struct drm_property *property,
- uint64_t *value);
-extern int drm_framebuffer_init(struct drm_device *dev,
- struct drm_framebuffer *fb,
- const struct drm_framebuffer_funcs *funcs);
-extern struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
- uint32_t id);
-extern void drm_framebuffer_remove(struct drm_framebuffer *fb);
-extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
-extern void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
-
-extern void drm_object_attach_property(struct drm_mode_object *obj,
- struct drm_property *property,
- uint64_t init_val);
-extern struct drm_property *drm_property_create(struct drm_device *dev, int flags,
- const char *name, int num_values);
-extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
- const char *name,
- const struct drm_prop_enum_list *props,
- int num_values);
-struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
- int flags, const char *name,
- const struct drm_prop_enum_list *props,
- int num_props,
- uint64_t supported_bits);
-struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
- const char *name,
- uint64_t min, uint64_t max);
-struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
- int flags, const char *name,
- int64_t min, int64_t max);
-struct drm_property *drm_property_create_object(struct drm_device *dev,
- int flags, const char *name, uint32_t type);
-struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
- const char *name);
-struct drm_property_blob *drm_property_create_blob(struct drm_device *dev,
- size_t length,
- const void *data);
-struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
- uint32_t id);
-struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob);
-void drm_property_unreference_blob(struct drm_property_blob *blob);
-extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
-extern int drm_property_add_enum(struct drm_property *property, int index,
- uint64_t value, const char *name);
-extern int drm_mode_create_dvi_i_properties(struct drm_device *dev);
-extern int drm_mode_create_tv_properties(struct drm_device *dev,
- unsigned int num_modes,
- const char * const modes[]);
-extern int drm_mode_create_scaling_mode_property(struct drm_device *dev);
-extern int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
-extern int drm_mode_create_dirty_info_property(struct drm_device *dev);
-extern int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
-
-extern int drm_mode_connector_attach_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 int drm_mode_set_config_internal(struct drm_mode_set *set);
-extern uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
-
extern struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
char topology[8]);
extern struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
@@ -2993,11 +2126,6 @@ int drm_plane_create_zpos_immutable_property(struct drm_plane *plane,
unsigned int zpos);
/* Helpers */
-struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
- uint32_t id, uint32_t type);
-void drm_mode_object_reference(struct drm_mode_object *obj);
-void drm_mode_object_unreference(struct drm_mode_object *obj);
-
static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
uint32_t id)
{
@@ -3014,38 +2142,6 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
return mo ? obj_to_crtc(mo) : NULL;
}
-static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
- uint32_t id)
-{
- struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
- return mo ? obj_to_encoder(mo) : NULL;
-}
-
-/**
- * drm_connector_lookup - lookup connector object
- * @dev: DRM device
- * @id: connector object id
- *
- * This function looks up the connector object specified by id
- * add takes a reference to it.
- */
-static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev,
- uint32_t id)
-{
- struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR);
- return mo ? obj_to_connector(mo) : NULL;
-}
-
-static inline struct drm_property *drm_property_find(struct drm_device *dev,
- uint32_t id)
-{
- struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY);
- return mo ? obj_to_property(mo) : NULL;
-}
-
/*
* Extract a degamma/gamma LUT value provided by user and round it to the
* precision supported by the hardware.
@@ -3065,61 +2161,6 @@ static inline uint32_t drm_color_lut_extract(uint32_t user_input,
return clamp_val(val, 0, max);
}
-/**
- * drm_framebuffer_reference - incr the fb refcnt
- * @fb: framebuffer
- *
- * This functions increments the fb's refcount.
- */
-static inline void drm_framebuffer_reference(struct drm_framebuffer *fb)
-{
- drm_mode_object_reference(&fb->base);
-}
-
-/**
- * drm_framebuffer_unreference - unref a framebuffer
- * @fb: framebuffer to unref
- *
- * This functions decrements the fb's refcount and frees it if it drops to zero.
- */
-static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb)
-{
- drm_mode_object_unreference(&fb->base);
-}
-
-/**
- * drm_framebuffer_read_refcount - read the framebuffer reference count.
- * @fb: framebuffer
- *
- * This functions returns the framebuffer's reference count.
- */
-static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb)
-{
- return atomic_read(&fb->base.refcount.refcount);
-}
-
-/**
- * drm_connector_reference - incr the connector refcnt
- * @connector: connector
- *
- * This function increments the connector's refcount.
- */
-static inline void drm_connector_reference(struct drm_connector *connector)
-{
- drm_mode_object_reference(&connector->base);
-}
-
-/**
- * drm_connector_unreference - unref a connector
- * @connector: connector to unref
- *
- * This function decrements the connector's refcount and frees it if it drops to zero.
- */
-static inline void drm_connector_unreference(struct drm_connector *connector)
-{
- drm_mode_object_unreference(&connector->base);
-}
-
/* Plane list iterator for legacy (overlay only) planes. */
#define drm_for_each_legacy_plane(plane, dev) \
list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) \
@@ -3196,6 +2237,7 @@ extern int drm_bridge_add(struct drm_bridge *bridge);
extern void drm_bridge_remove(struct drm_bridge *bridge);
extern struct drm_bridge *of_drm_find_bridge(struct device_node *np);
extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge);
+extern void drm_bridge_detach(struct drm_bridge *bridge);
bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 4b37afa2b73b..982c299e435a 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -41,6 +41,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_modeset_helper.h>
extern void drm_helper_disable_unused_functions(struct drm_device *dev);
extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
@@ -53,11 +54,6 @@ extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
extern int 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_mode_fill_fb_struct(struct drm_framebuffer *fb,
- const struct drm_mode_fb_cmd2 *mode_cmd);
-
extern void drm_helper_resume_force_mode(struct drm_device *dev);
int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
diff --git a/include/drm/drm_dp_aux_dev.h b/include/drm/drm_dp_aux_dev.h
deleted file mode 100644
index 1b76d990d8ab..000000000000
--- a/include/drm/drm_dp_aux_dev.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright © 2015 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.
- *
- * Authors:
- * Rafael Antognolli <rafael.antognolli@intel.com>
- *
- */
-
-#ifndef DRM_DP_AUX_DEV
-#define DRM_DP_AUX_DEV
-
-#include <drm/drm_dp_helper.h>
-
-#ifdef CONFIG_DRM_DP_AUX_CHARDEV
-
-int drm_dp_aux_dev_init(void);
-void drm_dp_aux_dev_exit(void);
-int drm_dp_aux_register_devnode(struct drm_dp_aux *aux);
-void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux);
-
-#else
-
-static inline int drm_dp_aux_dev_init(void)
-{
- return 0;
-}
-
-static inline void drm_dp_aux_dev_exit(void)
-{
-}
-
-static inline int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
-{
- return 0;
-}
-
-static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
-{
-}
-
-#endif
-
-#endif
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
new file mode 100644
index 000000000000..fce0203094f7
--- /dev/null
+++ b/include/drm/drm_encoder.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef __DRM_ENCODER_H__
+#define __DRM_ENCODER_H__
+
+#include <linux/list.h>
+#include <linux/ctype.h>
+#include <drm/drm_mode_object.h>
+
+/**
+ * struct drm_encoder_funcs - encoder controls
+ *
+ * Encoders sit between CRTCs and connectors.
+ */
+struct drm_encoder_funcs {
+ /**
+ * @reset:
+ *
+ * Reset encoder hardware and software state to off. This function isn't
+ * called by the core directly, only through drm_mode_config_reset().
+ * It's not a helper hook only for historical reasons.
+ */
+ void (*reset)(struct drm_encoder *encoder);
+
+ /**
+ * @destroy:
+ *
+ * Clean up encoder resources. This is only called at driver unload time
+ * through drm_mode_config_cleanup() since an encoder cannot be
+ * hotplugged in DRM.
+ */
+ void (*destroy)(struct drm_encoder *encoder);
+
+ /**
+ * @late_register:
+ *
+ * This optional hook can be used to register additional userspace
+ * interfaces attached to the encoder like debugfs interfaces.
+ * It is called late in the driver load sequence from drm_dev_register().
+ * Everything added from this callback should be unregistered in
+ * the early_unregister callback.
+ *
+ * Returns:
+ *
+ * 0 on success, or a negative error code on failure.
+ */
+ int (*late_register)(struct drm_encoder *encoder);
+
+ /**
+ * @early_unregister:
+ *
+ * This optional hook should be used to unregister the additional
+ * userspace interfaces attached to the encoder from
+ * late_unregister(). It is called from drm_dev_unregister(),
+ * early in the driver unload sequence to disable userspace access
+ * before data structures are torndown.
+ */
+ void (*early_unregister)(struct drm_encoder *encoder);
+};
+
+/**
+ * struct drm_encoder - central DRM encoder structure
+ * @dev: parent DRM device
+ * @head: list management
+ * @base: base KMS object
+ * @name: human readable name, can be overwritten by the driver
+ * @crtc: currently bound CRTC
+ * @bridge: bridge associated to the encoder
+ * @funcs: control functions
+ * @helper_private: mid-layer private data
+ *
+ * CRTCs drive pixels to encoders, which convert them into signals
+ * appropriate for a given connector or set of connectors.
+ */
+struct drm_encoder {
+ struct drm_device *dev;
+ struct list_head head;
+
+ struct drm_mode_object base;
+ char *name;
+ /**
+ * @encoder_type:
+ *
+ * One of the DRM_MODE_ENCODER_<foo> types in drm_mode.h. The following
+ * encoder types are defined thus far:
+ *
+ * - DRM_MODE_ENCODER_DAC for VGA and analog on DVI-I/DVI-A.
+ *
+ * - DRM_MODE_ENCODER_TMDS for DVI, HDMI and (embedded) DisplayPort.
+ *
+ * - DRM_MODE_ENCODER_LVDS for display panels, or in general any panel
+ * with a proprietary parallel connector.
+ *
+ * - DRM_MODE_ENCODER_TVDAC for TV output (Composite, S-Video,
+ * Component, SCART).
+ *
+ * - DRM_MODE_ENCODER_VIRTUAL for virtual machine displays
+ *
+ * - DRM_MODE_ENCODER_DSI for panels connected using the DSI serial bus.
+ *
+ * - DRM_MODE_ENCODER_DPI for panels connected using the DPI parallel
+ * bus.
+ *
+ * - DRM_MODE_ENCODER_DPMST for special fake encoders used to allow
+ * mutliple DP MST streams to share one physical encoder.
+ */
+ int encoder_type;
+
+ /**
+ * @index: Position inside the mode_config.list, can be used as an array
+ * index. It is invariant over the lifetime of the encoder.
+ */
+ unsigned index;
+
+ /**
+ * @possible_crtcs: Bitmask of potential CRTC bindings, using
+ * drm_crtc_index() as the index into the bitfield. The driver must set
+ * the bits for all &drm_crtc objects this encoder can be connected to
+ * before calling drm_encoder_init().
+ *
+ * In reality almost every driver gets this wrong.
+ *
+ * Note that since CRTC objects can't be hotplugged the assigned indices
+ * are stable and hence known before registering all objects.
+ */
+ uint32_t possible_crtcs;
+
+ /**
+ * @possible_clones: Bitmask of potential sibling encoders for cloning,
+ * using drm_encoder_index() as the index into the bitfield. The driver
+ * must set the bits for all &drm_encoder objects which can clone a
+ * &drm_crtc together with this encoder before calling
+ * drm_encoder_init(). Drivers should set the bit representing the
+ * encoder itself, too. Cloning bits should be set such that when two
+ * encoders can be used in a cloned configuration, they both should have
+ * each another bits set.
+ *
+ * In reality almost every driver gets this wrong.
+ *
+ * Note that since encoder objects can't be hotplugged the assigned indices
+ * are stable and hence known before registering all objects.
+ */
+ uint32_t possible_clones;
+
+ struct drm_crtc *crtc;
+ struct drm_bridge *bridge;
+ const struct drm_encoder_funcs *funcs;
+ const struct drm_encoder_helper_funcs *helper_private;
+};
+
+#define obj_to_encoder(x) container_of(x, struct drm_encoder, base)
+
+__printf(5, 6)
+int drm_encoder_init(struct drm_device *dev,
+ struct drm_encoder *encoder,
+ const struct drm_encoder_funcs *funcs,
+ int encoder_type, const char *name, ...);
+
+/**
+ * drm_encoder_index - find the index of a registered encoder
+ * @encoder: encoder to find index for
+ *
+ * Given a registered encoder, return the index of that encoder within a DRM
+ * device's list of encoders.
+ */
+static inline unsigned int drm_encoder_index(struct drm_encoder *encoder)
+{
+ return encoder->index;
+}
+
+/* FIXME: We have an include file mess still, drm_crtc.h needs untangling. */
+static inline uint32_t drm_crtc_mask(struct drm_crtc *crtc);
+
+/**
+ * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
+ * @encoder: encoder to test
+ * @crtc: crtc to test
+ *
+ * Returns false if @encoder can't be driven by @crtc, true otherwise.
+ */
+static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
+ struct drm_crtc *crtc)
+{
+ return !!(encoder->possible_crtcs & drm_crtc_mask(crtc));
+}
+
+/**
+ * drm_encoder_find - find a &drm_encoder
+ * @dev: DRM device
+ * @id: encoder id
+ *
+ * Returns the encoder with @id, NULL if it doesn't exist. Simple wrapper around
+ * drm_mode_object_find().
+ */
+static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
+ uint32_t id)
+{
+ struct drm_mode_object *mo;
+
+ mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
+
+ return mo ? obj_to_encoder(mo) : NULL;
+}
+
+void drm_encoder_cleanup(struct drm_encoder *encoder);
+
+#endif
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 130c324f1aee..797fb5f80c45 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -177,6 +177,7 @@ struct drm_fb_helper_connector {
* the screen buffer
* @dirty_lock: spinlock protecting @dirty_clip
* @dirty_work: worker used to flush the framebuffer
+ * @resume_work: worker used during resume if the console lock is already taken
*
* This is the main structure used by the fbdev helpers. Drivers supporting
* fbdev emulation should embedded this into their overall driver structure.
@@ -197,6 +198,7 @@ struct drm_fb_helper {
struct drm_clip_rect dirty_clip;
spinlock_t dirty_lock;
struct work_struct dirty_work;
+ struct work_struct resume_work;
/**
* @kernel_fb_list:
@@ -216,7 +218,6 @@ struct drm_fb_helper {
};
#ifdef CONFIG_DRM_FBDEV_EMULATION
-int drm_fb_helper_modinit(void);
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
const struct drm_fb_helper_funcs *funcs);
int drm_fb_helper_init(struct drm_device *dev,
@@ -264,7 +265,9 @@ void drm_fb_helper_cfb_copyarea(struct fb_info *info,
void drm_fb_helper_cfb_imageblit(struct fb_info *info,
const struct fb_image *image);
-void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, int state);
+void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend);
+void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
+ bool suspend);
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
@@ -283,12 +286,6 @@ drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector);
int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
struct drm_connector *connector);
-static inline int
-drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a,
- const char *name, bool primary)
-{
- return remove_conflicting_framebuffers(a, name, primary);
-}
#else
static inline int drm_fb_helper_modinit(void)
{
@@ -424,7 +421,12 @@ static inline void drm_fb_helper_cfb_imageblit(struct fb_info *info,
}
static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper,
- int state)
+ bool suspend)
+{
+}
+
+static inline void
+drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend)
{
}
@@ -483,11 +485,17 @@ drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
return 0;
}
+#endif
+
static inline int
drm_fb_helper_remove_conflicting_framebuffers(struct apertures_struct *a,
const char *name, bool primary)
{
+#if IS_REACHABLE(CONFIG_FB)
+ return remove_conflicting_framebuffers(a, name, primary);
+#else
return 0;
-}
#endif
+}
+
#endif
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 7f90a396cf2b..30c30fa87ee8 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -25,6 +25,7 @@
#include <linux/types.h>
#include <uapi/drm/drm_fourcc.h>
+uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp);
int drm_format_num_planes(uint32_t format);
int drm_format_plane_cpp(uint32_t format, int plane);
@@ -32,6 +33,6 @@ int drm_format_horz_chroma_subsampling(uint32_t format);
int drm_format_vert_chroma_subsampling(uint32_t format);
int drm_format_plane_width(int width, uint32_t format, int plane);
int drm_format_plane_height(int height, uint32_t format, int plane);
-const char *drm_get_format_name(uint32_t format);
+char *drm_get_format_name(uint32_t format) __malloc;
#endif /* __DRM_FOURCC_H__ */
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
new file mode 100644
index 000000000000..b2554c50a903
--- /dev/null
+++ b/include/drm/drm_framebuffer.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef __DRM_FRAMEBUFFER_H__
+#define __DRM_FRAMEBUFFER_H__
+
+#include <linux/list.h>
+#include <linux/ctype.h>
+#include <drm/drm_mode_object.h>
+
+struct drm_framebuffer;
+struct drm_file;
+struct drm_device;
+
+/**
+ * struct drm_framebuffer_funcs - framebuffer hooks
+ */
+struct drm_framebuffer_funcs {
+ /**
+ * @destroy:
+ *
+ * Clean up framebuffer resources, specifically also unreference the
+ * backing storage. The core guarantees to call this function for every
+ * framebuffer successfully created by ->fb_create() in
+ * &drm_mode_config_funcs. Drivers must also call
+ * drm_framebuffer_cleanup() to release DRM core resources for this
+ * framebuffer.
+ */
+ void (*destroy)(struct drm_framebuffer *framebuffer);
+
+ /**
+ * @create_handle:
+ *
+ * Create a buffer handle in the driver-specific buffer manager (either
+ * GEM or TTM) valid for the passed-in struct &drm_file. This is used by
+ * the core to implement the GETFB IOCTL, which returns (for
+ * sufficiently priviledged user) also a native buffer handle. This can
+ * be used for seamless transitions between modesetting clients by
+ * copying the current screen contents to a private buffer and blending
+ * between that and the new contents.
+ *
+ * GEM based drivers should call drm_gem_handle_create() to create the
+ * handle.
+ *
+ * RETURNS:
+ *
+ * 0 on success or a negative error code on failure.
+ */
+ int (*create_handle)(struct drm_framebuffer *fb,
+ struct drm_file *file_priv,
+ unsigned int *handle);
+ /**
+ * @dirty:
+ *
+ * Optional callback for the dirty fb IOCTL.
+ *
+ * Userspace can notify the driver via this callback that an area of the
+ * framebuffer has changed and should be flushed to the display
+ * hardware. This can also be used internally, e.g. by the fbdev
+ * emulation, though that's not the case currently.
+ *
+ * See documentation in drm_mode.h for the struct drm_mode_fb_dirty_cmd
+ * for more information as all the semantics and arguments have a one to
+ * one mapping on this function.
+ *
+ * RETURNS:
+ *
+ * 0 on success or a negative error code on failure.
+ */
+ int (*dirty)(struct drm_framebuffer *framebuffer,
+ struct drm_file *file_priv, unsigned flags,
+ unsigned color, struct drm_clip_rect *clips,
+ unsigned num_clips);
+};
+
+/**
+ * struct drm_framebuffer - frame buffer object
+ *
+ * Note that the fb is refcounted for the benefit of driver internals,
+ * for example some hw, disabling a CRTC/plane is asynchronous, and
+ * scanout does not actually complete until the next vblank. So some
+ * cleanup (like releasing the reference(s) on the backing GEM bo(s))
+ * should be deferred. In cases like this, the driver would like to
+ * hold a ref to the fb even though it has already been removed from
+ * userspace perspective. See drm_framebuffer_reference() and
+ * drm_framebuffer_unreference().
+ *
+ * The refcount is stored inside the mode object @base.
+ */
+struct drm_framebuffer {
+ /**
+ * @dev: DRM device this framebuffer belongs to
+ */
+ struct drm_device *dev;
+ /**
+ * @head: Place on the dev->mode_config.fb_list, access protected by
+ * dev->mode_config.fb_lock.
+ */
+ struct list_head head;
+
+ /**
+ * @base: base modeset object structure, contains the reference count.
+ */
+ struct drm_mode_object base;
+ /**
+ * @funcs: framebuffer vfunc table
+ */
+ const struct drm_framebuffer_funcs *funcs;
+ /**
+ * @pitches: Line stride per buffer. For userspace created object this
+ * is copied from drm_mode_fb_cmd2.
+ */
+ unsigned int pitches[4];
+ /**
+ * @offsets: Offset from buffer start to the actual pixel data in bytes,
+ * per buffer. For userspace created object this is copied from
+ * drm_mode_fb_cmd2.
+ *
+ * Note that this is a linear offset and does not take into account
+ * tiling or buffer laytou per @modifier. It meant to be used when the
+ * actual pixel data for this framebuffer plane starts at an offset,
+ * e.g. when multiple planes are allocated within the same backing
+ * storage buffer object. For tiled layouts this generally means it
+ * @offsets must at least be tile-size aligned, but hardware often has
+ * stricter requirements.
+ *
+ * This should not be used to specifiy x/y pixel offsets into the buffer
+ * data (even for linear buffers). Specifying an x/y pixel offset is
+ * instead done through the source rectangle in struct &drm_plane_state.
+ */
+ unsigned int offsets[4];
+ /**
+ * @modifier: Data layout modifier, per buffer. This is used to describe
+ * tiling, or also special layouts (like compression) of auxiliary
+ * buffers. For userspace created object this is copied from
+ * drm_mode_fb_cmd2.
+ */
+ uint64_t modifier[4];
+ /**
+ * @width: Logical width of the visible area of the framebuffer, in
+ * pixels.
+ */
+ unsigned int width;
+ /**
+ * @height: Logical height of the visible area of the framebuffer, in
+ * pixels.
+ */
+ unsigned int height;
+ /**
+ * @depth: Depth in bits per pixel for RGB formats. 0 for everything
+ * else. Legacy information derived from @pixel_format, it's suggested to use
+ * the DRM FOURCC codes and helper functions directly instead.
+ */
+ unsigned int depth;
+ /**
+ * @bits_per_pixel: Storage used bits per pixel for RGB formats. 0 for
+ * everything else. Legacy information derived from @pixel_format, it's
+ * suggested to use the DRM FOURCC codes and helper functions directly
+ * instead.
+ */
+ int bits_per_pixel;
+ /**
+ * @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or
+ * DRM_MODE_FB_MODIFIERS.
+ */
+ int flags;
+ /**
+ * @pixel_format: DRM FOURCC code describing the pixel format.
+ */
+ uint32_t pixel_format; /* fourcc format */
+ /**
+ * @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor
+ * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
+ * universal plane.
+ */
+ int hot_x;
+ /**
+ * @hot_y: Y coordinate of the cursor hotspot. Used by the legacy cursor
+ * IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
+ * universal plane.
+ */
+ int hot_y;
+ /**
+ * @filp_head: Placed on struct &drm_file fbs list_head, protected by
+ * fbs_lock in the same structure.
+ */
+ struct list_head filp_head;
+};
+
+int drm_framebuffer_init(struct drm_device *dev,
+ struct drm_framebuffer *fb,
+ const struct drm_framebuffer_funcs *funcs);
+struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
+ uint32_t id);
+void drm_framebuffer_remove(struct drm_framebuffer *fb);
+void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
+void drm_framebuffer_unregister_private(struct drm_framebuffer *fb);
+
+/**
+ * drm_framebuffer_reference - incr the fb refcnt
+ * @fb: framebuffer
+ *
+ * This functions increments the fb's refcount.
+ */
+static inline void drm_framebuffer_reference(struct drm_framebuffer *fb)
+{
+ drm_mode_object_reference(&fb->base);
+}
+
+/**
+ * drm_framebuffer_unreference - unref a framebuffer
+ * @fb: framebuffer to unref
+ *
+ * This functions decrements the fb's refcount and frees it if it drops to zero.
+ */
+static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb)
+{
+ drm_mode_object_unreference(&fb->base);
+}
+
+/**
+ * drm_framebuffer_read_refcount - read the framebuffer reference count.
+ * @fb: framebuffer
+ *
+ * This functions returns the framebuffer's reference count.
+ */
+static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb)
+{
+ return atomic_read(&fb->base.refcount.refcount);
+}
+#endif
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index fca1cd1b9c26..9f63736e6163 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -210,8 +210,8 @@ drm_gem_object_reference(struct drm_gem_object *obj)
* drm_gem_object_unreference_unlocked().
*
* Drivers should never call this directly in their code. Instead they should
- * wrap it up into a driver_gem_object_unreference(struct driver_gem_object
- * *obj) wrapper function, and use that. Shared code should never call this, to
+ * wrap it up into a ``driver_gem_object_unreference(struct driver_gem_object
+ * *obj)`` wrapper function, and use that. Shared code should never call this, to
* avoid breaking drivers by accident which still depend upon dev->struct_mutex
* locking.
*/
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
new file mode 100644
index 000000000000..be3d93839ae2
--- /dev/null
+++ b/include/drm/drm_mode_object.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef __DRM_MODESET_H__
+#define __DRM_MODESET_H__
+
+#include <linux/kref.h>
+struct drm_object_properties;
+struct drm_property;
+
+/**
+ * struct drm_mode_object - base structure for modeset objects
+ * @id: userspace visible identifier
+ * @type: type of the object, one of DRM_MODE_OBJECT\_\*
+ * @properties: properties attached to this object, including values
+ * @refcount: reference count for objects which with dynamic lifetime
+ * @free_cb: free function callback, only set for objects with dynamic lifetime
+ *
+ * Base structure for modeset objects visible to userspace. Objects can be
+ * looked up using drm_mode_object_find(). Besides basic uapi interface
+ * properties like @id and @type it provides two services:
+ *
+ * - It tracks attached properties and their values. This is used by &drm_crtc,
+ * &drm_plane and &drm_connector. Properties are attached by calling
+ * drm_object_attach_property() before the object is visible to userspace.
+ *
+ * - For objects with dynamic lifetimes (as indicated by a non-NULL @free_cb) it
+ * provides reference counting through drm_mode_object_reference() and
+ * drm_mode_object_unreference(). This is used by &drm_framebuffer,
+ * &drm_connector and &drm_property_blob. These objects provide specialized
+ * reference counting wrappers.
+ */
+struct drm_mode_object {
+ uint32_t id;
+ uint32_t type;
+ struct drm_object_properties *properties;
+ struct kref refcount;
+ void (*free_cb)(struct kref *kref);
+};
+
+#define DRM_OBJECT_MAX_PROPERTY 24
+/**
+ * struct drm_object_properties - property tracking for &drm_mode_object
+ */
+struct drm_object_properties {
+ /**
+ * @count: number of valid properties, must be less than or equal to
+ * DRM_OBJECT_MAX_PROPERTY.
+ */
+
+ int count;
+ /**
+ * @properties: Array of pointers to &drm_property.
+ *
+ * NOTE: if we ever start dynamically destroying properties (ie.
+ * not at drm_mode_config_cleanup() time), then we'd have to do
+ * a better job of detaching property from mode objects to avoid
+ * dangling property pointers:
+ */
+ struct drm_property *properties[DRM_OBJECT_MAX_PROPERTY];
+
+ /**
+ * @values: Array to store the property values, matching @properties. Do
+ * not read/write values directly, but use
+ * drm_object_property_get_value() and drm_object_property_set_value().
+ *
+ * Note that atomic drivers do not store mutable properties in this
+ * array, but only the decoded values in the corresponding state
+ * structure. The decoding is done using the ->atomic_get_property and
+ * ->atomic_set_property hooks of the corresponding object. Hence atomic
+ * drivers should not use drm_object_property_set_value() and
+ * drm_object_property_get_value() on mutable objects, i.e. those
+ * without the DRM_MODE_PROP_IMMUTABLE flag set.
+ */
+ uint64_t values[DRM_OBJECT_MAX_PROPERTY];
+};
+
+/* Avoid boilerplate. I'm tired of typing. */
+#define DRM_ENUM_NAME_FN(fnname, list) \
+ const char *fnname(int val) \
+ { \
+ int i; \
+ for (i = 0; i < ARRAY_SIZE(list); i++) { \
+ if (list[i].type == val) \
+ return list[i].name; \
+ } \
+ return "(unknown)"; \
+ }
+
+struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+ uint32_t id, uint32_t type);
+void drm_mode_object_reference(struct drm_mode_object *obj);
+void drm_mode_object_unreference(struct drm_mode_object *obj);
+
+int drm_object_property_set_value(struct drm_mode_object *obj,
+ struct drm_property *property,
+ uint64_t val);
+int drm_object_property_get_value(struct drm_mode_object *obj,
+ struct drm_property *property,
+ uint64_t *value);
+
+void drm_object_attach_property(struct drm_mode_object *obj,
+ struct drm_property *property,
+ uint64_t init_val);
+#endif
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index 48e1a56ea283..011f199d3bcf 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -27,6 +27,9 @@
#ifndef __DRM_MODES_H__
#define __DRM_MODES_H__
+#include <drm/drm_mode_object.h>
+#include <drm/drm_connector.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,
@@ -400,21 +403,6 @@ struct drm_display_mode {
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
diff --git a/include/drm/drm_modeset_helper.h b/include/drm/drm_modeset_helper.h
new file mode 100644
index 000000000000..b8051d5abe10
--- /dev/null
+++ b/include/drm/drm_modeset_helper.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef __DRM_KMS_HELPER_H__
+#define __DRM_KMS_HELPER_H__
+
+#include <drm/drmP.h>
+
+void drm_helper_move_panel_connectors_to_head(struct drm_device *);
+
+void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
+ const struct drm_mode_fb_cmd2 *mode_cmd);
+
+int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
+ const struct drm_crtc_funcs *funcs);
+
+#endif
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 686feec6b4c8..10e449c86dbd 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -266,6 +266,8 @@ struct drm_crtc_helper_funcs {
* disable anything at the CRTC level. To ensure that runtime PM
* handling (using either DPMS or the new "ACTIVE" property) works
* @disable must be the inverse of @enable for atomic drivers.
+ * Atomic drivers should consider to use @atomic_disable instead of
+ * this one.
*
* NOTE:
*
@@ -391,6 +393,28 @@ struct drm_crtc_helper_funcs {
*/
void (*atomic_flush)(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state);
+
+ /**
+ * @atomic_disable:
+ *
+ * This callback should be used to disable the CRTC. With the atomic
+ * drivers it is called after all encoders connected to this CRTC have
+ * been shut off already using their own ->disable hook. If that
+ * sequence is too simple drivers can just add their own hooks and call
+ * it from this CRTC callback here by looping over all encoders
+ * connected to it using for_each_encoder_on_crtc().
+ *
+ * This hook is used only by atomic helpers. Atomic drivers don't
+ * need to implement it if there's no need to disable anything at the
+ * CRTC level.
+ *
+ * Comparing to @disable, this one provides the additional input
+ * parameter @old_crtc_state which could be used to access the old
+ * state. Atomic drivers should consider to use this one instead
+ * of @disable.
+ */
+ void (*atomic_disable)(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state);
};
/**
@@ -855,7 +879,7 @@ struct drm_plane_helper_funcs {
* everything else must complete successfully.
*/
int (*prepare_fb)(struct drm_plane *plane,
- const struct drm_plane_state *new_state);
+ struct drm_plane_state *new_state);
/**
* @cleanup_fb:
*
@@ -866,7 +890,7 @@ struct drm_plane_helper_funcs {
* transitional plane helpers, but it is optional.
*/
void (*cleanup_fb)(struct drm_plane *plane,
- const struct drm_plane_state *old_state);
+ struct drm_plane_state *old_state);
/**
* @atomic_check:
diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h
index fbc8ecb3e5e8..c18959685c06 100644
--- a/include/drm/drm_plane_helper.h
+++ b/include/drm/drm_plane_helper.h
@@ -27,6 +27,7 @@
#include <drm/drm_rect.h>
#include <drm/drm_crtc.h>
#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_modeset_helper.h>
/*
* Drivers that don't allow primary plane scaling may pass this macro in place
@@ -37,9 +38,6 @@
*/
#define DRM_PLANE_HELPER_NO_SCALING (1<<16)
-int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
- const struct drm_crtc_funcs *funcs);
-
int drm_plane_helper_check_state(struct drm_plane_state *state,
const struct drm_rect *clip,
int min_scale, int max_scale,
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
new file mode 100644
index 000000000000..30ab289be05d
--- /dev/null
+++ b/include/drm/drm_property.h
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef __DRM_PROPERTY_H__
+#define __DRM_PROPERTY_H__
+
+#include <linux/list.h>
+#include <linux/ctype.h>
+#include <drm/drm_mode_object.h>
+
+/**
+ * struct drm_property_enum - symbolic values for enumerations
+ * @value: numeric property value for this enum entry
+ * @head: list of enum values, linked to enum_list in &drm_property
+ * @name: symbolic name for the enum
+ *
+ * For enumeration and bitmask properties this structure stores the symbolic
+ * decoding for each value. This is used for example for the rotation property.
+ */
+struct drm_property_enum {
+ uint64_t value;
+ struct list_head head;
+ char name[DRM_PROP_NAME_LEN];
+};
+
+/**
+ * struct drm_property - modeset object property
+ *
+ * This structure represent a modeset object property. It combines both the name
+ * of the property with the set of permissible values. This means that when a
+ * driver wants to use a property with the same name on different objects, but
+ * with different value ranges, then it must create property for each one. An
+ * example would be rotation of &drm_plane, when e.g. the primary plane cannot
+ * be rotated. But if both the name and the value range match, then the same
+ * property structure can be instantiated multiple times for the same object.
+ * Userspace must be able to cope with this and cannot assume that the same
+ * symbolic property will have the same modeset object ID on all modeset
+ * objects.
+ *
+ * Properties are created by one of the special functions, as explained in
+ * detail in the @flags structure member.
+ *
+ * To actually expose a property it must be attached to each object using
+ * drm_object_attach_property(). Currently properties can only be attached to
+ * &drm_connector, &drm_crtc and &drm_plane.
+ *
+ * Properties are also used as the generic metadatatransport for the atomic
+ * IOCTL. Everything that was set directly in structures in the legacy modeset
+ * IOCTLs (like the plane source or destination windows, or e.g. the links to
+ * the CRTC) is exposed as a property with the DRM_MODE_PROP_ATOMIC flag set.
+ */
+struct drm_property {
+ /**
+ * @head: per-device list of properties, for cleanup.
+ */
+ struct list_head head;
+
+ /**
+ * @base: base KMS object
+ */
+ struct drm_mode_object base;
+
+ /**
+ * @flags:
+ *
+ * Property flags and type. A property needs to be one of the following
+ * types:
+ *
+ * DRM_MODE_PROP_RANGE
+ * Range properties report their minimum and maximum admissible unsigned values.
+ * The KMS core verifies that values set by application fit in that
+ * range. The range is unsigned. Range properties are created using
+ * drm_property_create_range().
+ *
+ * DRM_MODE_PROP_SIGNED_RANGE
+ * Range properties report their minimum and maximum admissible unsigned values.
+ * The KMS core verifies that values set by application fit in that
+ * range. The range is signed. Range properties are created using
+ * drm_property_create_signed_range().
+ *
+ * DRM_MODE_PROP_ENUM
+ * Enumerated properties take a numerical value that ranges from 0 to
+ * the number of enumerated values defined by the property minus one,
+ * and associate a free-formed string name to each value. Applications
+ * can retrieve the list of defined value-name pairs and use the
+ * numerical value to get and set property instance values. Enum
+ * properties are created using drm_property_create_enum().
+ *
+ * DRM_MODE_PROP_BITMASK
+ * Bitmask properties are enumeration properties that additionally
+ * restrict all enumerated values to the 0..63 range. Bitmask property
+ * instance values combine one or more of the enumerated bits defined
+ * by the property. Bitmask properties are created using
+ * drm_property_create_bitmask().
+ *
+ * DRM_MODE_PROB_OBJECT
+ * Object properties are used to link modeset objects. This is used
+ * extensively in the atomic support to create the display pipeline,
+ * by linking &drm_framebuffer to &drm_plane, &drm_plane to
+ * &drm_crtc and &drm_connector to &drm_crtc. An object property can
+ * only link to a specific type of &drm_mode_object, this limit is
+ * enforced by the core. Object properties are created using
+ * drm_property_create_object().
+ *
+ * Object properties work like blob properties, but in a more
+ * general fashion. They are limited to atomic drivers and must have
+ * the DRM_MODE_PROP_ATOMIC flag set.
+ *
+ * DRM_MODE_PROP_BLOB
+ * Blob properties store a binary blob without any format restriction.
+ * The binary blobs are created as KMS standalone objects, and blob
+ * property instance values store the ID of their associated blob
+ * object. Blob properties are created by calling
+ * drm_property_create() with DRM_MODE_PROP_BLOB as the type.
+ *
+ * Actual blob objects to contain blob data are created using
+ * drm_property_create_blob(), or through the corresponding IOCTL.
+ *
+ * Besides the built-in limit to only accept blob objects blob
+ * properties work exactly like object properties. The only reasons
+ * blob properties exist is backwards compatibility with existing
+ * userspace.
+ *
+ * In addition a property can have any combination of the below flags:
+ *
+ * DRM_MODE_PROP_ATOMIC
+ * Set for properties which encode atomic modeset state. Such
+ * properties are not exposed to legacy userspace.
+ *
+ * DRM_MODE_PROP_IMMUTABLE
+ * Set for properties where userspace cannot be changed by
+ * userspace. The kernel is allowed to update the value of these
+ * properties. This is generally used to expose probe state to
+ * usersapce, e.g. the EDID, or the connector path property on DP
+ * MST sinks.
+ */
+ uint32_t flags;
+
+ /**
+ * @name: symbolic name of the properties
+ */
+ char name[DRM_PROP_NAME_LEN];
+
+ /**
+ * @num_values: size of the @values array.
+ */
+ uint32_t num_values;
+
+ /**
+ * @values:
+ *
+ * Array with limits and values for the property. The
+ * interpretation of these limits is dependent upon the type per @flags.
+ */
+ uint64_t *values;
+
+ /**
+ * @dev: DRM device
+ */
+ struct drm_device *dev;
+
+ /**
+ * @enum_list:
+ *
+ * List of &drm_prop_enum_list structures with the symbolic names for
+ * enum and bitmask values.
+ */
+ struct list_head enum_list;
+};
+
+/**
+ * struct drm_property_blob - Blob data for &drm_property
+ * @base: base KMS object
+ * @dev: DRM device
+ * @head_global: entry on the global blob list in &drm_mode_config
+ * property_blob_list.
+ * @head_file: entry on the per-file blob list in &drm_file blobs list.
+ * @length: size of the blob in bytes, invariant over the lifetime of the object
+ * @data: actual data, embedded at the end of this structure
+ *
+ * Blobs are used to store bigger values than what fits directly into the 64
+ * bits available for a &drm_property.
+ *
+ * Blobs are reference counted using drm_property_reference_blob() and
+ * drm_property_unreference_blob(). They are created using
+ * drm_property_create_blob().
+ */
+struct drm_property_blob {
+ struct drm_mode_object base;
+ struct drm_device *dev;
+ struct list_head head_global;
+ struct list_head head_file;
+ size_t length;
+ unsigned char data[];
+};
+
+struct drm_prop_enum_list {
+ int type;
+ char *name;
+};
+
+#define obj_to_property(x) container_of(x, struct drm_property, base)
+
+/**
+ * drm_property_type_is - check the type of a property
+ * @property: property to check
+ * @type: property type to compare with
+ *
+ * This is a helper function becauase the uapi encoding of property types is
+ * a bit special for historical reasons.
+ */
+static inline bool drm_property_type_is(struct drm_property *property,
+ uint32_t type)
+{
+ /* instanceof for props.. handles extended type vs original types: */
+ if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE)
+ return (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) == type;
+ return property->flags & type;
+}
+
+struct drm_property *drm_property_create(struct drm_device *dev, int flags,
+ const char *name, int num_values);
+struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
+ const char *name,
+ const struct drm_prop_enum_list *props,
+ int num_values);
+struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
+ int flags, const char *name,
+ const struct drm_prop_enum_list *props,
+ int num_props,
+ uint64_t supported_bits);
+struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
+ const char *name,
+ uint64_t min, uint64_t max);
+struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
+ int flags, const char *name,
+ int64_t min, int64_t max);
+struct drm_property *drm_property_create_object(struct drm_device *dev,
+ int flags, const char *name, uint32_t type);
+struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
+ const char *name);
+int drm_property_add_enum(struct drm_property *property, int index,
+ uint64_t value, const char *name);
+void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
+
+struct drm_property_blob *drm_property_create_blob(struct drm_device *dev,
+ size_t length,
+ const void *data);
+struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
+ uint32_t id);
+int drm_property_replace_global_blob(struct drm_device *dev,
+ struct drm_property_blob **replace,
+ size_t length,
+ const void *data,
+ struct drm_mode_object *obj_holds_id,
+ struct drm_property *prop_holds_id);
+struct drm_property_blob *drm_property_reference_blob(struct drm_property_blob *blob);
+void drm_property_unreference_blob(struct drm_property_blob *blob);
+
+/**
+ * drm_connector_find - find property object
+ * @dev: DRM device
+ * @id: property object id
+ *
+ * This function looks up the property object specified by id and returns it.
+ */
+static inline struct drm_property *drm_property_find(struct drm_device *dev,
+ uint32_t id)
+{
+ struct drm_mode_object *mo;
+ mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY);
+ return mo ? obj_to_property(mo) : NULL;
+}
+
+#endif
diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h
index 269039722f91..5d112f75e04c 100644
--- a/include/drm/drm_simple_kms_helper.h
+++ b/include/drm/drm_simple_kms_helper.h
@@ -60,6 +60,12 @@ struct drm_simple_display_pipe_funcs {
*
* This function is called when the underlying plane state is updated.
* This hook is optional.
+ *
+ * This is the function drivers should submit the
+ * &drm_pending_vblank_event from. Using either
+ * drm_crtc_arm_vblank_event(), when the driver supports vblank
+ * interrupt handling, or drm_crtc_send_vblank_event() directly in case
+ * the hardware lacks vblank support entirely.
*/
void (*update)(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state);
@@ -85,6 +91,11 @@ struct drm_simple_display_pipe {
const struct drm_simple_display_pipe_funcs *funcs;
};
+int drm_simple_display_pipe_attach_bridge(struct drm_simple_display_pipe *pipe,
+ struct drm_bridge *bridge);
+
+void drm_simple_display_pipe_detach_bridge(struct drm_simple_display_pipe *pipe);
+
int drm_simple_display_pipe_init(struct drm_device *dev,
struct drm_simple_display_pipe *pipe,
const struct drm_simple_display_pipe_funcs *funcs,
diff --git a/include/drm/i2c/tda998x.h b/include/drm/i2c/tda998x.h
index 3e419d92cf5a..a25483090cd5 100644
--- a/include/drm/i2c/tda998x.h
+++ b/include/drm/i2c/tda998x.h
@@ -1,6 +1,24 @@
#ifndef __DRM_I2C_TDA998X_H__
#define __DRM_I2C_TDA998X_H__
+#include <linux/hdmi.h>
+#include <dt-bindings/display/tda998x.h>
+
+enum {
+ AFMT_UNUSED = 0,
+ AFMT_SPDIF = TDA998x_SPDIF,
+ AFMT_I2S = TDA998x_I2S,
+};
+
+struct tda998x_audio_params {
+ u8 config;
+ u8 format;
+ unsigned sample_width;
+ unsigned sample_rate;
+ struct hdmi_audio_infoframe cea;
+ u8 status[5];
+};
+
struct tda998x_encoder_params {
u8 swap_b:3;
u8 mirr_b:1;
@@ -15,16 +33,7 @@ struct tda998x_encoder_params {
u8 swap_e:3;
u8 mirr_e:1;
- u8 audio_cfg;
- u8 audio_clk_cfg;
- u8 audio_frame[6];
-
- enum {
- AFMT_SPDIF,
- AFMT_I2S
- } audio_format;
-
- unsigned audio_sample_rate;
+ struct tda998x_audio_params audio_params;
};
#endif
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
index 6f2c59887ba6..9eb940d6755f 100644
--- a/include/drm/ttm/ttm_bo_api.h
+++ b/include/drm/ttm/ttm_bo_api.h
@@ -45,37 +45,7 @@ struct ttm_bo_device;
struct drm_mm_node;
-/**
- * struct ttm_place
- *
- * @fpfn: first valid page frame number to put the object
- * @lpfn: last valid page frame number to put the object
- * @flags: memory domain and caching flags for the object
- *
- * Structure indicating a possible place to put an object.
- */
-struct ttm_place {
- unsigned fpfn;
- unsigned lpfn;
- uint32_t flags;
-};
-
-/**
- * struct ttm_placement
- *
- * @num_placement: number of preferred placements
- * @placement: preferred placements
- * @num_busy_placement: number of preferred placements when need to evict buffer
- * @busy_placement: preferred placements when need to evict buffer
- *
- * Structure indicating the placement you request for an object.
- */
-struct ttm_placement {
- unsigned num_placement;
- const struct ttm_place *placement;
- unsigned num_busy_placement;
- const struct ttm_place *busy_placement;
-};
+struct ttm_placement;
/**
* struct ttm_bus_placement
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 99c6d01d24f2..4f0a92185995 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -133,7 +133,6 @@ struct ttm_tt {
* struct ttm_dma_tt
*
* @ttm: Base ttm_tt struct.
- * @cpu_address: The CPU address of the pages
* @dma_address: The DMA (bus) addresses of the pages
* @pages_list: used by some page allocation backend
*
@@ -143,7 +142,6 @@ struct ttm_tt {
*/
struct ttm_dma_tt {
struct ttm_tt ttm;
- void **cpu_address;
dma_addr_t *dma_address;
struct list_head pages_list;
};
@@ -961,7 +959,6 @@ void ttm_mem_io_free(struct ttm_bo_device *bdev,
* ttm_bo_move_ttm
*
* @bo: A pointer to a struct ttm_buffer_object.
- * @evict: 1: This is an eviction. Don't try to pipeline.
* @interruptible: Sleep interruptible if waiting.
* @no_wait_gpu: Return immediately if the GPU is busy.
* @new_mem: struct ttm_mem_reg indicating where to move.
@@ -977,14 +974,13 @@ void ttm_mem_io_free(struct ttm_bo_device *bdev,
*/
extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
- bool evict, bool interruptible, bool no_wait_gpu,
+ bool interruptible, bool no_wait_gpu,
struct ttm_mem_reg *new_mem);
/**
* ttm_bo_move_memcpy
*
* @bo: A pointer to a struct ttm_buffer_object.
- * @evict: 1: This is an eviction. Don't try to pipeline.
* @interruptible: Sleep interruptible if waiting.
* @no_wait_gpu: Return immediately if the GPU is busy.
* @new_mem: struct ttm_mem_reg indicating where to move.
@@ -1000,8 +996,7 @@ extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
*/
extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
- bool evict, bool interruptible,
- bool no_wait_gpu,
+ bool interruptible, bool no_wait_gpu,
struct ttm_mem_reg *new_mem);
/**
diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
index 72dcbe81dd07..c4520890f267 100644
--- a/include/drm/ttm/ttm_memory.h
+++ b/include/drm/ttm/ttm_memory.h
@@ -155,4 +155,5 @@ extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
extern void ttm_mem_global_free_page(struct ttm_mem_global *glob,
struct page *page);
extern size_t ttm_round_pot(size_t size);
+extern uint64_t ttm_get_kernel_zone_memory_size(struct ttm_mem_global *glob);
#endif
diff --git a/include/drm/ttm/ttm_placement.h b/include/drm/ttm/ttm_placement.h
index 8ed44f9bbdfb..932be0c8086e 100644
--- a/include/drm/ttm/ttm_placement.h
+++ b/include/drm/ttm/ttm_placement.h
@@ -30,6 +30,9 @@
#ifndef _TTM_PLACEMENT_H_
#define _TTM_PLACEMENT_H_
+
+#include <linux/types.h>
+
/*
* Memory regions for data placement.
*/
@@ -37,24 +40,12 @@
#define TTM_PL_SYSTEM 0
#define TTM_PL_TT 1
#define TTM_PL_VRAM 2
-#define TTM_PL_PRIV0 3
-#define TTM_PL_PRIV1 4
-#define TTM_PL_PRIV2 5
-#define TTM_PL_PRIV3 6
-#define TTM_PL_PRIV4 7
-#define TTM_PL_PRIV5 8
-#define TTM_PL_SWAPPED 15
+#define TTM_PL_PRIV 3
#define TTM_PL_FLAG_SYSTEM (1 << TTM_PL_SYSTEM)
#define TTM_PL_FLAG_TT (1 << TTM_PL_TT)
#define TTM_PL_FLAG_VRAM (1 << TTM_PL_VRAM)
-#define TTM_PL_FLAG_PRIV0 (1 << TTM_PL_PRIV0)
-#define TTM_PL_FLAG_PRIV1 (1 << TTM_PL_PRIV1)
-#define TTM_PL_FLAG_PRIV2 (1 << TTM_PL_PRIV2)
-#define TTM_PL_FLAG_PRIV3 (1 << TTM_PL_PRIV3)
-#define TTM_PL_FLAG_PRIV4 (1 << TTM_PL_PRIV4)
-#define TTM_PL_FLAG_PRIV5 (1 << TTM_PL_PRIV5)
-#define TTM_PL_FLAG_SWAPPED (1 << TTM_PL_SWAPPED)
+#define TTM_PL_FLAG_PRIV (1 << TTM_PL_PRIV)
#define TTM_PL_MASK_MEM 0x0000FFFF
/*
@@ -72,7 +63,6 @@
#define TTM_PL_FLAG_CACHED (1 << 16)
#define TTM_PL_FLAG_UNCACHED (1 << 17)
#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)
@@ -82,14 +72,36 @@
#define TTM_PL_MASK_MEMTYPE (TTM_PL_MASK_MEM | TTM_PL_MASK_CACHING)
-/*
- * Access flags to be used for CPU- and GPU- mappings.
- * The idea is that the TTM synchronization mechanism will
- * allow concurrent READ access and exclusive write access.
- * Currently GPU- and CPU accesses are exclusive.
+/**
+ * struct ttm_place
+ *
+ * @fpfn: first valid page frame number to put the object
+ * @lpfn: last valid page frame number to put the object
+ * @flags: memory domain and caching flags for the object
+ *
+ * Structure indicating a possible place to put an object.
*/
+struct ttm_place {
+ unsigned fpfn;
+ unsigned lpfn;
+ uint32_t flags;
+};
-#define TTM_ACCESS_READ (1 << 0)
-#define TTM_ACCESS_WRITE (1 << 1)
+/**
+ * struct ttm_placement
+ *
+ * @num_placement: number of preferred placements
+ * @placement: preferred placements
+ * @num_busy_placement: number of preferred placements when need to evict buffer
+ * @busy_placement: preferred placements when need to evict buffer
+ *
+ * Structure indicating the placement you request for an object.
+ */
+struct ttm_placement {
+ unsigned num_placement;
+ const struct ttm_place *placement;
+ unsigned num_busy_placement;
+ const struct ttm_place *busy_placement;
+};
#endif