Commit 1f9e14ba authored by Dave Airlie's avatar Dave Airlie

Merge tag 'topic/core-stuff-2014-11-05' of git://anongit.freedesktop.org/drm-intel into drm-next

Just various stuff all over from a bunch of people. Shortlog gives a beter
overview, it's really all misc drm patches.

* tag 'topic/core-stuff-2014-11-05' of git://anongit.freedesktop.org/drm-intel:
  drm/edid: add #defines and helpers for ELD
  drm/dp: Add counters in the drm_dp_aux struct for I2C NACKs and DEFERs
  drm: Remove compiler BUG_ON() test
  drm: Fix DRM_FORCE_ON_DIGITAL use
  drm/gma500: Don't destroy DRM properties in the driver
  drm/i915: Don't destroy DRM properties in the driver
  drm: Add a note to drm_property_create() about property lifetime
  gpu: drm: Fix warning caused by a parameter description in drm_crtc.c
  drm/dp-helper: Move the legacy helpers to gma500
  drm/crtc: Remove duplicated ioctl code
  drm/crtc: Fix two typos
  gpu:drm: Fix typo in Documentation/DocBook/drm.xml
  gpu: drm: drm_dp_mst_topology.c: Fix improper use of strncat
  drm: drm_err: Remove unnecessary __func__ argument
  drm: Implement O_NONBLOCK support on /dev/dri/cardN
parents 5fa2704e babc9493
...@@ -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:
......
...@@ -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;
ret = wait_event_interruptible(file_priv->event_wait, if ((filp->f_flags & O_NONBLOCK) == 0) {
!list_empty(&file_priv->event_list)); ret = wait_event_interruptible(file_priv->event_wait,
if (ret < 0) !list_empty(&file_priv->event_list));
return ret; if (ret < 0)
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,
......
...@@ -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; \
......
...@@ -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.
...@@ -838,7 +838,7 @@ static u32 *vmap_batch(struct drm_i915_gem_object *obj) ...@@ -838,7 +838,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):
* *
......
...@@ -1660,7 +1660,7 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring) ...@@ -1660,7 +1660,7 @@ static uint32_t get_lr_context_size(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);
} }
......
...@@ -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, ...) \
......
...@@ -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__ */
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