Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux into drm-misc-next
Resync with drm-next, I have a patch which currently can't be applied
because drm-misc-next lacked the latest drm/i915 code.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
diff --git a/Documentation/gpu/introduction.rst b/Documentation/gpu/introduction.rst
index 1f8bd5e..05a82bd 100644
--- a/Documentation/gpu/introduction.rst
+++ b/Documentation/gpu/introduction.rst
@@ -60,3 +60,28 @@
Anyone looking to kick it up a notch can find a list of janitorial tasks on
the :ref:`TODO list <todo>`.
+
+Contribution Process
+====================
+
+Mostly the DRM subsystem works like any other kernel subsystem, see :ref:`the
+main process guidelines and documentation <process_index>` for how things work.
+Here we just document some of the specialities of the GPU subsystem.
+
+Feature Merge Deadlines
+-----------------------
+
+All feature work must be in the linux-next tree by the -rc6 release of the
+current release cycle, otherwise they must be postponed and can't reach the next
+merge window. All patches must have landed in the drm-next tree by latest -rc7,
+but if your branch is not in linux-next then this must have happened by -rc6
+already.
+
+After that point only bugfixes (like after the upstream merge window has closed
+with the -rc1 release) are allowed. No new platform enabling or new drivers are
+allowed.
+
+This means that there's a blackout-period of about one month where feature work
+can't be merged. The recommended way to deal with that is having a -next tree
+that's always open, but making sure to not feed it into linux-next during the
+blackout period. As an example, drm-misc works like that.
diff --git a/Documentation/process/index.rst b/Documentation/process/index.rst
index 10aa692..82fc399 100644
--- a/Documentation/process/index.rst
+++ b/Documentation/process/index.rst
@@ -3,6 +3,7 @@
\renewcommand\thesection*
\renewcommand\thesubsection*
+.. _process_index:
Working with the kernel development community
=============================================
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index f2cc375..d3fc7e4 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2042,10 +2042,6 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
goto out_unlock;
}
- mgr->total_pbn = 2560;
- mgr->total_slots = DIV_ROUND_UP(mgr->total_pbn, mgr->pbn_div);
- mgr->avail_slots = mgr->total_slots;
-
/* add initial branch device at LCT 1 */
mstb = drm_dp_add_mst_branch_device(1, NULL);
if (mstb == NULL) {
@@ -2475,26 +2471,25 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
- if (num_slots > mgr->avail_slots)
+ /* max. time slots - one slot for MTP header */
+ if (num_slots > 63)
return -ENOSPC;
return num_slots;
}
EXPORT_SYMBOL(drm_dp_find_vcpi_slots);
static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
- struct drm_dp_vcpi *vcpi, int pbn)
+ struct drm_dp_vcpi *vcpi, int pbn, int slots)
{
- int num_slots;
int ret;
- num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
-
- if (num_slots > mgr->avail_slots)
+ /* max. time slots - one slot for MTP header */
+ if (slots > 63)
return -ENOSPC;
vcpi->pbn = pbn;
- vcpi->aligned_pbn = num_slots * mgr->pbn_div;
- vcpi->num_slots = num_slots;
+ vcpi->aligned_pbn = slots * mgr->pbn_div;
+ vcpi->num_slots = slots;
ret = drm_dp_mst_assign_payload_id(mgr, vcpi);
if (ret < 0)
@@ -2509,7 +2504,8 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
* @pbn: payload bandwidth number to request
* @slots: returned number of slots for this PBN.
*/
-bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn, int *slots)
+bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_port *port, int pbn, int slots)
{
int ret;
@@ -2517,22 +2513,25 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
if (!port)
return false;
+ if (slots < 0)
+ return false;
+
if (port->vcpi.vcpi > 0) {
DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - requested pbn %d\n", port->vcpi.vcpi, port->vcpi.pbn, pbn);
if (pbn == port->vcpi.pbn) {
- *slots = port->vcpi.num_slots;
drm_dp_put_port(port);
return true;
}
}
- ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn);
+ ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
if (ret) {
- DRM_DEBUG_KMS("failed to init vcpi %d %d %d\n", DIV_ROUND_UP(pbn, mgr->pbn_div), mgr->avail_slots, ret);
+ DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n",
+ DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
goto out;
}
- DRM_DEBUG_KMS("initing vcpi for %d %d\n", pbn, port->vcpi.num_slots);
- *slots = port->vcpi.num_slots;
+ DRM_DEBUG_KMS("initing vcpi for pbn=%d slots=%d\n",
+ pbn, port->vcpi.num_slots);
drm_dp_put_port(port);
return true;
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index 74cd393..50abd1f 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -177,7 +177,7 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
int ret;
int i;
- info = drm_format_info(mode_cmd->pixel_format);
+ info = drm_get_format_info(dev, mode_cmd);
if (!info)
return ERR_PTR(-EINVAL);
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 92bf330..9c0152d 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -207,6 +207,31 @@ const struct drm_format_info *drm_format_info(u32 format)
EXPORT_SYMBOL(drm_format_info);
/**
+ * drm_get_format_info - query information for a given framebuffer configuration
+ * @dev: DRM device
+ * @mode_cmd: metadata from the userspace fb creation request
+ *
+ * Returns:
+ * The instance of struct drm_format_info that describes the pixel format, or
+ * NULL if the format is unsupported.
+ */
+const struct drm_format_info *
+drm_get_format_info(struct drm_device *dev,
+ const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ const struct drm_format_info *info = NULL;
+
+ if (dev->mode_config.funcs->get_format_info)
+ info = dev->mode_config.funcs->get_format_info(mode_cmd);
+
+ if (!info)
+ info = drm_format_info(mode_cmd->pixel_format);
+
+ return info;
+}
+EXPORT_SYMBOL(drm_get_format_info);
+
+/**
* drm_format_num_planes - get the number of planes for format
* @format: pixel format (DRM_FORMAT_*)
*
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index e4909ae..e8f9c13 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -126,11 +126,31 @@ int drm_mode_addfb(struct drm_device *dev,
return 0;
}
-static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
+static int fb_plane_width(int width,
+ const struct drm_format_info *format, int plane)
+{
+ if (plane == 0)
+ return width;
+
+ return DIV_ROUND_UP(width, format->hsub);
+}
+
+static int fb_plane_height(int height,
+ const struct drm_format_info *format, int plane)
+{
+ if (plane == 0)
+ return height;
+
+ return DIV_ROUND_UP(height, format->vsub);
+}
+
+static int framebuffer_check(struct drm_device *dev,
+ const struct drm_mode_fb_cmd2 *r)
{
const struct drm_format_info *info;
int i;
+ /* check if the format is supported at all */
info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN);
if (!info) {
struct drm_format_name_buf format_name;
@@ -140,19 +160,22 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
return -EINVAL;
}
- if (r->width == 0 || r->width % info->hsub) {
+ /* now let the driver pick its own format info */
+ info = drm_get_format_info(dev, r);
+
+ if (r->width == 0) {
DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
return -EINVAL;
}
- if (r->height == 0 || r->height % info->vsub) {
+ if (r->height == 0) {
DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
return -EINVAL;
}
for (i = 0; i < info->num_planes; i++) {
- unsigned int width = r->width / (i != 0 ? info->hsub : 1);
- unsigned int height = r->height / (i != 0 ? info->vsub : 1);
+ unsigned int width = fb_plane_width(r->width, info, i);
+ unsigned int height = fb_plane_height(r->height, info, i);
unsigned int cpp = info->cpp[i];
if (!r->handles[i]) {
@@ -263,7 +286,7 @@ drm_internal_framebuffer_create(struct drm_device *dev,
return ERR_PTR(-EINVAL);
}
- ret = framebuffer_check(r);
+ ret = framebuffer_check(dev, r);
if (ret)
return ERR_PTR(ret);
@@ -816,10 +839,7 @@ int drm_framebuffer_plane_width(int width,
if (plane >= fb->format->num_planes)
return 0;
- if (plane == 0)
- return width;
-
- return width / fb->format->hsub;
+ return fb_plane_width(width, fb->format, plane);
}
EXPORT_SYMBOL(drm_framebuffer_plane_width);
@@ -838,9 +858,6 @@ int drm_framebuffer_plane_height(int height,
if (plane >= fb->format->num_planes)
return 0;
- if (plane == 0)
- return height;
-
- return height / fb->format->vsub;
+ return fb_plane_height(height, fb->format, plane);
}
EXPORT_SYMBOL(drm_framebuffer_plane_height);
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index cc44a9a..2b33825 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -78,7 +78,7 @@ void drm_helper_mode_fill_fb_struct(struct drm_device *dev,
int i;
fb->dev = dev;
- fb->format = drm_format_info(mode_cmd->pixel_format);
+ fb->format = drm_get_format_info(dev, mode_cmd);
fb->width = mode_cmd->width;
fb->height = mode_cmd->height;
for (i = 0; i < 4; i++) {
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 094cbdc..c1f62eb 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -149,7 +149,6 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
to_intel_connector(conn_state->connector);
int ret;
uint32_t temp;
- int slots;
/* MST encoders are bound to a crtc, not to a connector,
* force the mapping here for get_hw_state.
@@ -165,7 +164,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
connector->port,
- pipe_config->pbn, &slots);
+ pipe_config->pbn,
+ pipe_config->dp_m_n.tu);
if (ret == false) {
DRM_ERROR("failed to allocate vcpi\n");
return;
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 7ad1ee5..418872b 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -2895,7 +2895,8 @@ nv50_msto_enable(struct drm_encoder *encoder)
if (WARN_ON(!mstc))
return;
- r = drm_dp_mst_allocate_vcpi(&mstm->mgr, mstc->port, mstc->pbn, &slots);
+ slots = drm_dp_find_vcpi_slots(&mstm->mgr, mstc->pbn);
+ r = drm_dp_mst_allocate_vcpi(&mstm->mgr, mstc->port, mstc->pbn, slots);
WARN_ON(!r);
if (mstm->outp->dcb->sorconf.link & 1)
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index 7d5ada3..6598306 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -453,9 +453,11 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
DRM_DEBUG_KMS("dig encoder is %d %d %d\n", dig_enc->dig_encoder,
dig_enc->linkb, radeon_crtc->crtc_id);
+ slots = drm_dp_find_vcpi_slots(&radeon_connector->mst_port->mst_mgr,
+ mst_enc->pbn);
ret = drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
radeon_connector->port,
- mst_enc->pbn, &slots);
+ mst_enc->pbn, slots);
ret = drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
radeon_dp_mst_set_be_cntl(primary, mst_enc,
diff --git a/drivers/gpu/drm/zte/zx_hdmi.c b/drivers/gpu/drm/zte/zx_hdmi.c
index c47b9cb..0df7366 100644
--- a/drivers/gpu/drm/zte/zx_hdmi.c
+++ b/drivers/gpu/drm/zte/zx_hdmi.c
@@ -50,7 +50,6 @@ struct zx_hdmi {
struct clk *xclk;
bool sink_is_hdmi;
bool sink_has_audio;
- const struct vou_inf *inf;
struct platform_device *audio_pdev;
};
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index f4b4d15..5b02476 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -479,18 +479,6 @@ struct drm_dp_mst_topology_mgr {
* @pbn_div: PBN to slots divisor.
*/
int pbn_div;
- /**
- * @total_slots: Total slots that can be allocated.
- */
- int total_slots;
- /**
- * @avail_slots: Still available slots that can be allocated.
- */
- int avail_slots;
- /**
- * @total_pbn: Total PBN count.
- */
- int total_pbn;
/**
* @qlock: protects @tx_msg_downq, the &drm_dp_mst_branch.txslost and
@@ -579,7 +567,8 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_
int drm_dp_calc_pbn_mode(int clock, int bpp);
-bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn, int *slots);
+bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_port *port, int pbn, int slots);
int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index fcc08da..6942e84 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -25,6 +25,9 @@
#include <linux/types.h>
#include <uapi/drm/drm_fourcc.h>
+struct drm_device;
+struct drm_mode_fb_cmd2;
+
/**
* struct drm_format_info - information about a DRM format
* @format: 4CC format identifier (DRM_FORMAT_*)
@@ -55,6 +58,9 @@ struct drm_format_name_buf {
const struct drm_format_info *__drm_format_info(u32 format);
const struct drm_format_info *drm_format_info(u32 format);
+const struct drm_format_info *
+drm_get_format_info(struct drm_device *dev,
+ const struct drm_mode_fb_cmd2 *mode_cmd);
uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
int drm_format_num_planes(uint32_t format);
int drm_format_plane_cpp(uint32_t format, int plane);
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index ea169a90..579070f 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -34,6 +34,7 @@ struct drm_file;
struct drm_device;
struct drm_atomic_state;
struct drm_mode_fb_cmd2;
+struct drm_format_info;
/**
* struct drm_mode_config_funcs - basic driver provided mode setting functions
@@ -70,6 +71,19 @@ struct drm_mode_config_funcs {
const struct drm_mode_fb_cmd2 *mode_cmd);
/**
+ * @get_format_info:
+ *
+ * Allows a driver to return custom format information for special
+ * fb layouts (eg. ones with auxiliary compression control planes).
+ *
+ * RETURNS:
+ *
+ * The format information specific to the given fb metadata, or
+ * NULL if none is found.
+ */
+ const struct drm_format_info *(*get_format_info)(const struct drm_mode_fb_cmd2 *mode_cmd);
+
+ /**
* @output_poll_changed:
*
* Callback used by helpers to inform the driver of output configuration