summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/dp/dp_link.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/dp/dp_link.c')
-rw-r--r--drivers/gpu/drm/msm/dp/dp_link.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c
index 66e1bbd80db3..2aeb3ecf76fa 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.c
+++ b/drivers/gpu/drm/msm/dp/dp_link.c
@@ -6,12 +6,14 @@
#define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
#include <drm/drm_device.h>
+#include <drm/drm_of.h>
#include <drm/drm_print.h>
#include "dp_reg.h"
#include "dp_link.h"
#include "dp_panel.h"
+#define DP_LINK_RATE_HBR2 540000 /* kbytes */
#define DP_TEST_REQUEST_MASK 0x7F
enum audio_sample_rate {
@@ -1210,10 +1212,61 @@ u32 msm_dp_link_get_test_bits_depth(struct msm_dp_link *msm_dp_link, u32 bpp)
return tbd;
}
+static u32 msm_dp_link_link_frequencies(struct device_node *of_node)
+{
+ struct device_node *endpoint;
+ u64 frequency = 0;
+ int cnt;
+
+ endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port@1 */
+ if (!endpoint)
+ return 0;
+
+ cnt = of_property_count_u64_elems(endpoint, "link-frequencies");
+
+ if (cnt > 0)
+ of_property_read_u64_index(endpoint, "link-frequencies",
+ cnt - 1, &frequency);
+ of_node_put(endpoint);
+
+ do_div(frequency,
+ 10 * /* from symbol rate to link rate */
+ 1000); /* kbytes */
+
+ return frequency;
+}
+
+static int msm_dp_link_parse_dt(struct device *dev, struct msm_dp_link *msm_dp_link)
+{
+ struct device_node *of_node = dev->of_node;
+ int cnt;
+
+ /*
+ * data-lanes is the property of msm_dp_out endpoint
+ */
+ cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
+ if (cnt < 0) {
+ /* legacy code, data-lanes is the property of mdss_dp node */
+ cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
+ }
+
+ if (cnt > 0)
+ msm_dp_link->max_dp_lanes = cnt;
+ else
+ msm_dp_link->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
+
+ msm_dp_link->max_dp_link_rate = msm_dp_link_link_frequencies(of_node);
+ if (!msm_dp_link->max_dp_link_rate)
+ msm_dp_link->max_dp_link_rate = DP_LINK_RATE_HBR2;
+
+ return 0;
+}
+
struct msm_dp_link *msm_dp_link_get(struct device *dev, struct drm_dp_aux *aux)
{
struct msm_dp_link_private *link;
struct msm_dp_link *msm_dp_link;
+ int ret;
if (!dev || !aux) {
DRM_ERROR("invalid input\n");
@@ -1229,5 +1282,9 @@ struct msm_dp_link *msm_dp_link_get(struct device *dev, struct drm_dp_aux *aux)
mutex_init(&link->psm_mutex);
msm_dp_link = &link->msm_dp_link;
+ ret = msm_dp_link_parse_dt(dev, msm_dp_link);
+ if (ret)
+ return ERR_PTR(ret);
+
return msm_dp_link;
}