Commit eb84f976 authored by Daniel Vetter's avatar Daniel Vetter

Merge remote-tracking branch 'airlied/drm-next' into HEAD

Backmerge drm-next so that I can keep merging patches. Specifically I
want:
- atomic stuff, yay!
- eld parsing patch from Jani.
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
parents 69f627f5 cc7096fb
...@@ -994,6 +994,10 @@ int max_width, max_height;</synopsis> ...@@ -994,6 +994,10 @@ int max_width, max_height;</synopsis>
<title>Display Modes Function Reference</title> <title>Display Modes Function Reference</title>
!Iinclude/drm/drm_modes.h !Iinclude/drm/drm_modes.h
!Edrivers/gpu/drm/drm_modes.c !Edrivers/gpu/drm/drm_modes.c
</sect2>
<sect2>
<title>Atomic Mode Setting Function Reference</title>
!Edrivers/gpu/drm/drm_atomic.c
</sect2> </sect2>
<sect2> <sect2>
<title>Frame Buffer Creation</title> <title>Frame Buffer Creation</title>
...@@ -1825,6 +1829,10 @@ void intel_crt_init(struct drm_device *dev) ...@@ -1825,6 +1829,10 @@ void intel_crt_init(struct drm_device *dev)
<sect2> <sect2>
<title>KMS API Functions</title> <title>KMS API Functions</title>
!Edrivers/gpu/drm/drm_crtc.c !Edrivers/gpu/drm/drm_crtc.c
</sect2>
<sect2>
<title>KMS Data Structures</title>
!Iinclude/drm/drm_crtc.h
</sect2> </sect2>
<sect2> <sect2>
<title>KMS Locking</title> <title>KMS Locking</title>
...@@ -2315,9 +2323,26 @@ void intel_crt_init(struct drm_device *dev) ...@@ -2315,9 +2323,26 @@ void intel_crt_init(struct drm_device *dev)
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</sect2> </sect2>
<sect2>
<title>Atomic Modeset Helper Functions Reference</title>
<sect3>
<title>Overview</title>
!Pdrivers/gpu/drm/drm_atomic_helper.c overview
</sect3>
<sect3>
<title>Implementing Asynchronous Atomic Commit</title>
!Pdrivers/gpu/drm/drm_atomic_helper.c implementing async commit
</sect3>
<sect3>
<title>Atomic State Reset and Initialization</title>
!Pdrivers/gpu/drm/drm_atomic_helper.c atomic state reset and initialization
</sect3>
!Edrivers/gpu/drm/drm_atomic_helper.c
</sect2>
<sect2> <sect2>
<title>Modeset Helper Functions Reference</title> <title>Modeset Helper Functions Reference</title>
!Edrivers/gpu/drm/drm_crtc_helper.c !Edrivers/gpu/drm/drm_crtc_helper.c
!Pdrivers/gpu/drm/drm_crtc_helper.c overview
</sect2> </sect2>
<sect2> <sect2>
<title>Output Probing Helper Functions Reference</title> <title>Output Probing Helper Functions Reference</title>
...@@ -2371,7 +2396,8 @@ void intel_crt_init(struct drm_device *dev) ...@@ -2371,7 +2396,8 @@ void intel_crt_init(struct drm_device *dev)
</sect2> </sect2>
<sect2> <sect2>
<title id="drm-kms-planehelpers">Plane Helper Reference</title> <title id="drm-kms-planehelpers">Plane Helper Reference</title>
!Edrivers/gpu/drm/drm_plane_helper.c Plane Helpers !Edrivers/gpu/drm/drm_plane_helper.c
!Pdrivers/gpu/drm/drm_plane_helper.c overview
</sect2> </sect2>
</sect1> </sect1>
...@@ -2508,7 +2534,7 @@ void intel_crt_init(struct drm_device *dev) ...@@ -2508,7 +2534,7 @@ void intel_crt_init(struct drm_device *dev)
</tr> </tr>
<tr> <tr>
<td rowspan="21" valign="top" >DRM</td> <td rowspan="21" valign="top" >DRM</td>
<td rowspan="2" valign="top" >Generic</td> <td rowspan="3" valign="top" >Generic</td>
<td valign="top" >“EDID”</td> <td valign="top" >“EDID”</td>
<td valign="top" >BLOB | IMMUTABLE</td> <td valign="top" >BLOB | IMMUTABLE</td>
<td valign="top" >0</td> <td valign="top" >0</td>
...@@ -2523,6 +2549,13 @@ void intel_crt_init(struct drm_device *dev) ...@@ -2523,6 +2549,13 @@ void intel_crt_init(struct drm_device *dev)
<td valign="top" >Contains DPMS operation mode value.</td> <td valign="top" >Contains DPMS operation mode value.</td>
</tr> </tr>
<tr> <tr>
<td valign="top" >“PATH”</td>
<td valign="top" >BLOB | IMMUTABLE</td>
<td valign="top" >0</td>
<td valign="top" >Connector</td>
<td valign="top" >Contains topology path to a connector.</td>
</tr>
<tr>
<td rowspan="1" valign="top" >Plane</td> <td rowspan="1" valign="top" >Plane</td>
<td valign="top" >“type”</td> <td valign="top" >“type”</td>
<td valign="top" >ENUM | IMMUTABLE</td> <td valign="top" >ENUM | IMMUTABLE</td>
......
...@@ -14,7 +14,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ ...@@ -14,7 +14,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_info.o drm_debugfs.o drm_encoder_slave.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \
drm_trace_points.o drm_global.o drm_prime.o \ drm_trace_points.o drm_global.o drm_prime.o \
drm_rect.o drm_vma_manager.o drm_flip_work.o \ drm_rect.o drm_vma_manager.o drm_flip_work.o \
drm_modeset_lock.o drm_modeset_lock.o drm_atomic.o
drm-$(CONFIG_COMPAT) += drm_ioc32.o drm-$(CONFIG_COMPAT) += drm_ioc32.o
drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
...@@ -23,7 +23,7 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o ...@@ -23,7 +23,7 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o
drm-$(CONFIG_OF) += drm_of.o drm-$(CONFIG_OF) += drm_of.o
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
drm_plane_helper.o drm_dp_mst_topology.o drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
......
************************************************************
* For the very latest on DRI development, please see: *
* http://dri.freedesktop.org/ *
************************************************************
The Direct Rendering Manager (drm) is a device-independent kernel-level
device driver that provides support for the XFree86 Direct Rendering
Infrastructure (DRI).
The DRM supports the Direct Rendering Infrastructure (DRI) in four major
ways:
1. The DRM provides synchronized access to the graphics hardware via
the use of an optimized two-tiered lock.
2. The DRM enforces the DRI security policy for access to the graphics
hardware by only allowing authenticated X11 clients access to
restricted regions of memory.
3. The DRM provides a generic DMA engine, complete with multiple
queues and the ability to detect the need for an OpenGL context
switch.
4. The DRM is extensible via the use of small device-specific modules
that rely extensively on the API exported by the DRM module.
Documentation on the DRI is available from:
http://dri.freedesktop.org/wiki/Documentation
http://sourceforge.net/project/showfiles.php?group_id=387
http://dri.sourceforge.net/doc/
For specific information about kernel-level support, see:
The Direct Rendering Manager, Kernel Support for the Direct Rendering
Infrastructure
http://dri.sourceforge.net/doc/drm_low_level.html
Hardware Locking for the Direct Rendering Infrastructure
http://dri.sourceforge.net/doc/hardware_locking_low_level.html
A Security Analysis of the Direct Rendering Infrastructure
http://dri.sourceforge.net/doc/security_low_level.html
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include "armada_crtc.h" #include "armada_crtc.h"
#include "armada_drm.h" #include "armada_drm.h"
#include "armada_fb.h" #include "armada_fb.h"
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include "ast_drv.h" #include "ast_drv.h"
#include "ast_tables.h" #include "ast_tables.h"
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
*/ */
#include "bochs.h" #include "bochs.h"
#include <drm/drm_plane_helper.h>
static int defx = 1024; static int defx = 1024;
static int defy = 768; static int defy = 768;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
*/ */
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include <video/cirrus.h> #include <video/cirrus.h>
......
This diff is collapsed.
This diff is collapsed.
...@@ -766,7 +766,6 @@ static void drm_mode_remove(struct drm_connector *connector, ...@@ -766,7 +766,6 @@ static void drm_mode_remove(struct drm_connector *connector,
/** /**
* drm_connector_get_cmdline_mode - reads the user's cmdline mode * drm_connector_get_cmdline_mode - reads the user's cmdline mode
* @connector: connector to quwery * @connector: connector to quwery
* @mode: returned mode
* *
* The kernel supports per-connector configration of its consoles through * The kernel supports per-connector configration of its consoles through
* use of the video= parameter. This function parses that option and * use of the video= parameter. This function parses that option and
...@@ -2943,7 +2942,7 @@ EXPORT_SYMBOL(drm_mode_legacy_fb_format); ...@@ -2943,7 +2942,7 @@ EXPORT_SYMBOL(drm_mode_legacy_fb_format);
* @file_priv: drm file for the ioctl call * @file_priv: drm file for the ioctl call
* *
* Add a new FB to the specified CRTC, given a user request. This is the * Add a new FB to the specified CRTC, given a user request. This is the
* original addfb ioclt which only supported RGB formats. * original addfb ioctl which only supported RGB formats.
* *
* Called by the user via ioctl. * Called by the user via ioctl.
* *
...@@ -2955,11 +2954,9 @@ int drm_mode_addfb(struct drm_device *dev, ...@@ -2955,11 +2954,9 @@ int drm_mode_addfb(struct drm_device *dev,
{ {
struct drm_mode_fb_cmd *or = data; struct drm_mode_fb_cmd *or = data;
struct drm_mode_fb_cmd2 r = {}; struct drm_mode_fb_cmd2 r = {};
struct drm_mode_config *config = &dev->mode_config; int ret;
struct drm_framebuffer *fb;
int ret = 0;
/* Use new struct with format internally */ /* convert to new format and call new ioctl */
r.fb_id = or->fb_id; r.fb_id = or->fb_id;
r.width = or->width; r.width = or->width;
r.height = or->height; r.height = or->height;
...@@ -2967,26 +2964,11 @@ int drm_mode_addfb(struct drm_device *dev, ...@@ -2967,26 +2964,11 @@ int drm_mode_addfb(struct drm_device *dev,
r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
r.handles[0] = or->handle; r.handles[0] = or->handle;
if (!drm_core_check_feature(dev, DRIVER_MODESET)) ret = drm_mode_addfb2(dev, &r, file_priv);
return -EINVAL; if (ret)
return ret;
if ((config->min_width > r.width) || (r.width > config->max_width))
return -EINVAL;
if ((config->min_height > r.height) || (r.height > config->max_height))
return -EINVAL;
fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
if (IS_ERR(fb)) {
DRM_DEBUG_KMS("could not create framebuffer\n");
return PTR_ERR(fb);
}
mutex_lock(&file_priv->fbs_lock); or->fb_id = r.fb_id;
or->fb_id = fb->base.id;
list_add(&fb->filp_head, &file_priv->fbs);
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
mutex_unlock(&file_priv->fbs_lock);
return ret; return ret;
} }
...@@ -3080,7 +3062,7 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) ...@@ -3080,7 +3062,7 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
num_planes = drm_format_num_planes(r->pixel_format); num_planes = drm_format_num_planes(r->pixel_format);
if (r->width == 0 || r->width % hsub) { if (r->width == 0 || r->width % hsub) {
DRM_DEBUG_KMS("bad framebuffer width %u\n", r->height); DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
return -EINVAL; return -EINVAL;
} }
...@@ -3435,6 +3417,10 @@ void drm_fb_release(struct drm_file *priv) ...@@ -3435,6 +3417,10 @@ void drm_fb_release(struct drm_file *priv)
* object with drm_object_attach_property. The returned property object must be * object with drm_object_attach_property. The returned property object must be
* freed with drm_property_destroy. * freed with drm_property_destroy.
* *
* Note that the DRM core keeps a per-device list of properties and that, if
* drm_mode_config_cleanup() is called, it will destroy all properties created
* by the driver.
*
* Returns: * Returns:
* A pointer to the newly created property on success, NULL on failure. * A pointer to the newly created property on success, NULL on failure.
*/ */
...@@ -3611,7 +3597,7 @@ static struct drm_property *property_create_range(struct drm_device *dev, ...@@ -3611,7 +3597,7 @@ static struct drm_property *property_create_range(struct drm_device *dev,
* object with drm_object_attach_property. The returned property object must be * object with drm_object_attach_property. The returned property object must be
* freed with drm_property_destroy. * freed with drm_property_destroy.
* *
* Userspace is allowed to set any interger value in the (min, max) range * Userspace is allowed to set any integer value in the (min, max) range
* inclusive. * inclusive.
* *
* Returns: * Returns:
...@@ -4019,6 +4005,19 @@ int drm_mode_getblob_ioctl(struct drm_device *dev, ...@@ -4019,6 +4005,19 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
return ret; return ret;
} }
/**
* drm_mode_connector_set_path_property - set tile property on connector
* @connector: connector to set property on.
* @path: path to use for property.
*
* This creates a property to expose to userspace to specify a
* connector path. This is mainly used for DisplayPort MST where
* connectors have a topology and we want to allow userspace to give
* them more meaningful names.
*
* Returns:
* Zero on success, errno on failure.
*/
int drm_mode_connector_set_path_property(struct drm_connector *connector, int drm_mode_connector_set_path_property(struct drm_connector *connector,
char *path) char *path)
{ {
......
...@@ -34,12 +34,35 @@ ...@@ -34,12 +34,35 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_atomic.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_fourcc.h> #include <drm/drm_fourcc.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
/**
* DOC: overview
*
* The CRTC modeset helper library provides a default set_config implementation
* in drm_crtc_helper_set_config(). Plus a few other convenience functions using
* the same callbacks which drivers can use to e.g. restore the modeset
* configuration on resume with drm_helper_resume_force_mode().
*
* The driver callbacks are mostly compatible with the atomic modeset helpers,
* except for the handling of the primary plane: Atomic helpers require that the
* primary plane is implemented as a real standalone plane and not directly tied
* to the CRTC state. For easier transition this library provides functions to
* implement the old semantics required by the CRTC helpers using the new plane
* and atomic helper callbacks.
*
* Drivers are strongly urged to convert to the atomic helpers (by way of first
* converting to the plane helpers). New drivers must not use these functions
* but need to implement the atomic interface instead, potentially using the
* atomic helpers for that.
*/
MODULE_AUTHOR("David Airlie, Jesse Barnes"); MODULE_AUTHOR("David Airlie, Jesse Barnes");
MODULE_DESCRIPTION("DRM KMS helper"); MODULE_DESCRIPTION("DRM KMS helper");
MODULE_LICENSE("GPL and additional rights"); MODULE_LICENSE("GPL and additional rights");
...@@ -888,3 +911,112 @@ void drm_helper_resume_force_mode(struct drm_device *dev) ...@@ -888,3 +911,112 @@ void drm_helper_resume_force_mode(struct drm_device *dev)
drm_modeset_unlock_all(dev); drm_modeset_unlock_all(dev);
} }
EXPORT_SYMBOL(drm_helper_resume_force_mode); EXPORT_SYMBOL(drm_helper_resume_force_mode);
/**
* drm_helper_crtc_mode_set - mode_set implementation for atomic plane helpers
* @crtc: DRM CRTC
* @mode: DRM display mode which userspace requested
* @adjusted_mode: DRM display mode adjusted by ->mode_fixup callbacks
* @x: x offset of the CRTC scanout area on the underlying framebuffer
* @y: y offset of the CRTC scanout area on the underlying framebuffer
* @old_fb: previous framebuffer
*
* This function implements a callback useable as the ->mode_set callback
* required by the crtc helpers. Besides the atomic plane helper functions for
* the primary plane the driver must also provide the ->mode_set_nofb callback
* to set up the crtc.
*
* This is a transitional helper useful for converting drivers to the atomic
* interfaces.
*/
int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode, int x, int y,
struct drm_framebuffer *old_fb)
{
struct drm_crtc_state *crtc_state;
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
int ret;
if (crtc->funcs->atomic_duplicate_state)
crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
else if (crtc->state)
crtc_state = kmemdup(crtc->state, sizeof(*crtc_state),
GFP_KERNEL);
else
crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
if (!crtc_state)
return -ENOMEM;
crtc_state->enable = true;
crtc_state->planes_changed = true;
crtc_state->mode_changed = true;
drm_mode_copy(&crtc_state->mode, mode);
drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode);
if (crtc_funcs->atomic_check) {
ret = crtc_funcs->atomic_check(crtc, crtc_state);
if (ret) {
kfree(crtc_state);
return ret;
}
}
swap(crtc->state, crtc_state);
crtc_funcs->mode_set_nofb(crtc);
if (crtc_state) {
if (crtc->funcs->atomic_destroy_state)
crtc->funcs->atomic_destroy_state(crtc, crtc_state);
else
kfree(crtc_state);
}
return drm_helper_crtc_mode_set_base(crtc, x, y, old_fb);
}
EXPORT_SYMBOL(drm_helper_crtc_mode_set);
/**
* drm_helper_crtc_mode_set_base - mode_set_base implementation for atomic plane helpers
* @crtc: DRM CRTC
* @x: x offset of the CRTC scanout area on the underlying framebuffer
* @y: y offset of the CRTC scanout area on the underlying framebuffer
* @old_fb: previous framebuffer
*
* This function implements a callback useable as the ->mode_set_base used
* required by the crtc helpers. The driver must provide the atomic plane helper
* functions for the primary plane.
*
* This is a transitional helper useful for converting drivers to the atomic
* interfaces.
*/
int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
struct drm_plane_state *plane_state;
struct drm_plane *plane = crtc->primary;
if (plane->funcs->atomic_duplicate_state)
plane_state = plane->funcs->atomic_duplicate_state(plane);
else if (plane->state)
plane_state = drm_atomic_helper_plane_duplicate_state(plane);
else
plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
if (!plane_state)
return -ENOMEM;
plane_state->crtc = crtc;
drm_atomic_set_fb_for_plane(plane_state, crtc->primary->fb);
plane_state->crtc_x = 0;
plane_state->crtc_y = 0;
plane_state->crtc_h = crtc->mode.vdisplay;
plane_state->crtc_w = crtc->mode.hdisplay;
plane_state->src_x = x << 16;
plane_state->src_y = y << 16;
plane_state->src_h = crtc->mode.vdisplay << 16;
plane_state->src_w = crtc->mode.hdisplay << 16;
return drm_plane_helper_commit(plane, plane_state, old_fb);
}
EXPORT_SYMBOL(drm_helper_crtc_mode_set_base);
...@@ -39,198 +39,6 @@ ...@@ -39,198 +39,6 @@
* blocks, ... * blocks, ...
*/ */
/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
static int
i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
uint8_t write_byte, uint8_t *read_byte)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
int ret;
ret = (*algo_data->aux_ch)(adapter, mode,
write_byte, read_byte);
return ret;
}
/*
* I2C over AUX CH
*/
/*
* Send the address. If the I2C link is running, this 'restarts'
* the connection with the new address, this is used for doing
* a write followed by a read (as needed for DDC)
*/
static int
i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
int mode = MODE_I2C_START;
int ret;
if (reading)
mode |= MODE_I2C_READ;
else
mode |= MODE_I2C_WRITE;
algo_data->address = address;
algo_data->running = true;
ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
return ret;
}
/*
* Stop the I2C transaction. This closes out the link, sending
* a bare address packet with the MOT bit turned off
*/
static void
i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
int mode = MODE_I2C_STOP;
if (reading)
mode |= MODE_I2C_READ;
else
mode |= MODE_I2C_WRITE;
if (algo_data->running) {
(void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
algo_data->running = false;
}
}
/*
* Write a single byte to the current I2C address, the
* the I2C link must be running or this returns -EIO
*/
static int
i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
int ret;
if (!algo_data->running)
return -EIO;
ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
return ret;
}
/*
* Read a single byte from the current I2C address, the
* I2C link must be running or this returns -EIO
*/
static int
i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
int ret;
if (!algo_data->running)
return -EIO;
ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
return ret;
}
static int
i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
struct i2c_msg *msgs,
int num)
{
int ret = 0;
bool reading = false;
int m;
int b;
for (m = 0; m < num; m++) {
u16 len = msgs[m].len;
u8 *buf = msgs[m].buf;
reading = (msgs[m].flags & I2C_M_RD) != 0;
ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
if (ret < 0)
break;
if (reading) {
for (b = 0; b < len; b++) {
ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
if (ret < 0)
break;
}
} else {
for (b = 0; b < len; b++) {
ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
if (ret < 0)
break;
}
}
if (ret < 0)
break;
}
if (ret >= 0)
ret = num;
i2c_algo_dp_aux_stop(adapter, reading);
DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret);
return ret;
}
static u32
i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
I2C_FUNC_SMBUS_READ_BLOCK_DATA |
I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
I2C_FUNC_10BIT_ADDR;
}
static const struct i2c_algorithm i2c_dp_aux_algo = {
.master_xfer = i2c_algo_dp_aux_xfer,
.functionality = i2c_algo_dp_aux_functionality,
};
static void
i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
{
(void) i2c_algo_dp_aux_address(adapter, 0, false);
(void) i2c_algo_dp_aux_stop(adapter, false);
}
static int
i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
{
adapter->algo = &i2c_dp_aux_algo;
adapter->retries = 3;
i2c_dp_aux_reset_bus(adapter);
return 0;
}
/**
* i2c_dp_aux_add_bus() - register an i2c adapter using the aux ch helper
* @adapter: i2c adapter to register
*
* This registers an i2c adapter that uses dp aux channel as it's underlaying
* transport. The driver needs to fill out the &i2c_algo_dp_aux_data structure
* and store it in the algo_data member of the @adapter argument. This will be
* used by the i2c over dp aux algorithm to drive the hardware.
*
* RETURNS:
* 0 on success, -ERRNO on failure.
*
* IMPORTANT:
* This interface is deprecated, please switch to the new dp aux helpers and
* drm_dp_aux_register().
*/
int
i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
{
int error;
error = i2c_dp_aux_prepare_bus(adapter);
if (error)
return error;
error = i2c_add_adapter(adapter);
return error;
}
EXPORT_SYMBOL(i2c_dp_aux_add_bus);
/* Helpers for DP link training */ /* Helpers for DP link training */
static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r) static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
{ {
...@@ -654,10 +462,12 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) ...@@ -654,10 +462,12 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
case DP_AUX_I2C_REPLY_NACK: case DP_AUX_I2C_REPLY_NACK:
DRM_DEBUG_KMS("I2C nack\n"); DRM_DEBUG_KMS("I2C nack\n");
aux->i2c_nack_count++;
return -EREMOTEIO; return -EREMOTEIO;
case DP_AUX_I2C_REPLY_DEFER: case DP_AUX_I2C_REPLY_DEFER:
DRM_DEBUG_KMS("I2C defer\n"); DRM_DEBUG_KMS("I2C defer\n");
aux->i2c_defer_count++;
usleep_range(400, 500); usleep_range(400, 500);
continue; continue;
......
...@@ -1011,19 +1011,20 @@ static void drm_dp_check_port_guid(struct drm_dp_mst_branch *mstb, ...@@ -1011,19 +1011,20 @@ static void drm_dp_check_port_guid(struct drm_dp_mst_branch *mstb,
static void build_mst_prop_path(struct drm_dp_mst_port *port, static void build_mst_prop_path(struct drm_dp_mst_port *port,
struct drm_dp_mst_branch *mstb, struct drm_dp_mst_branch *mstb,
char *proppath) char *proppath,
size_t proppath_size)
{ {
int i; int i;
char temp[8]; char temp[8];
snprintf(proppath, 255, "mst:%d", mstb->mgr->conn_base_id); snprintf(proppath, proppath_size, "mst:%d", mstb->mgr->conn_base_id);
for (i = 0; i < (mstb->lct - 1); i++) { for (i = 0; i < (mstb->lct - 1); i++) {
int shift = (i % 2) ? 0 : 4; int shift = (i % 2) ? 0 : 4;
int port_num = mstb->rad[i / 2] >> shift; int port_num = mstb->rad[i / 2] >> shift;
snprintf(temp, 8, "-%d", port_num); snprintf(temp, sizeof(temp), "-%d", port_num);
strncat(proppath, temp, 255); strlcat(proppath, temp, proppath_size);
} }
snprintf(temp, 8, "-%d", port->port_num); snprintf(temp, sizeof(temp), "-%d", port->port_num);
strncat(proppath, temp, 255); strlcat(proppath, temp, proppath_size);
} }
static void drm_dp_add_port(struct drm_dp_mst_branch *mstb, static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
...@@ -1094,7 +1095,7 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb, ...@@ -1094,7 +1095,7 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
if (created && !port->input) { if (created && !port->input) {
char proppath[255]; char proppath[255];
build_mst_prop_path(port, mstb, proppath); build_mst_prop_path(port, mstb, proppath, sizeof(proppath));
port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath); port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath);
} }
......
...@@ -56,7 +56,7 @@ static struct idr drm_minors_idr; ...@@ -56,7 +56,7 @@ static struct idr drm_minors_idr;
struct class *drm_class; struct class *drm_class;
static struct dentry *drm_debugfs_root; static struct dentry *drm_debugfs_root;
void drm_err(const char *func, const char *format, ...) void drm_err(const char *format, ...)
{ {
struct va_format vaf; struct va_format vaf;
va_list args; va_list args;
...@@ -66,7 +66,8 @@ void drm_err(const char *func, const char *format, ...) ...@@ -66,7 +66,8 @@ void drm_err(const char *func, const char *format, ...)
vaf.fmt = format; vaf.fmt = format;
vaf.va = &args; vaf.va = &args;
printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* %pV", func, &vaf); printk(KERN_ERR "[" DRM_NAME ":%pf] *ERROR* %pV",
__builtin_return_address(0), &vaf);
va_end(args); va_end(args);
} }
......
...@@ -1570,7 +1570,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) ...@@ -1570,7 +1570,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
modeset = &fb_helper->crtc_info[i].mode_set; modeset = &fb_helper->crtc_info[i].mode_set;
if (modeset->num_connectors == 0) { if (modeset->num_connectors == 0) {
BUG_ON(modeset->fb); BUG_ON(modeset->fb);
BUG_ON(modeset->num_connectors);
if (modeset->mode) if (modeset->mode)
drm_mode_destroy(dev, modeset->mode); drm_mode_destroy(dev, modeset->mode);
modeset->mode = NULL; modeset->mode = NULL;
......
...@@ -515,10 +515,12 @@ ssize_t drm_read(struct file *filp, char __user *buffer, ...@@ -515,10 +515,12 @@ ssize_t drm_read(struct file *filp, char __user *buffer,
size_t total; size_t total;
ssize_t ret; ssize_t ret;
if ((filp->f_flags & O_NONBLOCK) == 0) {
ret = wait_event_interruptible(file_priv->event_wait, ret = wait_event_interruptible(file_priv->event_wait,
!list_empty(&file_priv->event_list)); !list_empty(&file_priv->event_list));
if (ret < 0) if (ret < 0)
return ret; return ret;
}
total = 0; total = 0;
while (drm_dequeue_event(file_priv, total, count, &e)) { while (drm_dequeue_event(file_priv, total, count, &e)) {
...@@ -532,7 +534,7 @@ ssize_t drm_read(struct file *filp, char __user *buffer, ...@@ -532,7 +534,7 @@ ssize_t drm_read(struct file *filp, char __user *buffer,
e->destroy(e); e->destroy(e);
} }
return total; return total ?: -EAGAIN;
} }
EXPORT_SYMBOL(drm_read); EXPORT_SYMBOL(drm_read);
......
...@@ -1190,7 +1190,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_off); ...@@ -1190,7 +1190,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_off);
* *
* This functions restores the vblank interrupt state captured with * This functions restores the vblank interrupt state captured with
* drm_vblank_off() again. Note that calls to drm_vblank_on() and * drm_vblank_off() again. Note that calls to drm_vblank_on() and
* drm_vblank_off() can be unbalanced and so can also be unconditionaly called * drm_vblank_off() can be unbalanced and so can also be unconditionally called
* in driver load code to reflect the current hardware state of the crtc. * in driver load code to reflect the current hardware state of the crtc.
* *
* This is the legacy version of drm_crtc_vblank_on(). * This is the legacy version of drm_crtc_vblank_on().
...@@ -1237,7 +1237,7 @@ EXPORT_SYMBOL(drm_vblank_on); ...@@ -1237,7 +1237,7 @@ EXPORT_SYMBOL(drm_vblank_on);
* *
* This functions restores the vblank interrupt state captured with * This functions restores the vblank interrupt state captured with
* drm_vblank_off() again. Note that calls to drm_vblank_on() and * drm_vblank_off() again. Note that calls to drm_vblank_on() and
* drm_vblank_off() can be unbalanced and so can also be unconditionaly called * drm_vblank_off() can be unbalanced and so can also be unconditionally called
* in driver load code to reflect the current hardware state of the crtc. * in driver load code to reflect the current hardware state of the crtc.
* *
* This is the native kms version of drm_vblank_on(). * This is the native kms version of drm_vblank_on().
......
...@@ -914,7 +914,7 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo); ...@@ -914,7 +914,7 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
* *
* This function is a helper which can be used to validate modes against size * This function is a helper which can be used to validate modes against size
* limitations of the DRM device/connector. If a mode is too big its status * limitations of the DRM device/connector. If a mode is too big its status
* memeber is updated with the appropriate validation failure code. The list * member is updated with the appropriate validation failure code. The list
* itself is not changed. * itself is not changed.
*/ */
void drm_mode_validate_size(struct drm_device *dev, void drm_mode_validate_size(struct drm_device *dev,
......
...@@ -27,10 +27,38 @@ ...@@ -27,10 +27,38 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_plane_helper.h> #include <drm/drm_plane_helper.h>
#include <drm/drm_rect.h> #include <drm/drm_rect.h>
#include <drm/drm_plane_helper.h> #include <drm/drm_atomic.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_atomic_helper.h>
#define SUBPIXEL_MASK 0xffff #define SUBPIXEL_MASK 0xffff
/**
* DOC: overview
*
* This helper library has two parts. The first part has support to implement
* primary plane support on top of the normal CRTC configuration interface.
* Since the legacy ->set_config interface ties the primary plane together with
* the CRTC state this does not allow userspace to disable the primary plane
* itself. To avoid too much duplicated code use
* drm_plane_helper_check_update() which can be used to enforce the same
* restrictions as primary planes had thus. The default primary plane only
* expose XRBG8888 and ARGB8888 as valid pixel formats for the attached
* framebuffer.
*
* Drivers are highly recommended to implement proper support for primary
* planes, and newly merged drivers must not rely upon these transitional
* helpers.
*
* The second part also implements transitional helpers which allow drivers to
* gradually switch to the atomic helper infrastructure for plane updates. Once
* that switch is complete drivers shouldn't use these any longer, instead using
* the proper legacy implementations for update and disable plane hooks provided
* by the atomic helpers.
*
* Again drivers are strongly urged to switch to the new interfaces.
*/
/* /*
* This is the minimal list of formats that seem to be safe for modeset use * This is the minimal list of formats that seem to be safe for modeset use
* with all current DRM drivers. Most hardware can actually support more * with all current DRM drivers. Most hardware can actually support more
...@@ -374,3 +402,171 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, ...@@ -374,3 +402,171 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs); return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs);
} }
EXPORT_SYMBOL(drm_crtc_init); EXPORT_SYMBOL(drm_crtc_init);
int drm_plane_helper_commit(struct drm_plane *plane,
struct drm_plane_state *plane_state,
struct drm_framebuffer *old_fb)
{
struct drm_plane_helper_funcs *plane_funcs;
struct drm_crtc *crtc[2];
struct drm_crtc_helper_funcs *crtc_funcs[2];
int i, ret = 0;
plane_funcs = plane->helper_private;
/* Since this is a transitional helper we can't assume that plane->state
* is always valid. Hence we need to use plane->crtc instead of
* plane->state->crtc as the old crtc. */
crtc[0] = plane->crtc;
crtc[1] = crtc[0] != plane_state->crtc ? plane_state->crtc : NULL;
for (i = 0; i < 2; i++)
crtc_funcs[i] = crtc[i] ? crtc[i]->helper_private : NULL;
if (plane_funcs->atomic_check) {
ret = plane_funcs->atomic_check(plane, plane_state);
if (ret)
goto out;
}
if (plane_funcs->prepare_fb && plane_state->fb) {
ret = plane_funcs->prepare_fb(plane, plane_state->fb);
if (ret)
goto out;
}
/* Point of no return, commit sw state. */
swap(plane->state, plane_state);
for (i = 0; i < 2; i++) {
if (crtc_funcs[i] && crtc_funcs[i]->atomic_begin)
crtc_funcs[i]->atomic_begin(crtc[i]);
}
plane_funcs->atomic_update(plane);
for (i = 0; i < 2; i++) {
if (crtc_funcs[i] && crtc_funcs[i]->atomic_flush)
crtc_funcs[i]->atomic_flush(crtc[i]);
}
for (i = 0; i < 2; i++) {
if (!crtc[i])
continue;
/* There's no other way to figure out whether the crtc is running. */
ret = drm_crtc_vblank_get(crtc[i]);
if (ret == 0) {
drm_crtc_wait_one_vblank(crtc[i]);
drm_crtc_vblank_put(crtc[i]);
}
ret = 0;
}
if (plane_funcs->cleanup_fb && old_fb)
plane_funcs->cleanup_fb(plane, old_fb);
out:
if (plane_state) {
if (plane->funcs->atomic_destroy_state)
plane->funcs->atomic_destroy_state(plane, plane_state);
else
drm_atomic_helper_plane_destroy_state(plane, plane_state);
}
return ret;
}
/**
* drm_plane_helper_update() - Helper for primary plane update
* @plane: plane object to update
* @crtc: owning CRTC of owning plane
* @fb: framebuffer to flip onto plane
* @crtc_x: x offset of primary plane on crtc
* @crtc_y: y offset of primary plane on crtc
* @crtc_w: width of primary plane rectangle on crtc
* @crtc_h: height of primary plane rectangle on crtc
* @src_x: x offset of @fb for panning
* @src_y: y offset of @fb for panning
* @src_w: width of source rectangle in @fb
* @src_h: height of source rectangle in @fb
*
* Provides a default plane update handler using the atomic plane update
* functions. It is fully left to the driver to check plane constraints and
* handle corner-cases like a fully occluded or otherwise invisible plane.
*
* This is useful for piecewise transitioning of a driver to the atomic helpers.
*
* RETURNS:
* Zero on success, error code on failure
*/
int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h)
{
struct drm_plane_state *plane_state;
if (plane->funcs->atomic_duplicate_state)
plane_state = plane->funcs->atomic_duplicate_state(plane);
else if (plane->state)
plane_state = drm_atomic_helper_plane_duplicate_state(plane);
else
plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
if (!plane_state)
return -ENOMEM;
plane_state->crtc = crtc;
drm_atomic_set_fb_for_plane(plane_state, fb);
plane_state->crtc_x = crtc_x;
plane_state->crtc_y = crtc_y;
plane_state->crtc_h = crtc_h;
plane_state->crtc_w = crtc_w;
plane_state->src_x = src_x;
plane_state->src_y = src_y;
plane_state->src_h = src_h;
plane_state->src_w = src_w;
return drm_plane_helper_commit(plane, plane_state, plane->fb);
}
EXPORT_SYMBOL(drm_plane_helper_update);
/**
* drm_plane_helper_disable() - Helper for primary plane disable
* @plane: plane to disable
*
* Provides a default plane disable handler using the atomic plane update
* functions. It is fully left to the driver to check plane constraints and
* handle corner-cases like a fully occluded or otherwise invisible plane.
*
* This is useful for piecewise transitioning of a driver to the atomic helpers.
*
* RETURNS:
* Zero on success, error code on failure
*/
int drm_plane_helper_disable(struct drm_plane *plane)
{
struct drm_plane_state *plane_state;
/* crtc helpers love to call disable functions for already disabled hw
* functions. So cope with that. */
if (!plane->crtc)
return 0;
if (plane->funcs->atomic_duplicate_state)
plane_state = plane->funcs->atomic_duplicate_state(plane);
else if (plane->state)
plane_state = drm_atomic_helper_plane_duplicate_state(plane);
else
plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
if (!plane_state)
return -ENOMEM;
plane_state->crtc = NULL;
drm_atomic_set_fb_for_plane(plane_state, NULL);
return drm_plane_helper_commit(plane, plane_state, plane->fb);
}
EXPORT_SYMBOL(drm_plane_helper_disable);
...@@ -328,7 +328,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { ...@@ -328,7 +328,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
*/ */
/** /**
* drm_gem_prime_export - helper library implemention of the export callback * drm_gem_prime_export - helper library implementation of the export callback
* @dev: drm_device to export from * @dev: drm_device to export from
* @obj: GEM object to export * @obj: GEM object to export
* @flags: flags like DRM_CLOEXEC * @flags: flags like DRM_CLOEXEC
...@@ -483,7 +483,7 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev, ...@@ -483,7 +483,7 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);
/** /**
* drm_gem_prime_import - helper library implemention of the import callback * drm_gem_prime_import - helper library implementation of the import callback
* @dev: drm_device to import into * @dev: drm_device to import into
* @dma_buf: dma-buf object to import * @dma_buf: dma-buf object to import
* *
......
...@@ -118,7 +118,8 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect ...@@ -118,7 +118,8 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
mode->status = MODE_UNVERIFIED; mode->status = MODE_UNVERIFIED;
if (connector->force) { if (connector->force) {
if (connector->force == DRM_FORCE_ON) if (connector->force == DRM_FORCE_ON ||
connector->force == DRM_FORCE_ON_DIGITAL)
connector->status = connector_status_connected; connector->status = connector_status_connected;
else else
connector->status = connector_status_disconnected; connector->status = connector_status_disconnected;
......
...@@ -37,6 +37,201 @@ ...@@ -37,6 +37,201 @@
#include "gma_display.h" #include "gma_display.h"
#include <drm/drm_dp_helper.h> #include <drm/drm_dp_helper.h>
/**
* struct i2c_algo_dp_aux_data - driver interface structure for i2c over dp
* aux algorithm
* @running: set by the algo indicating whether an i2c is ongoing or whether
* the i2c bus is quiescent
* @address: i2c target address for the currently ongoing transfer
* @aux_ch: driver callback to transfer a single byte of the i2c payload
*/
struct i2c_algo_dp_aux_data {
bool running;
u16 address;
int (*aux_ch) (struct i2c_adapter *adapter,
int mode, uint8_t write_byte,
uint8_t *read_byte);
};
/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
static int
i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
uint8_t write_byte, uint8_t *read_byte)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
int ret;
ret = (*algo_data->aux_ch)(adapter, mode,
write_byte, read_byte);
return ret;
}
/*
* I2C over AUX CH
*/
/*
* Send the address. If the I2C link is running, this 'restarts'
* the connection with the new address, this is used for doing
* a write followed by a read (as needed for DDC)
*/
static int
i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
int mode = MODE_I2C_START;
int ret;
if (reading)
mode |= MODE_I2C_READ;
else
mode |= MODE_I2C_WRITE;
algo_data->address = address;
algo_data->running = true;
ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
return ret;
}
/*
* Stop the I2C transaction. This closes out the link, sending
* a bare address packet with the MOT bit turned off
*/
static void
i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
int mode = MODE_I2C_STOP;
if (reading)
mode |= MODE_I2C_READ;
else
mode |= MODE_I2C_WRITE;
if (algo_data->running) {
(void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
algo_data->running = false;
}
}
/*
* Write a single byte to the current I2C address, the
* the I2C link must be running or this returns -EIO
*/
static int
i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
int ret;
if (!algo_data->running)
return -EIO;
ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
return ret;
}
/*
* Read a single byte from the current I2C address, the
* I2C link must be running or this returns -EIO
*/
static int
i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
{
struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
int ret;
if (!algo_data->running)
return -EIO;
ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
return ret;
}
static int
i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
struct i2c_msg *msgs,
int num)
{
int ret = 0;
bool reading = false;
int m;
int b;
for (m = 0; m < num; m++) {
u16 len = msgs[m].len;
u8 *buf = msgs[m].buf;
reading = (msgs[m].flags & I2C_M_RD) != 0;
ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
if (ret < 0)
break;
if (reading) {
for (b = 0; b < len; b++) {
ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
if (ret < 0)
break;
}
} else {
for (b = 0; b < len; b++) {
ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
if (ret < 0)
break;
}
}
if (ret < 0)
break;
}
if (ret >= 0)
ret = num;
i2c_algo_dp_aux_stop(adapter, reading);
DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret);
return ret;
}
static u32
i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
I2C_FUNC_SMBUS_READ_BLOCK_DATA |
I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
I2C_FUNC_10BIT_ADDR;
}
static const struct i2c_algorithm i2c_dp_aux_algo = {
.master_xfer = i2c_algo_dp_aux_xfer,
.functionality = i2c_algo_dp_aux_functionality,
};
static void
i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
{
(void) i2c_algo_dp_aux_address(adapter, 0, false);
(void) i2c_algo_dp_aux_stop(adapter, false);
}
static int
i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
{
adapter->algo = &i2c_dp_aux_algo;
adapter->retries = 3;
i2c_dp_aux_reset_bus(adapter);
return 0;
}
/*
* FIXME: This is the old dp aux helper, gma500 is the last driver that needs to
* be ported over to the new helper code in drm_dp_helper.c like i915 or radeon.
*/
static int __deprecated
i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
{
int error;
error = i2c_dp_aux_prepare_bus(adapter);
if (error)
return error;
error = i2c_add_adapter(adapter);
return error;
}
#define _wait_for(COND, MS, W) ({ \ #define _wait_for(COND, MS, W) ({ \
unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
int ret__ = 0; \ int ret__ = 0; \
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_plane_helper.h>
#include "framebuffer.h" #include "framebuffer.h"
#include "psb_drv.h" #include "psb_drv.h"
#include "psb_intel_drv.h" #include "psb_intel_drv.h"
......
...@@ -1631,57 +1631,8 @@ static int psb_intel_sdvo_get_modes(struct drm_connector *connector) ...@@ -1631,57 +1631,8 @@ static int psb_intel_sdvo_get_modes(struct drm_connector *connector)
return !list_empty(&connector->probed_modes); return !list_empty(&connector->probed_modes);
} }
static void
psb_intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
{
struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector);
struct drm_device *dev = connector->dev;
if (psb_intel_sdvo_connector->left)
drm_property_destroy(dev, psb_intel_sdvo_connector->left);
if (psb_intel_sdvo_connector->right)
drm_property_destroy(dev, psb_intel_sdvo_connector->right);
if (psb_intel_sdvo_connector->top)
drm_property_destroy(dev, psb_intel_sdvo_connector->top);
if (psb_intel_sdvo_connector->bottom)
drm_property_destroy(dev, psb_intel_sdvo_connector->bottom);
if (psb_intel_sdvo_connector->hpos)
drm_property_destroy(dev, psb_intel_sdvo_connector->hpos);
if (psb_intel_sdvo_connector->vpos)
drm_property_destroy(dev, psb_intel_sdvo_connector->vpos);
if (psb_intel_sdvo_connector->saturation)
drm_property_destroy(dev, psb_intel_sdvo_connector->saturation);
if (psb_intel_sdvo_connector->contrast)
drm_property_destroy(dev, psb_intel_sdvo_connector->contrast);
if (psb_intel_sdvo_connector->hue)
drm_property_destroy(dev, psb_intel_sdvo_connector->hue);
if (psb_intel_sdvo_connector->sharpness)
drm_property_destroy(dev, psb_intel_sdvo_connector->sharpness);
if (psb_intel_sdvo_connector->flicker_filter)
drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter);
if (psb_intel_sdvo_connector->flicker_filter_2d)
drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter_2d);
if (psb_intel_sdvo_connector->flicker_filter_adaptive)
drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter_adaptive);
if (psb_intel_sdvo_connector->tv_luma_filter)
drm_property_destroy(dev, psb_intel_sdvo_connector->tv_luma_filter);
if (psb_intel_sdvo_connector->tv_chroma_filter)
drm_property_destroy(dev, psb_intel_sdvo_connector->tv_chroma_filter);
if (psb_intel_sdvo_connector->dot_crawl)
drm_property_destroy(dev, psb_intel_sdvo_connector->dot_crawl);
if (psb_intel_sdvo_connector->brightness)
drm_property_destroy(dev, psb_intel_sdvo_connector->brightness);
}
static void psb_intel_sdvo_destroy(struct drm_connector *connector) static void psb_intel_sdvo_destroy(struct drm_connector *connector)
{ {
struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector);
if (psb_intel_sdvo_connector->tv_format)
drm_property_destroy(connector->dev,
psb_intel_sdvo_connector->tv_format);
psb_intel_sdvo_destroy_enhance_property(connector);
drm_connector_unregister(connector); drm_connector_unregister(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
kfree(connector); kfree(connector);
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
* those commands required by the parser. This generally works because command * those commands required by the parser. This generally works because command
* opcode ranges have standard command length encodings. So for commands that * opcode ranges have standard command length encodings. So for commands that
* the parser does not need to check, it can easily skip them. This is * the parser does not need to check, it can easily skip them. This is
* implementated via a per-ring length decoding vfunc. * implemented via a per-ring length decoding vfunc.
* *
* Unfortunately, there are a number of commands that do not follow the standard * Unfortunately, there are a number of commands that do not follow the standard
* length encoding for their opcode range, primarily amongst the MI_* commands. * length encoding for their opcode range, primarily amongst the MI_* commands.
...@@ -843,7 +843,7 @@ static u32 *vmap_batch(struct drm_i915_gem_object *obj) ...@@ -843,7 +843,7 @@ static u32 *vmap_batch(struct drm_i915_gem_object *obj)
* @ring: the ring in question * @ring: the ring in question
* *
* Only certain platforms require software batch buffer command parsing, and * Only certain platforms require software batch buffer command parsing, and
* only when enabled via module paramter. * only when enabled via module parameter.
* *
* Return: true if the ring requires software command parsing * Return: true if the ring requires software command parsing
*/ */
......
...@@ -672,7 +672,7 @@ enum punit_power_well { ...@@ -672,7 +672,7 @@ enum punit_power_well {
* need to be accessed during AUX communication, * need to be accessed during AUX communication,
* *
* Generally the common lane corresponds to the pipe and * Generally the common lane corresponds to the pipe and
* the spline (PCS/TX) correponds to the port. * the spline (PCS/TX) corresponds to the port.
* *
* For dual channel PHY (VLV/CHV): * For dual channel PHY (VLV/CHV):
* *
......
...@@ -1681,7 +1681,7 @@ static int lrc_setup_hardware_status_page(struct intel_engine_cs *ring, ...@@ -1681,7 +1681,7 @@ static int lrc_setup_hardware_status_page(struct intel_engine_cs *ring,
* the creation is a deferred call: it's better to make sure first that we need to use * the creation is a deferred call: it's better to make sure first that we need to use
* a given ring with the context. * a given ring with the context.
* *
* Return: non-zero on eror. * Return: non-zero on error.
*/ */
int intel_lr_context_deferred_create(struct intel_context *ctx, int intel_lr_context_deferred_create(struct intel_context *ctx,
struct intel_engine_cs *ring) struct intel_engine_cs *ring)
......
...@@ -1991,57 +1991,10 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) ...@@ -1991,57 +1991,10 @@ static int intel_sdvo_get_modes(struct drm_connector *connector)
return !list_empty(&connector->probed_modes); return !list_empty(&connector->probed_modes);
} }
static void
intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
{
struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
struct drm_device *dev = connector->dev;
if (intel_sdvo_connector->left)
drm_property_destroy(dev, intel_sdvo_connector->left);
if (intel_sdvo_connector->right)
drm_property_destroy(dev, intel_sdvo_connector->right);
if (intel_sdvo_connector->top)
drm_property_destroy(dev, intel_sdvo_connector->top);
if (intel_sdvo_connector->bottom)
drm_property_destroy(dev, intel_sdvo_connector->bottom);
if (intel_sdvo_connector->hpos)
drm_property_destroy(dev, intel_sdvo_connector->hpos);
if (intel_sdvo_connector->vpos)
drm_property_destroy(dev, intel_sdvo_connector->vpos);
if (intel_sdvo_connector->saturation)
drm_property_destroy(dev, intel_sdvo_connector->saturation);
if (intel_sdvo_connector->contrast)
drm_property_destroy(dev, intel_sdvo_connector->contrast);
if (intel_sdvo_connector->hue)
drm_property_destroy(dev, intel_sdvo_connector->hue);
if (intel_sdvo_connector->sharpness)
drm_property_destroy(dev, intel_sdvo_connector->sharpness);
if (intel_sdvo_connector->flicker_filter)
drm_property_destroy(dev, intel_sdvo_connector->flicker_filter);
if (intel_sdvo_connector->flicker_filter_2d)
drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_2d);
if (intel_sdvo_connector->flicker_filter_adaptive)
drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_adaptive);
if (intel_sdvo_connector->tv_luma_filter)
drm_property_destroy(dev, intel_sdvo_connector->tv_luma_filter);
if (intel_sdvo_connector->tv_chroma_filter)
drm_property_destroy(dev, intel_sdvo_connector->tv_chroma_filter);
if (intel_sdvo_connector->dot_crawl)
drm_property_destroy(dev, intel_sdvo_connector->dot_crawl);
if (intel_sdvo_connector->brightness)
drm_property_destroy(dev, intel_sdvo_connector->brightness);
}
static void intel_sdvo_destroy(struct drm_connector *connector) static void intel_sdvo_destroy(struct drm_connector *connector)
{ {
struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
if (intel_sdvo_connector->tv_format)
drm_property_destroy(connector->dev,
intel_sdvo_connector->tv_format);
intel_sdvo_destroy_enhance_property(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
kfree(intel_sdvo_connector); kfree(intel_sdvo_connector);
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include "mgag200_drv.h" #include "mgag200_drv.h"
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include "nouveau_drm.h" #include "nouveau_drm.h"
#include "nouveau_reg.h" #include "nouveau_reg.h"
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_dp_helper.h> #include <drm/drm_dp_helper.h>
#include <nvif/class.h> #include <nvif/class.h>
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "omap_drv.h" #include "omap_drv.h"
#include <drm/drm_mode.h> #include <drm/drm_mode.h>
#include <drm/drm_plane_helper.h>
#include "drm_crtc.h" #include "drm_crtc.h"
#include "drm_crtc_helper.h" #include "drm_crtc_helper.h"
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "qxl_drv.h" #include "qxl_drv.h"
#include "qxl_object.h" #include "qxl_object.h"
#include "drm_crtc_helper.h" #include "drm_crtc_helper.h"
#include <drm/drm_plane_helper.h>
static bool qxl_head_enabled(struct qxl_head *head) static bool qxl_head_enabled(struct qxl_head *head)
{ {
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include <linux/gcd.h> #include <linux/gcd.h>
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_cma_helper.h> #include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_plane_helper.h>
#include "rcar_du_crtc.h" #include "rcar_du_crtc.h"
#include "rcar_du_drv.h" #include "rcar_du_drv.h"
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_cma_helper.h> #include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_plane_helper.h>
#include <video/sh_mobile_meram.h> #include <video/sh_mobile_meram.h>
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include "sti_compositor.h" #include "sti_compositor.h"
#include "sti_drm_drv.h" #include "sti_drm_drv.h"
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include "drm.h" #include "drm.h"
#include "gem.h" #include "gem.h"
#include <drm/drm_plane_helper.h>
struct tegra_dc_soc_info { struct tegra_dc_soc_info {
bool supports_interlacing; bool supports_interlacing;
bool supports_cursor; bool supports_cursor;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
*/ */
#include "drm_flip_work.h" #include "drm_flip_work.h"
#include <drm/drm_plane_helper.h>
#include "tilcdc_drv.h" #include "tilcdc_drv.h"
#include "tilcdc_regs.h" #include "tilcdc_regs.h"
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include "udl_drv.h" #include "udl_drv.h"
/* /*
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
**************************************************************************/ **************************************************************************/
#include "vmwgfx_kms.h" #include "vmwgfx_kms.h"
#include <drm/drm_plane_helper.h>
#define vmw_crtc_to_ldu(x) \ #define vmw_crtc_to_ldu(x) \
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
**************************************************************************/ **************************************************************************/
#include "vmwgfx_kms.h" #include "vmwgfx_kms.h"
#include <drm/drm_plane_helper.h>
#define vmw_crtc_to_sou(x) \ #define vmw_crtc_to_sou(x) \
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_fb_cma_helper.h> #include <drm/drm_fb_cma_helper.h>
#include <drm/drm_plane_helper.h>
#include "imx-drm.h" #include "imx-drm.h"
......
...@@ -125,8 +125,8 @@ struct dma_buf_attachment; ...@@ -125,8 +125,8 @@ struct dma_buf_attachment;
extern __printf(2, 3) extern __printf(2, 3)
void drm_ut_debug_printk(const char *function_name, void drm_ut_debug_printk(const char *function_name,
const char *format, ...); const char *format, ...);
extern __printf(2, 3) extern __printf(1, 2)
void drm_err(const char *func, const char *format, ...); void drm_err(const char *format, ...);
/***********************************************************************/ /***********************************************************************/
/** \name DRM template customization defaults */ /** \name DRM template customization defaults */
...@@ -155,7 +155,7 @@ void drm_err(const char *func, const char *format, ...); ...@@ -155,7 +155,7 @@ void drm_err(const char *func, const char *format, ...);
* \param arg arguments * \param arg arguments
*/ */
#define DRM_ERROR(fmt, ...) \ #define DRM_ERROR(fmt, ...) \
drm_err(__func__, fmt, ##__VA_ARGS__) drm_err(fmt, ##__VA_ARGS__)
/** /**
* Rate limited error output. Like DRM_ERROR() but won't flood the log. * Rate limited error output. Like DRM_ERROR() but won't flood the log.
...@@ -170,7 +170,7 @@ void drm_err(const char *func, const char *format, ...); ...@@ -170,7 +170,7 @@ void drm_err(const char *func, const char *format, ...);
DEFAULT_RATELIMIT_BURST); \ DEFAULT_RATELIMIT_BURST); \
\ \
if (__ratelimit(&_rs)) \ if (__ratelimit(&_rs)) \
drm_err(__func__, fmt, ##__VA_ARGS__); \ drm_err(fmt, ##__VA_ARGS__); \
}) })
#define DRM_INFO(fmt, ...) \ #define DRM_INFO(fmt, ...) \
......
/*
* Copyright (C) 2014 Red Hat
* Copyright (C) 2014 Intel Corp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rob Clark <robdclark@gmail.com>
* Daniel Vetter <daniel.vetter@ffwll.ch>
*/
#ifndef DRM_ATOMIC_H_
#define DRM_ATOMIC_H_
struct drm_atomic_state * __must_check
drm_atomic_state_alloc(struct drm_device *dev);
void drm_atomic_state_clear(struct drm_atomic_state *state);
void drm_atomic_state_free(struct drm_atomic_state *state);
struct drm_crtc_state * __must_check
drm_atomic_get_crtc_state(struct drm_atomic_state *state,
struct drm_crtc *crtc);
struct drm_plane_state * __must_check
drm_atomic_get_plane_state(struct drm_atomic_state *state,
struct drm_plane *plane);
struct drm_connector_state * __must_check
drm_atomic_get_connector_state(struct drm_atomic_state *state,
struct drm_connector *connector);
int __must_check
drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
struct drm_crtc *crtc);
void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
struct drm_framebuffer *fb);
int __must_check
drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
struct drm_crtc *crtc);
int __must_check
drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
struct drm_crtc *crtc);
int
drm_atomic_connectors_for_crtc(struct drm_atomic_state *state,
struct drm_crtc *crtc);
void drm_atomic_legacy_backoff(struct drm_atomic_state *state);
int __must_check drm_atomic_check_only(struct drm_atomic_state *state);
int __must_check drm_atomic_commit(struct drm_atomic_state *state);
int __must_check drm_atomic_async_commit(struct drm_atomic_state *state);
#endif /* DRM_ATOMIC_H_ */
/*
* Copyright (C) 2014 Red Hat
* Copyright (C) 2014 Intel Corp.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rob Clark <robdclark@gmail.com>
* Daniel Vetter <daniel.vetter@ffwll.ch>
*/
#ifndef DRM_ATOMIC_HELPER_H_
#define DRM_ATOMIC_HELPER_H_
int drm_atomic_helper_check(struct drm_device *dev,
struct drm_atomic_state *state);
int drm_atomic_helper_commit(struct drm_device *dev,
struct drm_atomic_state *state,
bool async);
void drm_atomic_helper_commit_pre_planes(struct drm_device *dev,
struct drm_atomic_state *state);
void drm_atomic_helper_commit_post_planes(struct drm_device *dev,
struct drm_atomic_state *old_state);
int drm_atomic_helper_prepare_planes(struct drm_device *dev,
struct drm_atomic_state *state);
void drm_atomic_helper_commit_planes(struct drm_device *dev,
struct drm_atomic_state *state);
void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
struct drm_atomic_state *old_state);
void drm_atomic_helper_swap_state(struct drm_device *dev,
struct drm_atomic_state *state);
/* implementations for legacy interfaces */
int drm_atomic_helper_update_plane(struct drm_plane *plane,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h);
int drm_atomic_helper_disable_plane(struct drm_plane *plane);
int drm_atomic_helper_set_config(struct drm_mode_set *set);
int drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
struct drm_property *property,
uint64_t val);
int drm_atomic_helper_plane_set_property(struct drm_plane *plane,
struct drm_property *property,
uint64_t val);
int drm_atomic_helper_connector_set_property(struct drm_connector *connector,
struct drm_property *property,
uint64_t val);
int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t flags);
/* default implementations for state handling */
void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);
struct drm_crtc_state *
drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc);
void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
struct drm_crtc_state *state);
void drm_atomic_helper_plane_reset(struct drm_plane *plane);
struct drm_plane_state *
drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane);
void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state);
void drm_atomic_helper_connector_reset(struct drm_connector *connector);
struct drm_connector_state *
drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector);
void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
struct drm_connector_state *state);
#endif /* DRM_ATOMIC_HELPER_H_ */
This diff is collapsed.
...@@ -68,6 +68,7 @@ struct drm_crtc_helper_funcs { ...@@ -68,6 +68,7 @@ struct drm_crtc_helper_funcs {
int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode, int x, int y, struct drm_display_mode *adjusted_mode, int x, int y,
struct drm_framebuffer *old_fb); struct drm_framebuffer *old_fb);
void (*mode_set_nofb)(struct drm_crtc *crtc);
/* Move the crtc on the current fb to the given position *optional* */ /* Move the crtc on the current fb to the given position *optional* */
int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
...@@ -81,6 +82,12 @@ struct drm_crtc_helper_funcs { ...@@ -81,6 +82,12 @@ struct drm_crtc_helper_funcs {
/* disable crtc when not in use - more explicit than dpms off */ /* disable crtc when not in use - more explicit than dpms off */
void (*disable)(struct drm_crtc *crtc); void (*disable)(struct drm_crtc *crtc);
/* atomic helpers */
int (*atomic_check)(struct drm_crtc *crtc,
struct drm_crtc_state *state);
void (*atomic_begin)(struct drm_crtc *crtc);
void (*atomic_flush)(struct drm_crtc *crtc);
}; };
/** /**
...@@ -161,6 +168,12 @@ static inline void drm_connector_helper_add(struct drm_connector *connector, ...@@ -161,6 +168,12 @@ static inline void drm_connector_helper_add(struct drm_connector *connector,
extern void drm_helper_resume_force_mode(struct drm_device *dev); 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,
struct drm_display_mode *adjusted_mode, int x, int y,
struct drm_framebuffer *old_fb);
int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb);
/* drm_probe_helper.c */ /* drm_probe_helper.c */
extern int drm_helper_probe_single_connector_modes(struct drm_connector extern int drm_helper_probe_single_connector_modes(struct drm_connector
*connector, uint32_t maxX, *connector, uint32_t maxX,
......
...@@ -405,26 +405,6 @@ ...@@ -405,26 +405,6 @@
#define MODE_I2C_READ 4 #define MODE_I2C_READ 4
#define MODE_I2C_STOP 8 #define MODE_I2C_STOP 8
/**
* struct i2c_algo_dp_aux_data - driver interface structure for i2c over dp
* aux algorithm
* @running: set by the algo indicating whether an i2c is ongoing or whether
* the i2c bus is quiescent
* @address: i2c target address for the currently ongoing transfer
* @aux_ch: driver callback to transfer a single byte of the i2c payload
*/
struct i2c_algo_dp_aux_data {
bool running;
u16 address;
int (*aux_ch) (struct i2c_adapter *adapter,
int mode, uint8_t write_byte,
uint8_t *read_byte);
};
int
i2c_dp_aux_add_bus(struct i2c_adapter *adapter);
#define DP_LINK_STATUS_SIZE 6 #define DP_LINK_STATUS_SIZE 6
bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE], bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
int lane_count); int lane_count);
...@@ -551,6 +531,7 @@ struct drm_dp_aux { ...@@ -551,6 +531,7 @@ struct drm_dp_aux {
struct mutex hw_mutex; struct mutex hw_mutex;
ssize_t (*transfer)(struct drm_dp_aux *aux, ssize_t (*transfer)(struct drm_dp_aux *aux,
struct drm_dp_aux_msg *msg); struct drm_dp_aux_msg *msg);
unsigned i2c_nack_count, i2c_defer_count;
}; };
ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
struct drm_dp_mst_branch; struct drm_dp_mst_branch;
/** /**
* struct drm_dp_vcpi - Virtual Channel Payload Identifer * struct drm_dp_vcpi - Virtual Channel Payload Identifier
* @vcpi: Virtual channel ID. * @vcpi: Virtual channel ID.
* @pbn: Payload Bandwidth Number for this channel * @pbn: Payload Bandwidth Number for this channel
* @aligned_pbn: PBN aligned with slot size * @aligned_pbn: PBN aligned with slot size
......
...@@ -207,6 +207,61 @@ struct detailed_timing { ...@@ -207,6 +207,61 @@ struct detailed_timing {
#define DRM_EDID_HDMI_DC_30 (1 << 4) #define DRM_EDID_HDMI_DC_30 (1 << 4)
#define DRM_EDID_HDMI_DC_Y444 (1 << 3) #define DRM_EDID_HDMI_DC_Y444 (1 << 3)
/* ELD Header Block */
#define DRM_ELD_HEADER_BLOCK_SIZE 4
#define DRM_ELD_VER 0
# define DRM_ELD_VER_SHIFT 3
# define DRM_ELD_VER_MASK (0x1f << 3)
#define DRM_ELD_BASELINE_ELD_LEN 2 /* in dwords! */
/* ELD Baseline Block for ELD_Ver == 2 */
#define DRM_ELD_CEA_EDID_VER_MNL 4
# define DRM_ELD_CEA_EDID_VER_SHIFT 5
# define DRM_ELD_CEA_EDID_VER_MASK (7 << 5)
# define DRM_ELD_CEA_EDID_VER_NONE (0 << 5)
# define DRM_ELD_CEA_EDID_VER_CEA861 (1 << 5)
# define DRM_ELD_CEA_EDID_VER_CEA861A (2 << 5)
# define DRM_ELD_CEA_EDID_VER_CEA861BCD (3 << 5)
# define DRM_ELD_MNL_SHIFT 0
# define DRM_ELD_MNL_MASK (0x1f << 0)
#define DRM_ELD_SAD_COUNT_CONN_TYPE 5
# define DRM_ELD_SAD_COUNT_SHIFT 4
# define DRM_ELD_SAD_COUNT_MASK (0xf << 4)
# define DRM_ELD_CONN_TYPE_SHIFT 2
# define DRM_ELD_CONN_TYPE_MASK (3 << 2)
# define DRM_ELD_CONN_TYPE_HDMI (0 << 2)
# define DRM_ELD_CONN_TYPE_DP (1 << 2)
# define DRM_ELD_SUPPORTS_AI (1 << 1)
# define DRM_ELD_SUPPORTS_HDCP (1 << 0)
#define DRM_ELD_AUD_SYNCH_DELAY 6 /* in units of 2 ms */
# define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa /* 500 ms */
#define DRM_ELD_SPEAKER 7
# define DRM_ELD_SPEAKER_RLRC (1 << 6)
# define DRM_ELD_SPEAKER_FLRC (1 << 5)
# define DRM_ELD_SPEAKER_RC (1 << 4)
# define DRM_ELD_SPEAKER_RLR (1 << 3)
# define DRM_ELD_SPEAKER_FC (1 << 2)
# define DRM_ELD_SPEAKER_LFE (1 << 1)
# define DRM_ELD_SPEAKER_FLR (1 << 0)
#define DRM_ELD_PORT_ID 8 /* offsets 8..15 inclusive */
# define DRM_ELD_PORT_ID_LEN 8
#define DRM_ELD_MANUFACTURER_NAME0 16
#define DRM_ELD_MANUFACTURER_NAME1 17
#define DRM_ELD_PRODUCT_CODE0 18
#define DRM_ELD_PRODUCT_CODE1 19
#define DRM_ELD_MONITOR_NAME_STRING 20 /* offsets 20..(20+mnl-1) inclusive */
#define DRM_ELD_CEA_SAD(mnl, sad) (20 + (mnl) + 3 * (sad))
struct edid { struct edid {
u8 header[8]; u8 header[8];
/* Vendor & product info */ /* Vendor & product info */
...@@ -279,4 +334,51 @@ int ...@@ -279,4 +334,51 @@ int
drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
const struct drm_display_mode *mode); const struct drm_display_mode *mode);
/**
* drm_eld_mnl - Get ELD monitor name length in bytes.
* @eld: pointer to an eld memory structure with mnl set
*/
static inline int drm_eld_mnl(const uint8_t *eld)
{
return (eld[DRM_ELD_CEA_EDID_VER_MNL] & DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT;
}
/**
* drm_eld_sad_count - Get ELD SAD count.
* @eld: pointer to an eld memory structure with sad_count set
*/
static inline int drm_eld_sad_count(const uint8_t *eld)
{
return (eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_SAD_COUNT_MASK) >>
DRM_ELD_SAD_COUNT_SHIFT;
}
/**
* drm_eld_calc_baseline_block_size - Calculate baseline block size in bytes
* @eld: pointer to an eld memory structure with mnl and sad_count set
*
* This is a helper for determining the payload size of the baseline block, in
* bytes, for e.g. setting the Baseline_ELD_Len field in the ELD header block.
*/
static inline int drm_eld_calc_baseline_block_size(const uint8_t *eld)
{
return DRM_ELD_MONITOR_NAME_STRING - DRM_ELD_HEADER_BLOCK_SIZE +
drm_eld_mnl(eld) + drm_eld_sad_count(eld) * 3;
}
/**
* drm_eld_size - Get ELD size in bytes
* @eld: pointer to a complete eld memory structure
*
* The returned value does not include the vendor block. It's vendor specific,
* and comprises of the remaining bytes in the ELD memory buffer after
* drm_eld_size() bytes of header and baseline block.
*
* The returned value is guaranteed to be a multiple of 4.
*/
static inline int drm_eld_size(const uint8_t *eld)
{
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
}
#endif /* __DRM_EDID_H__ */ #endif /* __DRM_EDID_H__ */
...@@ -33,6 +33,7 @@ struct drm_modeset_lock; ...@@ -33,6 +33,7 @@ struct drm_modeset_lock;
* @ww_ctx: base acquire ctx * @ww_ctx: base acquire ctx
* @contended: used internally for -EDEADLK handling * @contended: used internally for -EDEADLK handling
* @locked: list of held locks * @locked: list of held locks
* @trylock_only: trylock mode used in atomic contexts/panic notifiers
* *
* Each thread competing for a set of locks must use one acquire * Each thread competing for a set of locks must use one acquire
* ctx. And if any lock fxn returns -EDEADLK, it must backoff and * ctx. And if any lock fxn returns -EDEADLK, it must backoff and
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define DRM_PLANE_HELPER_H #define DRM_PLANE_HELPER_H
#include <drm/drm_rect.h> #include <drm/drm_rect.h>
#include <drm/drm_crtc.h>
/* /*
* Drivers that don't allow primary plane scaling may pass this macro in place * Drivers that don't allow primary plane scaling may pass this macro in place
...@@ -42,6 +43,32 @@ ...@@ -42,6 +43,32 @@
* planes. * planes.
*/ */
extern int drm_crtc_init(struct drm_device *dev,
struct drm_crtc *crtc,
const struct drm_crtc_funcs *funcs);
/**
* drm_plane_helper_funcs - helper operations for CRTCs
*
* The helper operations are called by the mid-layer CRTC helper.
*/
struct drm_plane_helper_funcs {
int (*prepare_fb)(struct drm_plane *plane,
struct drm_framebuffer *fb);
void (*cleanup_fb)(struct drm_plane *plane,
struct drm_framebuffer *fb);
int (*atomic_check)(struct drm_plane *plane,
struct drm_plane_state *state);
void (*atomic_update)(struct drm_plane *plane);
};
static inline void drm_plane_helper_add(struct drm_plane *plane,
const struct drm_plane_helper_funcs *funcs)
{
plane->helper_private = (void *)funcs;
}
extern int drm_plane_helper_check_update(struct drm_plane *plane, extern int drm_plane_helper_check_update(struct drm_plane *plane,
struct drm_crtc *crtc, struct drm_crtc *crtc,
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
...@@ -68,4 +95,16 @@ extern struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev, ...@@ -68,4 +95,16 @@ extern struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev,
int num_formats); int num_formats);
int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h);
int drm_plane_helper_disable(struct drm_plane *plane);
/* For use by drm_crtc_helper.c */
int drm_plane_helper_commit(struct drm_plane *plane,
struct drm_plane_state *plane_state,
struct drm_framebuffer *old_fb);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment