Commit d79dc0a9 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'topic/drm-misc-2015-03-18' of git://anongit.freedesktop.org/drm-intel into drm-next

Another drm-misch pull request. Mostly the fbdev sizes deconfusion series
from Rob, everything else is small stuff all over. And the large i2c over
aux transfers patch, too.

* tag 'topic/drm-misc-2015-03-18' of git://anongit.freedesktop.org/drm-intel:
  drm: check that planes types are correct while initializing CRTC
  drm: change connector to tmp_connector
  drm: Fix some typo mistake of the annotations
  drm: Silence sparse warnings
  drm: %pF is only for function pointers
  drm/fb: handle tiled connectors better
  drm/fb: small cleanup
  drm/rockchip: use correct fb width/height
  drm/exynos: use correct fb width/height
  drm/cma: use correct fb width/height
  drm/atomic: minor kerneldoc typo fix
  drm/fb: document drm_fb_helper_surface_size
  drm/dp: Use large transactions for I2C over AUX
  drm/plane-helper: Fixup mismerge
  drm/atomic: Constify a bunch of functions pointer structs
parents 03be7005 522cf91f
...@@ -151,7 +151,7 @@ steal_encoder(struct drm_atomic_state *state, ...@@ -151,7 +151,7 @@ steal_encoder(struct drm_atomic_state *state,
static int static int
update_connector_routing(struct drm_atomic_state *state, int conn_idx) update_connector_routing(struct drm_atomic_state *state, int conn_idx)
{ {
struct drm_connector_helper_funcs *funcs; const struct drm_connector_helper_funcs *funcs;
struct drm_encoder *new_encoder; struct drm_encoder *new_encoder;
struct drm_crtc *encoder_crtc; struct drm_crtc *encoder_crtc;
struct drm_connector *connector; struct drm_connector *connector;
...@@ -264,7 +264,7 @@ mode_fixup(struct drm_atomic_state *state) ...@@ -264,7 +264,7 @@ mode_fixup(struct drm_atomic_state *state)
} }
for (i = 0; i < state->num_connector; i++) { for (i = 0; i < state->num_connector; i++) {
struct drm_encoder_helper_funcs *funcs; const struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder; struct drm_encoder *encoder;
conn_state = state->connector_states[i]; conn_state = state->connector_states[i];
...@@ -317,7 +317,7 @@ mode_fixup(struct drm_atomic_state *state) ...@@ -317,7 +317,7 @@ mode_fixup(struct drm_atomic_state *state)
} }
for (i = 0; i < ncrtcs; i++) { for (i = 0; i < ncrtcs; i++) {
struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
struct drm_crtc *crtc; struct drm_crtc *crtc;
crtc_state = state->crtc_states[i]; crtc_state = state->crtc_states[i];
...@@ -346,7 +346,7 @@ needs_modeset(struct drm_crtc_state *state) ...@@ -346,7 +346,7 @@ needs_modeset(struct drm_crtc_state *state)
} }
/** /**
* drm_atomic_helper_check - validate state object for modeset changes * drm_atomic_helper_check_modeset - validate state object for modeset changes
* @dev: DRM device * @dev: DRM device
* @state: the driver state object * @state: the driver state object
* *
...@@ -461,7 +461,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -461,7 +461,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
EXPORT_SYMBOL(drm_atomic_helper_check_modeset); EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
/** /**
* drm_atomic_helper_check - validate state object for modeset changes * drm_atomic_helper_check_planes - validate state object for planes changes
* @dev: DRM device * @dev: DRM device
* @state: the driver state object * @state: the driver state object
* *
...@@ -481,7 +481,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev, ...@@ -481,7 +481,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
int i, ret = 0; int i, ret = 0;
for (i = 0; i < nplanes; i++) { for (i = 0; i < nplanes; i++) {
struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
struct drm_plane *plane = state->planes[i]; struct drm_plane *plane = state->planes[i];
struct drm_plane_state *plane_state = state->plane_states[i]; struct drm_plane_state *plane_state = state->plane_states[i];
...@@ -504,7 +504,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev, ...@@ -504,7 +504,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
} }
for (i = 0; i < ncrtcs; i++) { for (i = 0; i < ncrtcs; i++) {
struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
struct drm_crtc *crtc = state->crtcs[i]; struct drm_crtc *crtc = state->crtcs[i];
if (!crtc) if (!crtc)
...@@ -571,9 +571,9 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -571,9 +571,9 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
int i; int i;
for (i = 0; i < old_state->num_connector; i++) { for (i = 0; i < old_state->num_connector; i++) {
const struct drm_encoder_helper_funcs *funcs;
struct drm_connector_state *old_conn_state; struct drm_connector_state *old_conn_state;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *old_crtc_state;
...@@ -605,7 +605,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -605,7 +605,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
/* /*
* Each encoder has at most one connector (since we always steal * Each encoder has at most one connector (since we always steal
* it away), so we won't call call disable hooks twice. * it away), so we won't call disable hooks twice.
*/ */
if (encoder->bridge) if (encoder->bridge)
encoder->bridge->funcs->disable(encoder->bridge); encoder->bridge->funcs->disable(encoder->bridge);
...@@ -623,7 +623,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -623,7 +623,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
} }
for (i = 0; i < ncrtcs; i++) { for (i = 0; i < ncrtcs; i++) {
struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *old_crtc_state;
...@@ -713,7 +713,7 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -713,7 +713,7 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
int i; int i;
for (i = 0; i < ncrtcs; i++) { for (i = 0; i < ncrtcs; i++) {
struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
struct drm_crtc *crtc; struct drm_crtc *crtc;
crtc = old_state->crtcs[i]; crtc = old_state->crtcs[i];
...@@ -732,9 +732,9 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -732,9 +732,9 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
} }
for (i = 0; i < old_state->num_connector; i++) { for (i = 0; i < old_state->num_connector; i++) {
const struct drm_encoder_helper_funcs *funcs;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_crtc_state *new_crtc_state; struct drm_crtc_state *new_crtc_state;
struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_display_mode *mode, *adjusted_mode; struct drm_display_mode *mode, *adjusted_mode;
...@@ -757,7 +757,7 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -757,7 +757,7 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
/* /*
* Each encoder has at most one connector (since we always steal * Each encoder has at most one connector (since we always steal
* it away), so we won't call call mode_set hooks twice. * it away), so we won't call mode_set hooks twice.
*/ */
if (funcs->mode_set) if (funcs->mode_set)
funcs->mode_set(encoder, mode, adjusted_mode); funcs->mode_set(encoder, mode, adjusted_mode);
...@@ -812,7 +812,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, ...@@ -812,7 +812,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
int i; int i;
for (i = 0; i < ncrtcs; i++) { for (i = 0; i < ncrtcs; i++) {
struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
struct drm_crtc *crtc; struct drm_crtc *crtc;
crtc = old_state->crtcs[i]; crtc = old_state->crtcs[i];
...@@ -838,8 +838,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, ...@@ -838,8 +838,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
} }
for (i = 0; i < old_state->num_connector; i++) { for (i = 0; i < old_state->num_connector; i++) {
const struct drm_encoder_helper_funcs *funcs;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder; struct drm_encoder *encoder;
connector = old_state->connectors[i]; connector = old_state->connectors[i];
...@@ -858,7 +858,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, ...@@ -858,7 +858,7 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
/* /*
* Each encoder has at most one connector (since we always steal * Each encoder has at most one connector (since we always steal
* it away), so we won't call call enable hooks twice. * it away), so we won't call enable hooks twice.
*/ */
if (encoder->bridge) if (encoder->bridge)
encoder->bridge->funcs->pre_enable(encoder->bridge); encoder->bridge->funcs->pre_enable(encoder->bridge);
...@@ -1025,7 +1025,7 @@ int drm_atomic_helper_commit(struct drm_device *dev, ...@@ -1025,7 +1025,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
/* /*
* Everything below can be run asynchronously without the need to grab * Everything below can be run asynchronously without the need to grab
* any modeset locks at all under one conditions: It must be guaranteed * any modeset locks at all under one condition: It must be guaranteed
* that the asynchronous work has either been cancelled (if the driver * that the asynchronous work has either been cancelled (if the driver
* supports it, which at least requires that the framebuffers get * supports it, which at least requires that the framebuffers get
* cleaned up with drm_atomic_helper_cleanup_planes()) or completed * cleaned up with drm_atomic_helper_cleanup_planes()) or completed
...@@ -1114,7 +1114,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev, ...@@ -1114,7 +1114,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
int ret, i; int ret, i;
for (i = 0; i < nplanes; i++) { for (i = 0; i < nplanes; i++) {
struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
struct drm_plane *plane = state->planes[i]; struct drm_plane *plane = state->planes[i];
struct drm_plane_state *plane_state = state->plane_states[i]; struct drm_plane_state *plane_state = state->plane_states[i];
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
...@@ -1137,7 +1137,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev, ...@@ -1137,7 +1137,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
fail: fail:
for (i--; i >= 0; i--) { for (i--; i >= 0; i--) {
struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
struct drm_plane *plane = state->planes[i]; struct drm_plane *plane = state->planes[i];
struct drm_plane_state *plane_state = state->plane_states[i]; struct drm_plane_state *plane_state = state->plane_states[i];
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
...@@ -1179,7 +1179,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, ...@@ -1179,7 +1179,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
int i; int i;
for (i = 0; i < ncrtcs; i++) { for (i = 0; i < ncrtcs; i++) {
struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
struct drm_crtc *crtc = old_state->crtcs[i]; struct drm_crtc *crtc = old_state->crtcs[i];
if (!crtc) if (!crtc)
...@@ -1194,7 +1194,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, ...@@ -1194,7 +1194,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
} }
for (i = 0; i < nplanes; i++) { for (i = 0; i < nplanes; i++) {
struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
struct drm_plane *plane = old_state->planes[i]; struct drm_plane *plane = old_state->planes[i];
struct drm_plane_state *old_plane_state; struct drm_plane_state *old_plane_state;
...@@ -1219,7 +1219,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, ...@@ -1219,7 +1219,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
} }
for (i = 0; i < ncrtcs; i++) { for (i = 0; i < ncrtcs; i++) {
struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
struct drm_crtc *crtc = old_state->crtcs[i]; struct drm_crtc *crtc = old_state->crtcs[i];
if (!crtc) if (!crtc)
...@@ -1254,7 +1254,7 @@ void drm_atomic_helper_cleanup_planes(struct drm_device *dev, ...@@ -1254,7 +1254,7 @@ void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
int i; int i;
for (i = 0; i < nplanes; i++) { for (i = 0; i < nplanes; i++) {
struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
struct drm_plane *plane = old_state->planes[i]; struct drm_plane *plane = old_state->planes[i];
struct drm_plane_state *plane_state = old_state->plane_states[i]; struct drm_plane_state *plane_state = old_state->plane_states[i];
struct drm_framebuffer *old_fb; struct drm_framebuffer *old_fb;
...@@ -2001,10 +2001,10 @@ void drm_atomic_helper_connector_dpms(struct drm_connector *connector, ...@@ -2001,10 +2001,10 @@ void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
list_for_each_entry(tmp_connector, &config->connector_list, head) { list_for_each_entry(tmp_connector, &config->connector_list, head) {
if (connector->state->crtc != crtc) if (tmp_connector->state->crtc != crtc)
continue; continue;
if (connector->dpms == DRM_MODE_DPMS_ON) { if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
active = true; active = true;
break; break;
} }
......
...@@ -49,7 +49,7 @@ void drm_bridge_remove(struct drm_bridge *bridge) ...@@ -49,7 +49,7 @@ void drm_bridge_remove(struct drm_bridge *bridge)
} }
EXPORT_SYMBOL(drm_bridge_remove); EXPORT_SYMBOL(drm_bridge_remove);
extern int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge) int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge)
{ {
if (!dev || !bridge) if (!dev || !bridge)
return -EINVAL; return -EINVAL;
......
...@@ -659,6 +659,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, ...@@ -659,6 +659,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
struct drm_mode_config *config = &dev->mode_config; struct drm_mode_config *config = &dev->mode_config;
int ret; int ret;
WARN_ON(primary && primary->type != DRM_PLANE_TYPE_PRIMARY);
WARN_ON(cursor && cursor->type != DRM_PLANE_TYPE_CURSOR);
crtc->dev = dev; crtc->dev = dev;
crtc->funcs = funcs; crtc->funcs = funcs;
crtc->invert_dimensions = false; crtc->invert_dimensions = false;
......
...@@ -427,11 +427,13 @@ static u32 drm_dp_i2c_functionality(struct i2c_adapter *adapter) ...@@ -427,11 +427,13 @@ static u32 drm_dp_i2c_functionality(struct i2c_adapter *adapter)
* retrying the transaction as appropriate. It is assumed that the * retrying the transaction as appropriate. It is assumed that the
* aux->transfer function does not modify anything in the msg other than the * aux->transfer function does not modify anything in the msg other than the
* reply field. * reply field.
*
* Returns bytes transferred on success, or a negative error code on failure.
*/ */
static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
{ {
unsigned int retry; unsigned int retry;
int err; int ret;
/* /*
* DP1.2 sections 2.7.7.1.5.6.1 and 2.7.7.1.6.6.1: A DP Source device * DP1.2 sections 2.7.7.1.5.6.1 and 2.7.7.1.6.6.1: A DP Source device
...@@ -440,14 +442,14 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) ...@@ -440,14 +442,14 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
*/ */
for (retry = 0; retry < 7; retry++) { for (retry = 0; retry < 7; retry++) {
mutex_lock(&aux->hw_mutex); mutex_lock(&aux->hw_mutex);
err = aux->transfer(aux, msg); ret = aux->transfer(aux, msg);
mutex_unlock(&aux->hw_mutex); mutex_unlock(&aux->hw_mutex);
if (err < 0) { if (ret < 0) {
if (err == -EBUSY) if (ret == -EBUSY)
continue; continue;
DRM_DEBUG_KMS("transaction failed: %d\n", err); DRM_DEBUG_KMS("transaction failed: %d\n", ret);
return err; return ret;
} }
...@@ -488,9 +490,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) ...@@ -488,9 +490,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
* Both native ACK and I2C ACK replies received. We * Both native ACK and I2C ACK replies received. We
* can assume the transfer was successful. * can assume the transfer was successful.
*/ */
if (err < msg->size) return ret;
return -EPROTO;
return 0;
case DP_AUX_I2C_REPLY_NACK: case DP_AUX_I2C_REPLY_NACK:
DRM_DEBUG_KMS("I2C nack\n"); DRM_DEBUG_KMS("I2C nack\n");
...@@ -513,14 +513,55 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) ...@@ -513,14 +513,55 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
return -EREMOTEIO; return -EREMOTEIO;
} }
/*
* Keep retrying drm_dp_i2c_do_msg until all data has been transferred.
*
* Returns an error code on failure, or a recommended transfer size on success.
*/
static int drm_dp_i2c_drain_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *orig_msg)
{
int err, ret = orig_msg->size;
struct drm_dp_aux_msg msg = *orig_msg;
while (msg.size > 0) {
err = drm_dp_i2c_do_msg(aux, &msg);
if (err <= 0)
return err == 0 ? -EPROTO : err;
if (err < msg.size && err < ret) {
DRM_DEBUG_KMS("Partial I2C reply: requested %zu bytes got %d bytes\n",
msg.size, err);
ret = err;
}
msg.size -= err;
msg.buffer += err;
}
return ret;
}
/*
* Bizlink designed DP->DVI-D Dual Link adapters require the I2C over AUX
* packets to be as large as possible. If not, the I2C transactions never
* succeed. Hence the default is maximum.
*/
static int dp_aux_i2c_transfer_size __read_mostly = DP_AUX_MAX_PAYLOAD_BYTES;
module_param_unsafe(dp_aux_i2c_transfer_size, int, 0644);
MODULE_PARM_DESC(dp_aux_i2c_transfer_size,
"Number of bytes to transfer in a single I2C over DP AUX CH message, (1-16, default 16)");
static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
int num) int num)
{ {
struct drm_dp_aux *aux = adapter->algo_data; struct drm_dp_aux *aux = adapter->algo_data;
unsigned int i, j; unsigned int i, j;
unsigned transfer_size;
struct drm_dp_aux_msg msg; struct drm_dp_aux_msg msg;
int err = 0; int err = 0;
dp_aux_i2c_transfer_size = clamp(dp_aux_i2c_transfer_size, 1, DP_AUX_MAX_PAYLOAD_BYTES);
memset(&msg, 0, sizeof(msg)); memset(&msg, 0, sizeof(msg));
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
...@@ -538,20 +579,19 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, ...@@ -538,20 +579,19 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
err = drm_dp_i2c_do_msg(aux, &msg); err = drm_dp_i2c_do_msg(aux, &msg);
if (err < 0) if (err < 0)
break; break;
/* /* We want each transaction to be as large as possible, but
* Many hardware implementations support FIFOs larger than a * we'll go to smaller sizes if the hardware gives us a
* single byte, but it has been empirically determined that * short reply.
* transferring data in larger chunks can actually lead to
* decreased performance. Therefore each message is simply
* transferred byte-by-byte.
*/ */
for (j = 0; j < msgs[i].len; j++) { transfer_size = dp_aux_i2c_transfer_size;
for (j = 0; j < msgs[i].len; j += msg.size) {
msg.buffer = msgs[i].buf + j; msg.buffer = msgs[i].buf + j;
msg.size = 1; msg.size = min(transfer_size, msgs[i].len - j);
err = drm_dp_i2c_do_msg(aux, &msg); err = drm_dp_i2c_drain_msg(aux, &msg);
if (err < 0) if (err < 0)
break; break;
transfer_size = err;
} }
if (err < 0) if (err < 0)
break; break;
......
...@@ -70,7 +70,7 @@ void drm_err(const char *format, ...) ...@@ -70,7 +70,7 @@ void drm_err(const char *format, ...)
vaf.fmt = format; vaf.fmt = format;
vaf.va = &args; vaf.va = &args;
printk(KERN_ERR "[" DRM_NAME ":%pf] *ERROR* %pV", printk(KERN_ERR "[" DRM_NAME ":%ps] *ERROR* %pV",
__builtin_return_address(0), &vaf); __builtin_return_address(0), &vaf);
va_end(args); va_end(args);
......
...@@ -304,7 +304,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, ...@@ -304,7 +304,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
} }
drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
offset = fbi->var.xoffset * bytes_per_pixel; offset = fbi->var.xoffset * bytes_per_pixel;
offset += fbi->var.yoffset * fb->pitches[0]; offset += fbi->var.yoffset * fb->pitches[0];
......
...@@ -1034,23 +1034,45 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, ...@@ -1034,23 +1034,45 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
crtc_count = 0; crtc_count = 0;
for (i = 0; i < fb_helper->crtc_count; i++) { for (i = 0; i < fb_helper->crtc_count; i++) {
struct drm_display_mode *desired_mode; struct drm_display_mode *desired_mode;
int x, y; struct drm_mode_set *mode_set;
int x, y, j;
/* in case of tile group, are we the last tile vert or horiz?
* If no tile group you are always the last one both vertically
* and horizontally
*/
bool lastv = true, lasth = true;
desired_mode = fb_helper->crtc_info[i].desired_mode; desired_mode = fb_helper->crtc_info[i].desired_mode;
mode_set = &fb_helper->crtc_info[i].mode_set;
if (!desired_mode)
continue;
crtc_count++;
x = fb_helper->crtc_info[i].x; x = fb_helper->crtc_info[i].x;
y = fb_helper->crtc_info[i].y; y = fb_helper->crtc_info[i].y;
if (desired_mode) {
if (gamma_size == 0) if (gamma_size == 0)
gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size; gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size;
if (desired_mode->hdisplay + x < sizes.fb_width)
sizes.fb_width = desired_mode->hdisplay + x; sizes.surface_width = max_t(u32, desired_mode->hdisplay + x, sizes.surface_width);
if (desired_mode->vdisplay + y < sizes.fb_height) sizes.surface_height = max_t(u32, desired_mode->vdisplay + y, sizes.surface_height);
sizes.fb_height = desired_mode->vdisplay + y;
if (desired_mode->hdisplay + x > sizes.surface_width) for (j = 0; j < mode_set->num_connectors; j++) {
sizes.surface_width = desired_mode->hdisplay + x; struct drm_connector *connector = mode_set->connectors[j];
if (desired_mode->vdisplay + y > sizes.surface_height) if (connector->has_tile) {
sizes.surface_height = desired_mode->vdisplay + y; lasth = (connector->tile_h_loc == (connector->num_h_tile - 1));
crtc_count++; lastv = (connector->tile_v_loc == (connector->num_v_tile - 1));
/* cloning to multiple tiles is just crazy-talk, so: */
break;
}
} }
if (lasth)
sizes.fb_width = min_t(u32, desired_mode->hdisplay + x, sizes.fb_width);
if (lastv)
sizes.fb_height = min_t(u32, desired_mode->vdisplay + y, sizes.fb_height);
} }
if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) { if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_gem.h> #include <drm/drm_gem.h>
#include "drm_internal.h"
#include "drm_legacy.h" #include "drm_legacy.h"
/** /**
......
...@@ -1016,7 +1016,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, ...@@ -1016,7 +1016,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
return 0; return 0;
} }
drm_ioctl_compat_t *drm_compat_ioctls[] = { static drm_ioctl_compat_t *drm_compat_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version, [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version,
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique, [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique,
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap, [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap,
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/export.h> #include <linux/export.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include "drm_internal.h"
#include "drm_legacy.h" #include "drm_legacy.h"
/** /**
......
...@@ -353,13 +353,14 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev) ...@@ -353,13 +353,14 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev)
if (primary == NULL) { if (primary == NULL) {
DRM_DEBUG_KMS("Failed to allocate primary plane\n"); DRM_DEBUG_KMS("Failed to allocate primary plane\n");
return NULL; return NULL;
/*
* Remove the format_default field from drm_plane when dropping
* this helper.
*/
primary->format_default = true;
} }
/*
* Remove the format_default field from drm_plane when dropping
* this helper.
*/
primary->format_default = true;
/* possible_crtc's will be filled in later by crtc_init */ /* possible_crtc's will be filled in later by crtc_init */
ret = drm_universal_plane_init(dev, primary, 0, ret = drm_universal_plane_init(dev, primary, 0,
&drm_primary_helper_funcs, &drm_primary_helper_funcs,
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#endif #endif
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include "drm_internal.h"
#include "drm_legacy.h" #include "drm_legacy.h"
struct drm_vma_entry { struct drm_vma_entry {
......
...@@ -76,6 +76,7 @@ static struct fb_ops exynos_drm_fb_ops = { ...@@ -76,6 +76,7 @@ static struct fb_ops exynos_drm_fb_ops = {
}; };
static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes,
struct drm_framebuffer *fb) struct drm_framebuffer *fb)
{ {
struct fb_info *fbi = helper->fbdev; struct fb_info *fbi = helper->fbdev;
...@@ -85,7 +86,7 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, ...@@ -85,7 +86,7 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
unsigned long offset; unsigned long offset;
drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
/* RGB formats use only one buffer */ /* RGB formats use only one buffer */
buffer = exynos_drm_fb_buffer(fb, 0); buffer = exynos_drm_fb_buffer(fb, 0);
...@@ -189,7 +190,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, ...@@ -189,7 +190,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
goto err_destroy_framebuffer; goto err_destroy_framebuffer;
} }
ret = exynos_drm_fbdev_update(helper, helper->fb); ret = exynos_drm_fbdev_update(helper, sizes, helper->fb);
if (ret < 0) if (ret < 0)
goto err_dealloc_cmap; goto err_dealloc_cmap;
......
...@@ -106,7 +106,7 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper, ...@@ -106,7 +106,7 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
fb = helper->fb; fb = helper->fb;
drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height); drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
offset = fbi->var.xoffset * bytes_per_pixel; offset = fbi->var.xoffset * bytes_per_pixel;
offset += fbi->var.yoffset * fb->pitches[0]; offset += fbi->var.yoffset * fb->pitches[0];
......
...@@ -915,7 +915,7 @@ struct drm_bridge { ...@@ -915,7 +915,7 @@ struct drm_bridge {
}; };
/** /**
* struct struct drm_atomic_state - the global state object for atomic updates * struct drm_atomic_state - the global state object for atomic updates
* @dev: parent DRM device * @dev: parent DRM device
* @allow_modeset: allow full modeset * @allow_modeset: allow full modeset
* @legacy_cursor_update: hint to enforce legacy cursor ioctl semantics * @legacy_cursor_update: hint to enforce legacy cursor ioctl semantics
......
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
* 1.2 formally includes both eDP and DPI definitions. * 1.2 formally includes both eDP and DPI definitions.
*/ */
#define DP_AUX_MAX_PAYLOAD_BYTES 16
#define DP_AUX_I2C_WRITE 0x0 #define DP_AUX_I2C_WRITE 0x0
#define DP_AUX_I2C_READ 0x1 #define DP_AUX_I2C_READ 0x1
#define DP_AUX_I2C_STATUS 0x2 #define DP_AUX_I2C_STATUS 0x2
...@@ -680,6 +682,9 @@ struct drm_dp_aux_msg { ...@@ -680,6 +682,9 @@ struct drm_dp_aux_msg {
* transactions. The drm_dp_aux_register_i2c_bus() function registers an * transactions. The drm_dp_aux_register_i2c_bus() function registers an
* I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers * I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers
* should call drm_dp_aux_unregister_i2c_bus() to remove the I2C adapter. * should call drm_dp_aux_unregister_i2c_bus() to remove the I2C adapter.
* The I2C adapter uses long transfers by default; if a partial response is
* received, the adapter will drop down to the size given by the partial
* response for this transaction only.
* *
* Note that the aux helper code assumes that the .transfer() function * Note that the aux helper code assumes that the .transfer() function
* only modifies the reply field of the drm_dp_aux_msg structure. The * only modifies the reply field of the drm_dp_aux_msg structure. The
......
...@@ -44,6 +44,25 @@ struct drm_fb_helper_crtc { ...@@ -44,6 +44,25 @@ struct drm_fb_helper_crtc {
int x, y; int x, y;
}; };
/**
* struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size
* @fb_width: fbdev width
* @fb_height: fbdev height
* @surface_width: scanout buffer width
* @surface_height: scanout buffer height
* @surface_bpp: scanout buffer bpp
* @surface_depth: scanout buffer depth
*
* Note that the scanout surface width/height may be larger than the fbdev
* width/height. In case of multiple displays, the scanout surface is sized
* according to the largest width/height (so it is large enough for all CRTCs
* to scanout). But the fbdev width/height is sized to the minimum width/
* height of all the displays. This ensures that fbcon fits on the smallest
* of the attached displays.
*
* So what is passed to drm_fb_helper_fill_var() should be fb_width/fb_height,
* rather than the surface size.
*/
struct drm_fb_helper_surface_size { struct drm_fb_helper_surface_size {
u32 fb_width; u32 fb_width;
u32 fb_height; u32 fb_height;
......
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