summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-11-15 03:22:28 -0700
committerLinux Build Service Account <lnxbuild@localhost>2016-11-15 03:22:28 -0700
commit06f25a82e3cd17ed9eba423bda7c37a7ee618ca1 (patch)
treed67616ca5e112e3fb9673cf46697c4fe51e73aad
parent124459b203bf648a97d88f7d9977f6882d7a47ac (diff)
parent24d0c1f91eb2850889cb27ef6fdcadc0c8ff2834 (diff)
Promotion of kernel.lnx.4.4-161115.
CRs Change ID Subject -------------------------------------------------------------------------------------------------------------- 1087395 Ib43bdbc1ac51334bcd930657c99f7a0aa255255a clk: msm: mdss: fix potential use of un-initialized vari 1085169 1086278 I67e08d3491fbb7c0960c463cc8f979238b89d818 mdss: display-port: add support to configure stream attr 1062506 I36fd45efe1aa9437d5551002fc75a5f37d9cef79 msm: mdss: dp: handle fast attention events 1084634 I932a58fc633918b151959fcbe320668a87dbc49c msm: sde: add buf_finish callback to clear last fd 1085169 I391ee35fa20cfade89773ecb565b220cc6249b8d msm: mdss: hdcp2p2: check for valid keys before authenti 1085169 Ia69987c0e15ec5f15a07ca3a0e44174ab6e5feb9 msm: mdss: dp: select pin assignment D for multi-functio Change-Id: I9deaf7b62fdf15bd1d6862708ba755abdb51be74 CRs-Fixed: 1062506, 1085169, 1084634, 1087395, 1086278
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi3
-rw-r--r--drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c2
-rw-r--r--drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c18
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c34
-rw-r--r--drivers/misc/hdcp.c59
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c144
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h5
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c56
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.h11
10 files changed, 279 insertions, 55 deletions
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi
index 9c72ebf4a0bd..75c985189842 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-mdss.dtsi
@@ -468,9 +468,10 @@
reg = <0xc990000 0xa84>,
<0xc011000 0x910>,
<0x1fcb200 0x050>,
+ <0xc8c2200 0x1a0>,
<0x780000 0x621c>,
<0xc9e1000 0x02c>;
- reg-names = "dp_ctrl", "dp_phy", "tcsr_regs",
+ reg-names = "dp_ctrl", "dp_phy", "tcsr_regs", "dp_mmss_cc",
"qfprom_physical","hdcp_physical";
clocks = <&clock_mmss clk_mmss_mnoc_ahb_clk>,
diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
index a574a9cd2b5a..f23f32f7e37a 100644
--- a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
+++ b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
@@ -733,7 +733,7 @@ unsigned long dp_vco_get_rate(struct clk *c)
{
struct dp_pll_vco_clk *vco = mdss_dp_to_vco_clk(c);
int rc;
- u32 div, hsclk_div, link2xclk_div;
+ u32 div, hsclk_div, link2xclk_div = 0;
u64 vco_rate;
struct mdss_pll_resources *pll = vco->priv;
diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c b/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c
index 4b2d8bba0940..299934c86d05 100644
--- a/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c
+++ b/drivers/clk/msm/mdss/mdss-dsi-pll-cobalt.c
@@ -205,18 +205,34 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_cobalt *pll,
struct dsi_pll_regs *regs = &pll->reg_setup;
u64 target_freq;
u64 fref = rsc->vco_ref_clk_rate;
- u32 computed_output_div, div_log;
+ u32 computed_output_div, div_log = 0;
u64 pll_freq;
u64 divider;
u64 dec, dec_multiple;
u32 frac;
u64 multiplier;
+ u32 i;
target_freq = rsc->vco_current_rate;
pr_debug("target_freq = %llu\n", target_freq);
if (config->div_override) {
computed_output_div = config->output_div;
+
+ /*
+ * Computed_output_div = 2 ^ div_log
+ * To get div_log from output div just get the index of the
+ * 1 bit in the value.
+ * div_log ranges from 0-3. so check the 4 lsbs
+ */
+
+ for (i = 0; i < 4; i++) {
+ if (computed_output_div & (1 << i)) {
+ div_log = i;
+ break;
+ }
+ }
+
} else {
if (target_freq < MHZ_375) {
computed_output_div = 8;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
index b88f03ce89ae..08075ae90507 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
@@ -305,6 +305,39 @@ static void sde_rotator_buf_queue(struct vb2_buffer *vb)
}
/*
+ * sde_rotator_buf_finish - vb2_ops buf_finish to finalize buffer before going
+ * back to user space
+ * @vb: Pointer to vb2 buffer struct.
+ */
+static void sde_rotator_buf_finish(struct vb2_buffer *vb)
+{
+ struct sde_rotator_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ int i;
+
+ SDEDEV_DBG(ctx->rot_dev->dev,
+ "buf_finish t:%d i:%d s:%d m:%u np:%d up:%lu\n",
+ vb->type, vb->index, vb->state,
+ vb->vb2_queue->memory,
+ vb->num_planes,
+ vb->planes[0].m.userptr);
+
+ if (vb->vb2_queue->memory != VB2_MEMORY_USERPTR)
+ return;
+
+ /*
+ * We use userptr to tunnel fd, and fd can be the same across qbuf
+ * even though the underlying buffer is different. Since vb2 layer
+ * optimizes memory mapping for userptr by first checking if userptr
+ * has changed, it will not trigger put_userptr if fd value does
+ * not change. In order to force buffer release, we need to clear
+ * userptr when the current buffer is done and ready to go back to
+ * user mode. Since 0 is a valid fd, reset userptr to -1 instead.
+ */
+ for (i = 0; i < vb->num_planes; i++)
+ vb->planes[i].m.userptr = ~0;
+}
+
+/*
* sde_rotator_return_all_buffers - Return all buffers with the given status.
* @q: Pointer to vb2 buffer queue struct.
* @state: State of the buffer
@@ -460,6 +493,7 @@ static struct vb2_ops sde_rotator_vb2_q_ops = {
.stop_streaming = sde_rotator_stop_streaming,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
+ .buf_finish = sde_rotator_buf_finish,
};
/*
diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c
index 69ec7127102c..56ddf8467d16 100644
--- a/drivers/misc/hdcp.c
+++ b/drivers/misc/hdcp.c
@@ -255,6 +255,15 @@ struct __attribute__ ((__packed__)) hdcp_version_rsp {
uint32_t appversion;
};
+struct __attribute__ ((__packed__)) hdcp_verify_key_req {
+ uint32_t commandid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_verify_key_rsp {
+ uint32_t status;
+ uint32_t commandId;
+};
+
struct __attribute__ ((__packed__)) hdcp_lib_init_req_v1 {
uint32_t commandid;
};
@@ -794,6 +803,48 @@ exit:
return rc;
}
+static int hdcp_lib_verify_keys(struct hdcp_lib_handle *handle)
+{
+ int rc = -EINVAL;
+ struct hdcp_verify_key_req *req_buf;
+ struct hdcp_verify_key_rsp *rsp_buf;
+
+ if (!handle) {
+ pr_err("invalid input\n");
+ goto exit;
+ }
+
+ if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+ pr_err("app not loaded\n");
+ goto exit;
+ }
+
+ req_buf = (struct hdcp_verify_key_req *)handle->qseecom_handle->sbuf;
+ req_buf->commandid = HDCP_TXMTR_VERIFY_KEY;
+
+ rsp_buf = (struct hdcp_verify_key_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_verify_key_req)));
+
+ rc = qseecom_send_command(handle->qseecom_handle,
+ req_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_verify_key_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_verify_key_rsp)));
+
+ if (rc < 0) {
+ pr_err("qseecom cmd failed err = %d\n", rc);
+ goto exit;
+ }
+
+ return rsp_buf->status;
+exit:
+ return rc;
+}
+
+
static int hdcp_app_init_legacy(struct hdcp_lib_handle *handle)
{
int rc = 0;
@@ -1456,10 +1507,12 @@ static bool hdcp_lib_client_feature_supported(void *phdcpcontext)
rc = hdcp_lib_library_load(handle);
if (!rc) {
- pr_debug("HDCP2p2 supported\n");
- handle->feature_supported = true;
+ if (!hdcp_lib_verify_keys(handle)) {
+ pr_debug("HDCP2p2 supported\n");
+ handle->feature_supported = true;
+ supported = true;
+ }
hdcp_lib_library_unload(handle);
- supported = true;
}
exit:
return supported;
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index 75e42ca8cd88..29fc4e6fd65b 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -45,6 +45,11 @@
#define VDDA_UA_ON_LOAD 100000 /* uA units */
#define VDDA_UA_OFF_LOAD 100 /* uA units */
+struct mdss_dp_attention_node {
+ u32 vdo;
+ struct list_head list;
+};
+
#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_640x480p60_4_3
static u32 supported_modes[] = {
HDMI_VFRMT_640x480p60_4_3,
@@ -60,6 +65,7 @@ static u32 supported_modes[] = {
static int mdss_dp_off_irq(struct mdss_dp_drv_pdata *dp_drv);
static void mdss_dp_mainlink_push_idle(struct mdss_panel_data *pdata);
static inline void mdss_dp_link_retraining(struct mdss_dp_drv_pdata *dp);
+static void mdss_dp_handle_attention(struct mdss_dp_drv_pdata *dp_drv);
static void mdss_dp_put_dt_clk_data(struct device *dev,
struct dss_module_power *module_power)
@@ -1133,7 +1139,7 @@ static void mdss_dp_configure_source_params(struct mdss_dp_drv_pdata *dp,
mdss_dp_fill_link_cfg(dp);
mdss_dp_mainlink_ctrl(&dp->ctrl_io, true);
mdss_dp_config_ctrl(dp);
- mdss_dp_sw_mvid_nvid(&dp->ctrl_io);
+ mdss_dp_sw_config_msa(&dp->ctrl_io, dp->link_rate, &dp->dp_cc_io);
mdss_dp_timing_cfg(&dp->ctrl_io, &dp->panel_data.panel_info);
}
@@ -1290,7 +1296,6 @@ link_training:
dp_drv->cont_splash = 0;
dp_drv->power_on = true;
- mdss_dp_ack_state(dp_drv, true);
pr_debug("End-\n");
exit:
@@ -1559,6 +1564,7 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
goto edid_error;
}
+ mdss_dp_update_cable_status(dp_drv, true);
mdss_dp_notify_clients(dp_drv, true);
dp_drv->dp_initialized = true;
@@ -1883,8 +1889,13 @@ static void mdss_dp_update_hdcp_info(struct mdss_dp_drv_pdata *dp)
}
/* update internal data about hdcp */
- dp->hdcp.data = fd;
- dp->hdcp.ops = ops;
+ if (dp->hdcp.hdcp2_present || dp->hdcp.hdcp1_present) {
+ dp->hdcp.data = fd;
+ dp->hdcp.ops = ops;
+ } else {
+ dp->hdcp.data = NULL;
+ dp->hdcp.ops = NULL;
+ }
}
static inline bool dp_is_hdcp_enabled(struct mdss_dp_drv_pdata *dp_drv)
@@ -1920,6 +1931,8 @@ static int mdss_dp_event_handler(struct mdss_panel_data *pdata,
if (dp->hdcp.ops && dp->hdcp.ops->authenticate)
rc = dp->hdcp.ops->authenticate(dp->hdcp.data);
+
+ mdss_dp_ack_state(dp, true);
break;
case MDSS_EVENT_PANEL_OFF:
rc = mdss_dp_off(pdata);
@@ -2041,6 +2054,12 @@ static int mdss_retrieve_dp_ctrl_resources(struct platform_device *pdev,
return rc;
}
+ if (msm_dss_ioremap_byname(pdev, &dp_drv->dp_cc_io, "dp_mmss_cc")) {
+ pr_err("%d unable to remap dp MMSS_CC resources\n",
+ __LINE__);
+ return rc;
+ }
+
if (msm_dss_ioremap_byname(pdev, &dp_drv->qfprom_io,
"qfprom_physical"))
pr_warn("unable to remap dp qfprom resources\n");
@@ -2117,6 +2136,9 @@ static void mdss_dp_event_work(struct work_struct *work)
case EV_IDLE_PATTERNS_SENT:
mdss_dp_idle_patterns_sent(dp);
break;
+ case EV_USBPD_ATTENTION:
+ mdss_dp_handle_attention(dp);
+ break;
case EV_USBPD_DISCOVER_MODES:
usbpd_send_svdm(dp->pd, USB_C_DP_SID, USBPD_SVDM_DISCOVER_MODES,
SVDM_CMD_TYPE_INITIATOR, 0x0, 0x0, 0x0);
@@ -2225,6 +2247,7 @@ static int mdss_dp_event_setup(struct mdss_dp_drv_pdata *dp)
INIT_WORK(&dp->work, mdss_dp_event_work);
INIT_DELAYED_WORK(&dp->hdcp_cb_work, mdss_dp_hdcp_cb_work);
+ INIT_LIST_HEAD(&dp->attention_head);
return 0;
}
@@ -2508,6 +2531,7 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
const u32 *vdos, int num_vdos)
{
struct mdss_dp_drv_pdata *dp_drv;
+ struct mdss_dp_attention_node *node;
dp_drv = container_of(hdlr, struct mdss_dp_drv_pdata, svid_handler);
if (!dp_drv->pd) {
@@ -2535,45 +2559,14 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
dp_send_events(dp_drv, EV_USBPD_DP_STATUS);
break;
case USBPD_SVDM_ATTENTION:
- dp_drv->alt_mode.dp_status.response = *vdos;
- mdss_dp_usbpd_ext_dp_status(&dp_drv->alt_mode.dp_status);
-
- dp_drv->hpd_irq_toggled = dp_drv->hpd_irq_on !=
- dp_drv->alt_mode.dp_status.hpd_irq;
+ node = kzalloc(sizeof(*node), GFP_KERNEL);
+ node->vdo = *vdos;
- if (dp_drv->alt_mode.dp_status.hpd_irq) {
- pr_debug("Attention: hpd_irq high\n");
-
- if (dp_drv->power_on && dp_drv->hdcp.ops &&
- dp_drv->hdcp.ops->cp_irq)
- dp_drv->hdcp.ops->cp_irq(dp_drv->hdcp.data);
-
- if (!mdss_dp_process_hpd_irq_high(dp_drv))
- break;
- } else if (dp_drv->hpd_irq_toggled) {
- if (!mdss_dp_process_hpd_irq_low(dp_drv))
- break;
- }
-
- if (!dp_drv->alt_mode.dp_status.hpd_high) {
- pr_debug("Attention: HPD low\n");
- mdss_dp_update_cable_status(dp_drv, false);
- mdss_dp_notify_clients(dp_drv, false);
- pr_debug("Attention: Notified clients\n");
- break;
- }
-
- pr_debug("Attention: HPD high\n");
-
- mdss_dp_update_cable_status(dp_drv, true);
-
- dp_drv->alt_mode.current_state |= DP_STATUS_DONE;
-
- if (dp_drv->alt_mode.current_state & DP_CONFIGURE_DONE)
- mdss_dp_host_init(&dp_drv->panel_data);
- else
- dp_send_events(dp_drv, EV_USBPD_DP_CONFIGURE);
+ mutex_lock(&dp_drv->attention_lock);
+ list_add_tail(&node->list, &dp_drv->attention_head);
+ mutex_unlock(&dp_drv->attention_lock);
+ dp_send_events(dp_drv, EV_USBPD_ATTENTION);
break;
case DP_VDM_STATUS:
dp_drv->alt_mode.dp_status.response = *vdos;
@@ -2597,6 +2590,74 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
}
}
+static void mdss_dp_process_attention(struct mdss_dp_drv_pdata *dp_drv)
+{
+ dp_drv->hpd_irq_toggled = dp_drv->hpd_irq_on !=
+ dp_drv->alt_mode.dp_status.hpd_irq;
+
+ if (dp_drv->alt_mode.dp_status.hpd_irq) {
+ pr_debug("Attention: hpd_irq high\n");
+
+ if (dp_drv->power_on && dp_drv->hdcp.ops &&
+ dp_drv->hdcp.ops->cp_irq)
+ dp_drv->hdcp.ops->cp_irq(dp_drv->hdcp.data);
+
+ if (!mdss_dp_process_hpd_irq_high(dp_drv))
+ return;
+ } else if (dp_drv->hpd_irq_toggled) {
+ if (!mdss_dp_process_hpd_irq_low(dp_drv))
+ return;
+ }
+
+ if (!dp_drv->alt_mode.dp_status.hpd_high) {
+ pr_debug("Attention: HPD low\n");
+ mdss_dp_update_cable_status(dp_drv, false);
+ mdss_dp_notify_clients(dp_drv, false);
+ pr_debug("Attention: Notified clients\n");
+ return;
+ }
+
+ pr_debug("Attention: HPD high\n");
+
+ mdss_dp_update_cable_status(dp_drv, true);
+
+ dp_drv->alt_mode.current_state |= DP_STATUS_DONE;
+
+ if (dp_drv->alt_mode.current_state & DP_CONFIGURE_DONE)
+ mdss_dp_host_init(&dp_drv->panel_data);
+ else
+ dp_send_events(dp_drv, EV_USBPD_DP_CONFIGURE);
+
+ pr_debug("exit\n");
+}
+
+static void mdss_dp_handle_attention(struct mdss_dp_drv_pdata *dp)
+{
+ int i = 0;
+
+ while (!list_empty_careful(&dp->attention_head)) {
+ struct mdss_dp_attention_node *node;
+ u32 vdo;
+
+ pr_debug("processing item %d in the list\n", ++i);
+
+ mutex_lock(&dp->attention_lock);
+ node = list_first_entry(&dp->attention_head,
+ struct mdss_dp_attention_node, list);
+
+ vdo = node->vdo;
+ list_del(&node->list);
+ mutex_unlock(&dp->attention_lock);
+
+ kzfree(node);
+
+ dp->alt_mode.dp_status.response = vdo;
+ mdss_dp_usbpd_ext_dp_status(&dp->alt_mode.dp_status);
+ mdss_dp_process_attention(dp);
+ };
+
+}
+
static int mdss_dp_usbpd_setup(struct mdss_dp_drv_pdata *dp_drv)
{
int ret = 0;
@@ -2670,6 +2731,7 @@ static int mdss_dp_probe(struct platform_device *pdev)
dp_drv->mask2 = EDP_INTR_MASK2;
mutex_init(&dp_drv->emutex);
mutex_init(&dp_drv->pd_msg_mutex);
+ mutex_init(&dp_drv->attention_lock);
mutex_init(&dp_drv->hdcp_mutex);
spin_lock_init(&dp_drv->lock);
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index e801eceeef1b..04abe9221acc 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -205,6 +205,7 @@ struct dp_alt_mode {
#define EV_USBPD_DP_CONFIGURE BIT(10)
#define EV_USBPD_CC_PIN_POLARITY BIT(11)
#define EV_USBPD_EXIT_MODE BIT(12)
+#define EV_USBPD_ATTENTION BIT(13)
/* dp state ctrl */
#define ST_TRAIN_PATTERN_1 BIT(0)
@@ -406,6 +407,7 @@ struct mdss_dp_drv_pdata {
struct dss_io_data ctrl_io;
struct dss_io_data phy_io;
struct dss_io_data tcsr_reg_io;
+ struct dss_io_data dp_cc_io;
struct dss_io_data qfprom_io;
struct dss_io_data hdcp_io;
int base_size;
@@ -454,6 +456,7 @@ struct mdss_dp_drv_pdata {
struct mutex aux_mutex;
struct mutex train_mutex;
struct mutex pd_msg_mutex;
+ struct mutex attention_lock;
struct mutex hdcp_mutex;
bool cable_connected;
u32 s3d_mode;
@@ -497,6 +500,8 @@ struct mdss_dp_drv_pdata {
struct dpcd_test_request test_data;
struct dpcd_sink_count sink_count;
+
+ struct list_head attention_head;
};
enum dp_lane_count {
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index f9dba99a653d..e396dfff60ef 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -1647,6 +1647,8 @@ int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp)
clear:
dp_clear_training_pattern(dp);
if (ret != -EINVAL) {
+ mdss_dp_config_misc_settings(&dp->ctrl_io,
+ &dp->panel_data.panel_info);
mdss_dp_setup_tr_unit(&dp->ctrl_io, dp->link_rate,
dp->lane_cnt, dp->vic);
mdss_dp_state_ctrl(&dp->ctrl_io, ST_SEND_VIDEO);
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c
index 2d24d8499105..86edc4492599 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.c
+++ b/drivers/video/fbdev/msm/mdss_dp_util.c
@@ -253,10 +253,48 @@ void mdss_dp_timing_cfg(struct dss_io_data *ctrl_io,
writel_relaxed(data, ctrl_io->base + DP_ACTIVE_HOR_VER);
}
-void mdss_dp_sw_mvid_nvid(struct dss_io_data *ctrl_io)
+void mdss_dp_sw_config_msa(struct dss_io_data *ctrl_io,
+ char lrate, struct dss_io_data *dp_cc_io)
{
- writel_relaxed(0x37, ctrl_io->base + DP_SOFTWARE_MVID);
- writel_relaxed(0x3c, ctrl_io->base + DP_SOFTWARE_NVID);
+ u32 pixel_m, pixel_n;
+ u32 mvid, nvid;
+
+ pixel_m = readl_relaxed(dp_cc_io->base + MMSS_DP_PIXEL_M);
+ pixel_n = readl_relaxed(dp_cc_io->base + MMSS_DP_PIXEL_N);
+ pr_debug("pixel_m=0x%x, pixel_n=0x%x\n",
+ pixel_m, pixel_n);
+
+ mvid = (pixel_m & 0xFFFF) * 5;
+ nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
+ if (lrate == DP_LINK_RATE_540)
+ nvid = nvid * 2;
+ pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid);
+ writel_relaxed(mvid, ctrl_io->base + DP_SOFTWARE_MVID);
+ writel_relaxed(nvid, ctrl_io->base + DP_SOFTWARE_NVID);
+}
+
+void mdss_dp_config_misc_settings(struct dss_io_data *ctrl_io,
+ struct mdss_panel_info *pinfo)
+{
+ u32 bpp = pinfo->bpp;
+ u32 misc_val = 0x0;
+
+ switch (bpp) {
+ case 18:
+ misc_val |= (0x0 << 5);
+ break;
+ case 30:
+ misc_val |= (0x2 << 5);
+ break;
+ case 24:
+ default:
+ misc_val |= (0x1 << 5);
+ }
+
+ misc_val |= BIT(0); /* Configure clock to synchronous mode */
+
+ pr_debug("Misc settings = 0x%x\n", misc_val);
+ writel_relaxed(misc_val, ctrl_io->base + DP_MISC1_MISC0);
}
void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate,
@@ -267,8 +305,6 @@ void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate,
u32 valid_boundary2 = 0x0;
struct dp_vc_tu_mapping_table const *tu_entry = tu_table;
- writel_relaxed(0x21, ctrl_io->base + DP_MISC1_MISC0);
-
for (; tu_entry != tu_table + ARRAY_SIZE(tu_table); ++tu_entry) {
if ((tu_entry->vic == res) &&
(tu_entry->lanes == ln_cnt) &&
@@ -454,8 +490,14 @@ u32 mdss_dp_usbpd_gen_config_pkt(struct mdss_dp_drv_pdata *dp)
pin_cfg = dp->alt_mode.dp_cap.dlink_pin_config;
for (pin = PIN_ASSIGNMENT_A; pin < PIN_ASSIGNMENT_MAX; pin++) {
- if (pin_cfg & BIT(pin))
- break;
+ if (pin_cfg & BIT(pin)) {
+ if (dp->alt_mode.dp_status.multi_func) {
+ if (pin == PIN_ASSIGNMENT_D)
+ break;
+ } else {
+ break;
+ }
+ }
}
if (pin == PIN_ASSIGNMENT_MAX)
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h
index 334c0071050d..4b28d98177be 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.h
+++ b/drivers/video/fbdev/msm/mdss_dp_util.h
@@ -164,6 +164,12 @@
#define TCSR_USB3_DP_PHYMODE 0x48
#define EDID_START_ADDRESS 0x50
+/* DP MMSS_CC registers */
+#define MMSS_DP_LINK_CMD_RCGR 0x0000
+#define MMSS_DP_LINK_CFG_RCGR 0x0004
+#define MMSS_DP_PIXEL_M 0x0048
+#define MMSS_DP_PIXEL_N 0x004C
+
/* DP HDCP 1.3 registers */
#define DP_HDCP_CTRL (0x0A0)
#define DP_HDCP_STATUS (0x0A4)
@@ -271,6 +277,8 @@ void mdss_dp_switch_usb3_phy_to_dp_mode(struct dss_io_data *tcsr_reg_io);
void mdss_dp_assert_phy_reset(struct dss_io_data *ctrl_io, bool assert);
void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate,
u8 ln_cnt, u32 res);
+void mdss_dp_config_misc_settings(struct dss_io_data *ctrl_io,
+ struct mdss_panel_info *pinfo);
void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io);
void mdss_dp_hpd_configure(struct dss_io_data *ctrl_io, bool enable);
void mdss_dp_aux_ctrl(struct dss_io_data *ctrl_io, bool enable);
@@ -285,7 +293,8 @@ void mdss_dp_state_ctrl(struct dss_io_data *ctrl_io, u32 data);
int mdss_dp_irq_setup(struct mdss_dp_drv_pdata *dp_drv);
void mdss_dp_irq_enable(struct mdss_dp_drv_pdata *dp_drv);
void mdss_dp_irq_disable(struct mdss_dp_drv_pdata *dp_drv);
-void mdss_dp_sw_mvid_nvid(struct dss_io_data *ctrl_io);
+void mdss_dp_sw_config_msa(struct dss_io_data *ctrl_io,
+ char lrate, struct dss_io_data *dp_cc_io);
void mdss_dp_usbpd_ext_capabilities(struct usbpd_dp_capabilities *dp_cap);
void mdss_dp_usbpd_ext_dp_status(struct usbpd_dp_status *dp_status);
u32 mdss_dp_usbpd_gen_config_pkt(struct mdss_dp_drv_pdata *dp);