summaryrefslogtreecommitdiff
path: root/include/drm
diff options
context:
space:
mode:
Diffstat (limited to 'include/drm')
-rw-r--r--include/drm/drm_atomic.h3
-rw-r--r--include/drm/drm_bridge.h275
-rw-r--r--include/drm/drm_dp_helper.h8
-rw-r--r--include/drm/drm_dp_mst_helper.h20
-rw-r--r--include/drm/drm_fb_cma_helper.h2
-rw-r--r--include/drm/gpu_scheduler.h8
-rw-r--r--include/drm/task_barrier.h107
7 files changed, 144 insertions, 279 deletions
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index ccce65e14917..951dfb15c27b 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -670,9 +670,6 @@ __drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
}
int __must_check
-drm_atomic_add_encoder_bridges(struct drm_atomic_state *state,
- struct drm_encoder *encoder);
-int __must_check
drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
struct drm_crtc *crtc);
int __must_check
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 46e15526b087..694e153a7531 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -25,8 +25,6 @@
#include <linux/list.h>
#include <linux/ctype.h>
-
-#include <drm/drm_atomic.h>
#include <drm/drm_encoder.h>
#include <drm/drm_mode_object.h>
#include <drm/drm_modes.h>
@@ -36,65 +34,6 @@ struct drm_bridge_timings;
struct drm_panel;
/**
- * struct drm_bus_cfg - bus configuration
- *
- * This structure stores the configuration of a physical bus between two
- * components in an output pipeline, usually between two bridges, an encoder
- * and a bridge, or a bridge and a connector.
- *
- * The bus configuration is stored in &drm_bridge_state separately for the
- * input and output buses, as seen from the point of view of each bridge. The
- * bus configuration of a bridge output is usually identical to the
- * configuration of the next bridge's input, but may differ if the signals are
- * modified between the two bridges, for instance by an inverter on the board.
- * The input and output configurations of a bridge may differ if the bridge
- * modifies the signals internally, for instance by performing format
- * conversion, or modifying signals polarities.
- */
-struct drm_bus_cfg {
- /**
- * @format: format used on this bus (one of the MEDIA_BUS_FMT_* format)
- *
- * This field should not be directly modified by drivers
- * (&drm_atomic_bridge_chain_select_bus_fmts() takes care of the bus
- * format negotiation).
- */
- u32 format;
-
- /**
- * @flags: DRM_BUS_* flags used on this bus
- */
- u32 flags;
-};
-
-/**
- * struct drm_bridge_state - Atomic bridge state object
- * @base: inherit from &drm_private_state
- * @bridge: the bridge this state refers to
- */
-struct drm_bridge_state {
- struct drm_private_state base;
-
- struct drm_bridge *bridge;
-
- /**
- * @input_bus_cfg: input bus configuration
- */
- struct drm_bus_cfg input_bus_cfg;
-
- /**
- * @output_bus_cfg: input bus configuration
- */
- struct drm_bus_cfg output_bus_cfg;
-};
-
-static inline struct drm_bridge_state *
-drm_priv_to_bridge_state(struct drm_private_state *priv)
-{
- return container_of(priv, struct drm_bridge_state, base);
-}
-
-/**
* struct drm_bridge_funcs - drm_bridge control functions
*/
struct drm_bridge_funcs {
@@ -170,9 +109,7 @@ struct drm_bridge_funcs {
* this function passes all other callbacks must succeed for this
* configuration.
*
- * The mode_fixup callback is optional. &drm_bridge_funcs.mode_fixup()
- * is not called when &drm_bridge_funcs.atomic_check() is implemented,
- * so only one of them should be provided.
+ * The @mode_fixup callback is optional.
*
* NOTE:
*
@@ -326,7 +263,7 @@ struct drm_bridge_funcs {
* The @atomic_pre_enable callback is optional.
*/
void (*atomic_pre_enable)(struct drm_bridge *bridge,
- struct drm_bridge_state *old_bridge_state);
+ struct drm_atomic_state *old_state);
/**
* @atomic_enable:
@@ -351,7 +288,7 @@ struct drm_bridge_funcs {
* The @atomic_enable callback is optional.
*/
void (*atomic_enable)(struct drm_bridge *bridge,
- struct drm_bridge_state *old_bridge_state);
+ struct drm_atomic_state *old_state);
/**
* @atomic_disable:
*
@@ -374,7 +311,7 @@ struct drm_bridge_funcs {
* The @atomic_disable callback is optional.
*/
void (*atomic_disable)(struct drm_bridge *bridge,
- struct drm_bridge_state *old_bridge_state);
+ struct drm_atomic_state *old_state);
/**
* @atomic_post_disable:
@@ -400,146 +337,7 @@ struct drm_bridge_funcs {
* The @atomic_post_disable callback is optional.
*/
void (*atomic_post_disable)(struct drm_bridge *bridge,
- struct drm_bridge_state *old_bridge_state);
-
- /**
- * @atomic_duplicate_state:
- *
- * Duplicate the current bridge state object (which is guaranteed to be
- * non-NULL).
- *
- * The atomic_duplicate_state() is optional. When not implemented the
- * core allocates a drm_bridge_state object and calls
- * &__drm_atomic_helper_bridge_duplicate_state() to initialize it.
- *
- * RETURNS:
- * A valid drm_bridge_state object or NULL if the allocation fails.
- */
- struct drm_bridge_state *(*atomic_duplicate_state)(struct drm_bridge *bridge);
-
- /**
- * @atomic_destroy_state:
- *
- * Destroy a bridge state object previously allocated by
- * &drm_bridge_funcs.atomic_duplicate_state().
- *
- * The atomic_destroy_state hook is optional. When not implemented the
- * core calls kfree() on the state.
- */
- void (*atomic_destroy_state)(struct drm_bridge *bridge,
- struct drm_bridge_state *state);
-
- /**
- * @atomic_get_output_bus_fmts:
- *
- * Return the supported bus formats on the output end of a bridge.
- * The returned array must be allocated with kmalloc() and will be
- * freed by the caller. If the allocation fails, NULL should be
- * returned. num_output_fmts must be set to the returned array size.
- * Formats listed in the returned array should be listed in decreasing
- * preference order (the core will try all formats until it finds one
- * that works).
- *
- * This method is only called on the last element of the bridge chain
- * as part of the bus format negotiation process that happens in
- * &drm_atomic_bridge_chain_select_bus_fmts().
- * This method is optional. When not implemented, the core will
- * fall back to &drm_connector.display_info.bus_formats[0] if
- * &drm_connector.display_info.num_bus_formats > 0,
- * or to MEDIA_BUS_FMT_FIXED otherwise.
- */
- u32 *(*atomic_get_output_bus_fmts)(struct drm_bridge *bridge,
- struct drm_bridge_state *bridge_state,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state,
- unsigned int *num_output_fmts);
-
- /**
- * @atomic_get_input_bus_fmts:
- *
- * Return the supported bus formats on the input end of a bridge for
- * a specific output bus format.
- *
- * The returned array must be allocated with kmalloc() and will be
- * freed by the caller. If the allocation fails, NULL should be
- * returned. num_output_fmts must be set to the returned array size.
- * Formats listed in the returned array should be listed in decreasing
- * preference order (the core will try all formats until it finds one
- * that works). When the format is not supported NULL should be
- * returned and *num_output_fmts should be set to 0.
- *
- * This method is called on all elements of the bridge chain as part of
- * the bus format negotiation process that happens in
- * &drm_atomic_bridge_chain_select_bus_fmts().
- * This method is optional. When not implemented, the core will bypass
- * bus format negotiation on this element of the bridge without
- * failing, and the previous element in the chain will be passed
- * MEDIA_BUS_FMT_FIXED as its output bus format.
- *
- * Bridge drivers that need to support being linked to bridges that are
- * not supporting bus format negotiation should handle the
- * output_fmt == MEDIA_BUS_FMT_FIXED case appropriately, by selecting a
- * sensible default value or extracting this information from somewhere
- * else (FW property, &drm_display_mode, &drm_display_info, ...)
- *
- * Note: Even if input format selection on the first bridge has no
- * impact on the negotiation process (bus format negotiation stops once
- * we reach the first element of the chain), drivers are expected to
- * return accurate input formats as the input format may be used to
- * configure the CRTC output appropriately.
- */
- u32 *(*atomic_get_input_bus_fmts)(struct drm_bridge *bridge,
- struct drm_bridge_state *bridge_state,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state,
- u32 output_fmt,
- unsigned int *num_input_fmts);
-
- /**
- * @atomic_check:
- *
- * This method is responsible for checking bridge state correctness.
- * It can also check the state of the surrounding components in chain
- * to make sure the whole pipeline can work properly.
- *
- * &drm_bridge_funcs.atomic_check() hooks are called in reverse
- * order (from the last to the first bridge).
- *
- * This method is optional. &drm_bridge_funcs.mode_fixup() is not
- * called when &drm_bridge_funcs.atomic_check() is implemented, so only
- * one of them should be provided.
- *
- * If drivers need to tweak &drm_bridge_state.input_bus_cfg.flags or
- * &drm_bridge_state.output_bus_cfg.flags it should should happen in
- * this function. By default the &drm_bridge_state.output_bus_cfg.flags
- * field is set to the next bridge
- * &drm_bridge_state.input_bus_cfg.flags value or
- * &drm_connector.display_info.bus_flags if the bridge is the last
- * element in the chain.
- *
- * RETURNS:
- * zero if the check passed, a negative error code otherwise.
- */
- int (*atomic_check)(struct drm_bridge *bridge,
- struct drm_bridge_state *bridge_state,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state);
-
- /**
- * @atomic_reset:
- *
- * Reset the bridge to a predefined state (or retrieve its current
- * state) and return a &drm_bridge_state object matching this state.
- * This function is called at attach time.
- *
- * The atomic_reset hook is optional. When not implemented the core
- * allocates a new state and calls &__drm_atomic_helper_bridge_reset().
- *
- * RETURNS:
- * A valid drm_bridge_state object in case of success, an ERR_PTR()
- * giving the reason of the failure otherwise.
- */
- struct drm_bridge_state *(*atomic_reset)(struct drm_bridge *bridge);
+ struct drm_atomic_state *old_state);
};
/**
@@ -582,8 +380,6 @@ struct drm_bridge_timings {
* struct drm_bridge - central DRM bridge control structure
*/
struct drm_bridge {
- /** @base: inherit from &drm_private_object */
- struct drm_private_obj base;
/** @dev: DRM device this bridge belongs to */
struct drm_device *dev;
/** @encoder: encoder to which this bridge is connected */
@@ -608,12 +404,6 @@ struct drm_bridge {
void *driver_private;
};
-static inline struct drm_bridge *
-drm_priv_to_bridge(struct drm_private_obj *priv)
-{
- return container_of(priv, struct drm_bridge, base);
-}
-
void drm_bridge_add(struct drm_bridge *bridge);
void drm_bridge_remove(struct drm_bridge *bridge);
struct drm_bridge *of_drm_find_bridge(struct device_node *np);
@@ -692,9 +482,6 @@ void drm_bridge_chain_mode_set(struct drm_bridge *bridge,
void drm_bridge_chain_pre_enable(struct drm_bridge *bridge);
void drm_bridge_chain_enable(struct drm_bridge *bridge);
-int drm_atomic_bridge_chain_check(struct drm_bridge *bridge,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state);
void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
struct drm_atomic_state *state);
void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
@@ -704,58 +491,6 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state);
-u32 *
-drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge,
- struct drm_bridge_state *bridge_state,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state,
- u32 output_fmt,
- unsigned int *num_input_fmts);
-
-void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge,
- struct drm_bridge_state *state);
-void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge,
- struct drm_bridge_state *new);
-
-static inline struct drm_bridge_state *
-drm_atomic_get_bridge_state(struct drm_atomic_state *state,
- struct drm_bridge *bridge)
-{
- struct drm_private_state *obj_state;
-
- obj_state = drm_atomic_get_private_obj_state(state, &bridge->base);
- if (IS_ERR(obj_state))
- return ERR_CAST(obj_state);
-
- return drm_priv_to_bridge_state(obj_state);
-}
-
-static inline struct drm_bridge_state *
-drm_atomic_get_old_bridge_state(struct drm_atomic_state *state,
- struct drm_bridge *bridge)
-{
- struct drm_private_state *obj_state;
-
- obj_state = drm_atomic_get_old_private_obj_state(state, &bridge->base);
- if (!obj_state)
- return NULL;
-
- return drm_priv_to_bridge_state(obj_state);
-}
-
-static inline struct drm_bridge_state *
-drm_atomic_get_new_bridge_state(struct drm_atomic_state *state,
- struct drm_bridge *bridge)
-{
- struct drm_private_state *obj_state;
-
- obj_state = drm_atomic_get_new_private_obj_state(state, &bridge->base);
- if (!obj_state)
- return NULL;
-
- return drm_priv_to_bridge_state(obj_state);
-}
-
#ifdef CONFIG_DRM_PANEL_BRIDGE
struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel);
struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel,
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 8f8f3632e697..bc04467f7c3a 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1465,6 +1465,7 @@ int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]);
void drm_dp_downstream_debug(struct seq_file *m, const u8 dpcd[DP_RECEIVER_CAP_SIZE],
const u8 port_cap[4], struct drm_dp_aux *aux);
+void drm_dp_remote_aux_init(struct drm_dp_aux *aux);
void drm_dp_aux_init(struct drm_dp_aux *aux);
int drm_dp_aux_register(struct drm_dp_aux *aux);
void drm_dp_aux_unregister(struct drm_dp_aux *aux);
@@ -1522,6 +1523,13 @@ enum drm_dp_quirk {
* The driver should ignore SINK_COUNT during detection.
*/
DP_DPCD_QUIRK_NO_SINK_COUNT,
+ /**
+ * @DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD:
+ *
+ * The device supports MST DSC despite not supporting Virtual DPCD.
+ * The DSC caps can be read from the physical aux instead.
+ */
+ DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD,
};
/**
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 5699493c6fb1..e5503771232f 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -156,6 +156,8 @@ struct drm_dp_mst_port {
* audio-capable.
*/
bool has_audio;
+
+ bool fec_capable;
};
/**
@@ -383,6 +385,7 @@ struct drm_dp_port_number_req {
struct drm_dp_enum_path_resources_ack_reply {
u8 port_number;
+ bool fec_capable;
u16 full_payload_bw_number;
u16 avail_payload_bw_number;
};
@@ -499,6 +502,8 @@ struct drm_dp_payload {
struct drm_dp_vcpi_allocation {
struct drm_dp_mst_port *port;
int vcpi;
+ int pbn;
+ bool dsc_enabled;
struct list_head next;
};
@@ -727,8 +732,7 @@ bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr,
struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
-int drm_dp_calc_pbn_mode(int clock, int bpp);
-
+int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc);
bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
struct drm_dp_mst_port *port, int pbn, int slots);
@@ -777,7 +781,15 @@ struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_a
int __must_check
drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
struct drm_dp_mst_topology_mgr *mgr,
- struct drm_dp_mst_port *port, int pbn);
+ struct drm_dp_mst_port *port, int pbn,
+ int pbn_div);
+int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
+ struct drm_dp_mst_port *port,
+ int pbn, int pbn_div,
+ bool enable);
+int __must_check
+drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state,
+ struct drm_dp_mst_topology_mgr *mgr);
int __must_check
drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
struct drm_dp_mst_topology_mgr *mgr,
@@ -789,6 +801,8 @@ int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port);
+struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port);
+
extern const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs;
/**
diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h
index 4becb09975a4..795aea1d0a25 100644
--- a/include/drm/drm_fb_cma_helper.h
+++ b/include/drm/drm_fb_cma_helper.h
@@ -2,6 +2,8 @@
#ifndef __DRM_FB_CMA_HELPER_H__
#define __DRM_FB_CMA_HELPER_H__
+#include <linux/types.h>
+
struct drm_framebuffer;
struct drm_plane_state;
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 684692a8ed76..96a1a1b7526e 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -81,8 +81,9 @@ enum drm_sched_priority {
struct drm_sched_entity {
struct list_head list;
struct drm_sched_rq *rq;
- struct drm_sched_rq **rq_list;
- unsigned int num_rq_list;
+ unsigned int num_sched_list;
+ struct drm_gpu_scheduler **sched_list;
+ enum drm_sched_priority priority;
spinlock_t rq_lock;
struct spsc_queue job_queue;
@@ -312,7 +313,8 @@ void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
struct drm_sched_entity *entity);
int drm_sched_entity_init(struct drm_sched_entity *entity,
- struct drm_sched_rq **rq_list,
+ enum drm_sched_priority priority,
+ struct drm_gpu_scheduler **sched_list,
unsigned int num_rq_list,
atomic_t *guilty);
long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
diff --git a/include/drm/task_barrier.h b/include/drm/task_barrier.h
new file mode 100644
index 000000000000..087e3f649c52
--- /dev/null
+++ b/include/drm/task_barrier.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <linux/semaphore.h>
+#include <linux/atomic.h>
+
+/*
+ * Reusable 2 PHASE task barrier (randevouz point) implementation for N tasks.
+ * Based on the Little book of sempahores - https://greenteapress.com/wp/semaphores/
+ */
+
+
+
+#ifndef DRM_TASK_BARRIER_H_
+#define DRM_TASK_BARRIER_H_
+
+/*
+ * Represents an instance of a task barrier.
+ */
+struct task_barrier {
+ unsigned int n;
+ atomic_t count;
+ struct semaphore enter_turnstile;
+ struct semaphore exit_turnstile;
+};
+
+static inline void task_barrier_signal_turnstile(struct semaphore *turnstile,
+ unsigned int n)
+{
+ int i;
+
+ for (i = 0 ; i < n; i++)
+ up(turnstile);
+}
+
+static inline void task_barrier_init(struct task_barrier *tb)
+{
+ tb->n = 0;
+ atomic_set(&tb->count, 0);
+ sema_init(&tb->enter_turnstile, 0);
+ sema_init(&tb->exit_turnstile, 0);
+}
+
+static inline void task_barrier_add_task(struct task_barrier *tb)
+{
+ tb->n++;
+}
+
+static inline void task_barrier_rem_task(struct task_barrier *tb)
+{
+ tb->n--;
+}
+
+/*
+ * Lines up all the threads BEFORE the critical point.
+ *
+ * When all thread passed this code the entry barrier is back to locked state.
+ */
+static inline void task_barrier_enter(struct task_barrier *tb)
+{
+ if (atomic_inc_return(&tb->count) == tb->n)
+ task_barrier_signal_turnstile(&tb->enter_turnstile, tb->n);
+
+ down(&tb->enter_turnstile);
+}
+
+/*
+ * Lines up all the threads AFTER the critical point.
+ *
+ * This function is used to avoid any one thread running ahead if the barrier is
+ * used repeatedly .
+ */
+static inline void task_barrier_exit(struct task_barrier *tb)
+{
+ if (atomic_dec_return(&tb->count) == 0)
+ task_barrier_signal_turnstile(&tb->exit_turnstile, tb->n);
+
+ down(&tb->exit_turnstile);
+}
+
+/* Convinieince function when nothing to be done in between entry and exit */
+static inline void task_barrier_full(struct task_barrier *tb)
+{
+ task_barrier_enter(tb);
+ task_barrier_exit(tb);
+}
+
+#endif