Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+13 −27
Original line number Diff line number Diff line
@@ -766,7 +766,6 @@ static void drm_mode_remove(struct drm_connector *connector,
/**
 * drm_connector_get_cmdline_mode - reads the user's cmdline mode
 * @connector: connector to quwery
 * @mode: returned mode
 *
 * The kernel supports per-connector configration of its consoles through
 * use of the video= parameter. This function parses that option and
@@ -2943,7 +2942,7 @@ EXPORT_SYMBOL(drm_mode_legacy_fb_format);
 * @file_priv: drm file for the ioctl call
 *
 * 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.
 *
@@ -2955,11 +2954,9 @@ int drm_mode_addfb(struct drm_device *dev,
{
	struct drm_mode_fb_cmd *or = data;
	struct drm_mode_fb_cmd2 r = {};
	struct drm_mode_config *config = &dev->mode_config;
	struct drm_framebuffer *fb;
	int ret = 0;
	int ret;

	/* Use new struct with format internally */
	/* convert to new format and call new ioctl */
	r.fb_id = or->fb_id;
	r.width = or->width;
	r.height = or->height;
@@ -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.handles[0] = or->handle;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -EINVAL;

	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);
	}
	ret = drm_mode_addfb2(dev, &r, file_priv);
	if (ret)
		return ret;

	mutex_lock(&file_priv->fbs_lock);
	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);
	or->fb_id = r.fb_id;

	return ret;
}
@@ -3080,7 +3062,7 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
	num_planes = drm_format_num_planes(r->pixel_format);

	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;
	}

@@ -3435,6 +3417,10 @@ void drm_fb_release(struct drm_file *priv)
 * object with drm_object_attach_property. The returned property object must be
 * 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:
 * 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,
 * object with drm_object_attach_property. The returned property object must be
 * 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.
 *
 * Returns:
+2 −192
Original line number Diff line number Diff line
@@ -39,198 +39,6 @@
 * 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 */
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)

		case DP_AUX_I2C_REPLY_NACK:
			DRM_DEBUG_KMS("I2C nack\n");
			aux->i2c_nack_count++;
			return -EREMOTEIO;

		case DP_AUX_I2C_REPLY_DEFER:
			DRM_DEBUG_KMS("I2C defer\n");
			aux->i2c_defer_count++;
			usleep_range(400, 500);
			continue;

+8 −7
Original line number Diff line number Diff line
@@ -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,
				struct drm_dp_mst_branch *mstb,
				char *proppath)
				char *proppath,
				size_t proppath_size)
{
	int i;
	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++) {
		int shift = (i % 2) ? 0 : 4;
		int port_num = mstb->rad[i / 2] >> shift;
		snprintf(temp, 8, "-%d", port_num);
		strncat(proppath, temp, 255);
		snprintf(temp, sizeof(temp), "-%d", port_num);
		strlcat(proppath, temp, proppath_size);
	}
	snprintf(temp, 8, "-%d", port->port_num);
	strncat(proppath, temp, 255);
	snprintf(temp, sizeof(temp), "-%d", port->port_num);
	strlcat(proppath, temp, proppath_size);
}

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) {
		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);
	}

+3 −2
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ static struct idr drm_minors_idr;
struct class *drm_class;
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;
	va_list args;
@@ -66,7 +66,8 @@ void drm_err(const char *func, const char *format, ...)
	vaf.fmt = format;
	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);
}
+0 −1
Original line number Diff line number Diff line
@@ -1570,7 +1570,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
		modeset = &fb_helper->crtc_info[i].mode_set;
		if (modeset->num_connectors == 0) {
			BUG_ON(modeset->fb);
			BUG_ON(modeset->num_connectors);
			if (modeset->mode)
				drm_mode_destroy(dev, modeset->mode);
			modeset->mode = NULL;
Loading