Commit 6739b3d7 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-fixes-mst' of git://people.freedesktop.org/~airlied/linux into drm-fixes

displayport multistream fixes from AMD.

* 'drm-fixes-mst' of git://people.freedesktop.org/~airlied/linux:
  drm/dp/mst: deallocate payload on port destruction
  drm/dp/mst: Reverse order of MST enable and clearing VC payload table.
  drm/dp/mst: move GUID storage from mgr, port to only mst branch
  drm/dp/mst: change MST detection scheme
  drm/dp/mst: Calculate MST PBN with 31.32 fixed point
  drm: Add drm_fixp_from_fraction and drm_fixp2int_ceil
  drm/mst: Add range check for max_payloads during init
  drm/mst: Don't ignore the MST PBN self-test result
  drm: fix missing reference counting decrease
parents c745884b 91a25e46
This diff is collapsed.
...@@ -44,8 +44,6 @@ struct drm_dp_vcpi { ...@@ -44,8 +44,6 @@ struct drm_dp_vcpi {
/** /**
* struct drm_dp_mst_port - MST port * struct drm_dp_mst_port - MST port
* @kref: reference count for this port. * @kref: reference count for this port.
* @guid_valid: for DP 1.2 devices if we have validated the GUID.
* @guid: guid for DP 1.2 device on this port.
* @port_num: port number * @port_num: port number
* @input: if this port is an input port. * @input: if this port is an input port.
* @mcs: message capability status - DP 1.2 spec. * @mcs: message capability status - DP 1.2 spec.
...@@ -70,10 +68,6 @@ struct drm_dp_vcpi { ...@@ -70,10 +68,6 @@ struct drm_dp_vcpi {
struct drm_dp_mst_port { struct drm_dp_mst_port {
struct kref kref; struct kref kref;
/* if dpcd 1.2 device is on this port - its GUID info */
bool guid_valid;
u8 guid[16];
u8 port_num; u8 port_num;
bool input; bool input;
bool mcs; bool mcs;
...@@ -110,10 +104,12 @@ struct drm_dp_mst_port { ...@@ -110,10 +104,12 @@ struct drm_dp_mst_port {
* @tx_slots: transmission slots for this device. * @tx_slots: transmission slots for this device.
* @last_seqno: last sequence number used to talk to this. * @last_seqno: last sequence number used to talk to this.
* @link_address_sent: if a link address message has been sent to this device yet. * @link_address_sent: if a link address message has been sent to this device yet.
* @guid: guid for DP 1.2 branch device. port under this branch can be
* identified by port #.
* *
* This structure represents an MST branch device, there is one * This structure represents an MST branch device, there is one
* primary branch device at the root, along with any others connected * primary branch device at the root, along with any other branches connected
* to downstream ports * to downstream port of parent branches.
*/ */
struct drm_dp_mst_branch { struct drm_dp_mst_branch {
struct kref kref; struct kref kref;
...@@ -132,6 +128,9 @@ struct drm_dp_mst_branch { ...@@ -132,6 +128,9 @@ struct drm_dp_mst_branch {
struct drm_dp_sideband_msg_tx *tx_slots[2]; struct drm_dp_sideband_msg_tx *tx_slots[2];
int last_seqno; int last_seqno;
bool link_address_sent; bool link_address_sent;
/* global unique identifier to identify branch devices */
u8 guid[16];
}; };
...@@ -406,11 +405,9 @@ struct drm_dp_payload { ...@@ -406,11 +405,9 @@ struct drm_dp_payload {
* @conn_base_id: DRM connector ID this mgr is connected to. * @conn_base_id: DRM connector ID this mgr is connected to.
* @down_rep_recv: msg receiver state for down replies. * @down_rep_recv: msg receiver state for down replies.
* @up_req_recv: msg receiver state for up requests. * @up_req_recv: msg receiver state for up requests.
* @lock: protects mst state, primary, guid, dpcd. * @lock: protects mst state, primary, dpcd.
* @mst_state: if this manager is enabled for an MST capable port. * @mst_state: if this manager is enabled for an MST capable port.
* @mst_primary: pointer to the primary branch device. * @mst_primary: pointer to the primary branch device.
* @guid_valid: GUID valid for the primary branch device.
* @guid: GUID for primary port.
* @dpcd: cache of DPCD for primary port. * @dpcd: cache of DPCD for primary port.
* @pbn_div: PBN to slots divisor. * @pbn_div: PBN to slots divisor.
* *
...@@ -432,13 +429,11 @@ struct drm_dp_mst_topology_mgr { ...@@ -432,13 +429,11 @@ struct drm_dp_mst_topology_mgr {
struct drm_dp_sideband_msg_rx up_req_recv; struct drm_dp_sideband_msg_rx up_req_recv;
/* pointer to info about the initial MST device */ /* pointer to info about the initial MST device */
struct mutex lock; /* protects mst_state + primary + guid + dpcd */ struct mutex lock; /* protects mst_state + primary + dpcd */
bool mst_state; bool mst_state;
struct drm_dp_mst_branch *mst_primary; struct drm_dp_mst_branch *mst_primary;
/* primary MST device GUID */
bool guid_valid;
u8 guid[16];
u8 dpcd[DP_RECEIVER_CAP_SIZE]; u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 sink_count; u8 sink_count;
int pbn_div; int pbn_div;
......
...@@ -73,18 +73,28 @@ static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B) ...@@ -73,18 +73,28 @@ static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B)
#define DRM_FIXED_ONE (1ULL << DRM_FIXED_POINT) #define DRM_FIXED_ONE (1ULL << DRM_FIXED_POINT)
#define DRM_FIXED_DECIMAL_MASK (DRM_FIXED_ONE - 1) #define DRM_FIXED_DECIMAL_MASK (DRM_FIXED_ONE - 1)
#define DRM_FIXED_DIGITS_MASK (~DRM_FIXED_DECIMAL_MASK) #define DRM_FIXED_DIGITS_MASK (~DRM_FIXED_DECIMAL_MASK)
#define DRM_FIXED_EPSILON 1LL
#define DRM_FIXED_ALMOST_ONE (DRM_FIXED_ONE - DRM_FIXED_EPSILON)
static inline s64 drm_int2fixp(int a) static inline s64 drm_int2fixp(int a)
{ {
return ((s64)a) << DRM_FIXED_POINT; return ((s64)a) << DRM_FIXED_POINT;
} }
static inline int drm_fixp2int(int64_t a) static inline int drm_fixp2int(s64 a)
{ {
return ((s64)a) >> DRM_FIXED_POINT; return ((s64)a) >> DRM_FIXED_POINT;
} }
static inline unsigned drm_fixp_msbset(int64_t a) static inline int drm_fixp2int_ceil(s64 a)
{
if (a > 0)
return drm_fixp2int(a + DRM_FIXED_ALMOST_ONE);
else
return drm_fixp2int(a - DRM_FIXED_ALMOST_ONE);
}
static inline unsigned drm_fixp_msbset(s64 a)
{ {
unsigned shift, sign = (a >> 63) & 1; unsigned shift, sign = (a >> 63) & 1;
...@@ -136,6 +146,45 @@ static inline s64 drm_fixp_div(s64 a, s64 b) ...@@ -136,6 +146,45 @@ static inline s64 drm_fixp_div(s64 a, s64 b)
return result; return result;
} }
static inline s64 drm_fixp_from_fraction(s64 a, s64 b)
{
s64 res;
bool a_neg = a < 0;
bool b_neg = b < 0;
u64 a_abs = a_neg ? -a : a;
u64 b_abs = b_neg ? -b : b;
u64 rem;
/* determine integer part */
u64 res_abs = div64_u64_rem(a_abs, b_abs, &rem);
/* determine fractional part */
{
u32 i = DRM_FIXED_POINT;
do {
rem <<= 1;
res_abs <<= 1;
if (rem >= b_abs) {
res_abs |= 1;
rem -= b_abs;
}
} while (--i != 0);
}
/* round up LSB */
{
u64 summand = (rem << 1) >= b_abs;
res_abs += summand;
}
res = (s64) res_abs;
if (a_neg ^ b_neg)
res = -res;
return res;
}
static inline s64 drm_fixp_exp(s64 x) static inline s64 drm_fixp_exp(s64 x)
{ {
s64 tolerance = div64_s64(DRM_FIXED_ONE, 1000000); s64 tolerance = div64_s64(DRM_FIXED_ONE, 1000000);
......
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