summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-dp.txt7
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-mdss.dtsi7
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_base.c15
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_base.h2
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_core.c6
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c4
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c2
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c13
-rw-r--r--drivers/video/fbdev/msm/mdp3_ctrl.c8
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c133
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h26
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c45
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.h17
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c1
14 files changed, 217 insertions, 69 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-dp.txt b/Documentation/devicetree/bindings/fb/mdss-dp.txt
index 27516d3b54a5..7bf7b9bacb60 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dp.txt
@@ -27,6 +27,7 @@ Required properties
- qcom,aux-en-gpio: Specifies the aux-channel enable gpio.
- qcom,aux-sel-gpio: Specifies the aux-channel select gpio.
- qcom,usbplug-cc-gpio: Specifies the usbplug orientation gpio.
+- qcom,aux-cfg-settings: An array that specifies the DP AUX configuration settings.
Optional properties:
- qcom,<type>-supply-entries: A node that lists the elements of the supply used by the
@@ -51,6 +52,8 @@ Optional properties:
- pinctrl-<0..n>: Lists phandles each pointing to the pin configuration node within a pin
controller. These pin configurations are installed in the pinctrl
device node. Refer to pinctrl-bindings.txt
+- qcom,logical2physical-lane-map: An array that specifies the DP logical to physical lane map setting.
+- qcom,phy-register-offset: An integer specifying the offset value of DP PHY register space.
Example:
mdss_dp_ctrl: qcom,dp_ctrl@c990000 {
@@ -83,6 +86,10 @@ Example:
"core_aux_clk", "core_cfg_ahb_clk", "ctrl_link_clk",
"ctrl_link_iface_clk", "ctrl_crypto_clk", "ctrl_pixel_clk";
+ qcom,aux-cfg-settings = [00 13 00 10 0a 26 0a 03 8b 03];
+ qcom,logical2physical-lane-map = [02 03 01 00];
+ qcom,phy-register-offset = <0x4>;
+
qcom,core-supply-entries {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi b/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi
index 845c96eb5ef4..3f13cdc34892 100644
--- a/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -126,7 +126,7 @@
<0x012ac 0xc0000ccc>,
<0x012b4 0xc0000ccc>,
<0x012bc 0x00cccccc>,
- <0x012c4 0x000000cc>,
+ <0x012c4 0x0000cccc>,
<0x013a8 0x0cccc0c0>,
<0x013b0 0xccccc0c0>,
<0x013b8 0xcccc0000>,
@@ -500,6 +500,9 @@
qcom,msm_ext_disp = <&msm_ext_disp>;
+ qcom,aux-cfg-settings = [00 13 00 10 0a 26 0a 03 8b 03];
+ qcom,logical2physical-lane-map = [02 03 01 00];
+
qcom,core-supply-entries {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
index 9048d54bed38..1f92186feeef 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
@@ -30,6 +30,7 @@
#include "sde_rotator_base.h"
#include "sde_rotator_util.h"
#include "sde_rotator_trace.h"
+#include "sde_rotator_debug.h"
static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
{
@@ -237,6 +238,8 @@ static u32 get_ot_limit(u32 reg_off, u32 bit_off,
exit:
SDEROT_DBG("ot_lim=%d\n", ot_lim);
+ SDEROT_EVTLOG(params->width, params->height, params->fmt, params->fps,
+ ot_lim);
return ot_lim;
}
@@ -248,6 +251,7 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
params->reg_off_vbif_lim_conf;
u32 bit_off_vbif_lim_conf = (params->xin_id % 4) * 8;
u32 reg_val;
+ u32 sts;
bool forced_on;
ot_lim = get_ot_limit(
@@ -258,6 +262,16 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
if (ot_lim == 0)
goto exit;
+ if (params->rotsts_base && params->rotsts_busy_mask) {
+ sts = readl_relaxed(params->rotsts_base);
+ if (sts & params->rotsts_busy_mask) {
+ SDEROT_ERR(
+ "Rotator still busy, should not modify VBIF\n");
+ SDEROT_EVTLOG_TOUT_HANDLER(
+ "rot", "vbif_dbg_bus", "panic");
+ }
+ }
+
trace_rot_perf_set_ot(params->num, params->xin_id, ot_lim);
forced_on = force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
@@ -283,6 +297,7 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
params->reg_off_mdp_clk_ctrl, false);
+ SDEROT_EVTLOG(params->num, params->xin_id, ot_lim);
exit:
return;
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
index c04e71f459d1..a7c1e890758e 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
@@ -39,6 +39,8 @@ struct sde_mdp_set_ot_params {
u32 reg_off_vbif_lim_conf;
u32 reg_off_mdp_clk_ctrl;
u32 bit_off_mdp_clk_ctrl;
+ char __iomem *rotsts_base;
+ u32 rotsts_busy_mask;
};
enum sde_bus_vote_type {
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
index 29215c1a5910..e9988400b729 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -1237,14 +1237,16 @@ static int sde_rotator_calc_perf(struct sde_rot_mgr *mgr,
perf->rdot_limit = sde_mdp_get_ot_limit(
config->input.width, config->input.height,
- config->input.format, max_fps, true);
+ config->input.format, config->frame_rate, true);
perf->wrot_limit = sde_mdp_get_ot_limit(
config->input.width, config->input.height,
- config->input.format, max_fps, false);
+ config->input.format, config->frame_rate, false);
SDEROT_DBG("clk:%lu, rdBW:%d, wrBW:%d, rdOT:%d, wrOT:%d\n",
perf->clk_rate, read_bw, write_bw, perf->rdot_limit,
perf->wrot_limit);
+ SDEROT_EVTLOG(perf->clk_rate, read_bw, write_bw, perf->rdot_limit,
+ perf->wrot_limit);
return 0;
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c
index 3d84389513f1..5f886d7f1af2 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -350,7 +350,7 @@ static int sde_mdp_src_addr_setup(struct sde_mdp_pipe *pipe,
static void sde_mdp_set_ot_limit_pipe(struct sde_mdp_pipe *pipe)
{
- struct sde_mdp_set_ot_params ot_params;
+ struct sde_mdp_set_ot_params ot_params = {0,};
ot_params.xin_id = pipe->xin_id;
ot_params.num = pipe->num;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c
index f9dc34167c59..863dfb09ad0f 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c
@@ -402,7 +402,7 @@ static int sde_mdp_wb_wait4comp(struct sde_mdp_ctl *ctl, void *arg)
static void sde_mdp_set_ot_limit_wb(struct sde_mdp_writeback_ctx *ctx)
{
- struct sde_mdp_set_ot_params ot_params;
+ struct sde_mdp_set_ot_params ot_params = {0,};
ot_params.xin_id = ctx->xin_id;
ot_params.num = ctx->wb_num;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index 3bb8399da4bf..d7fb167ab49f 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -339,6 +339,8 @@ static void sde_hw_rotator_disable_irq(struct sde_hw_rotator *rot)
*/
static void sde_hw_rotator_dump_status(struct sde_hw_rotator *rot)
{
+ struct sde_rot_data_type *mdata = sde_rot_get_mdata();
+
SDEROT_ERR(
"op_mode = %x, int_en = %x, int_status = %x\n",
SDE_ROTREG_READ(rot->mdss_base,
@@ -370,6 +372,10 @@ static void sde_hw_rotator_dump_status(struct sde_hw_rotator *rot)
"UBWC decode status = %x, UBWC encode status = %x\n",
SDE_ROTREG_READ(rot->mdss_base, ROT_SSPP_UBWC_ERROR_STATUS),
SDE_ROTREG_READ(rot->mdss_base, ROT_WB_UBWC_ERROR_STATUS));
+
+ SDEROT_ERR("VBIF XIN HALT status = %x VBIF AXI HALT status = %x\n",
+ SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL1),
+ SDE_VBIF_READ(mdata, MMSS_VBIF_AXI_HALT_CTRL1));
}
/**
@@ -1689,7 +1695,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
item->input.width, item->input.height,
item->output.width, item->output.height,
entry->src_buf.p[0].addr, entry->dst_buf.p[0].addr,
- item->input.format, item->output.format);
+ item->input.format, item->output.format,
+ entry->perf->config.frame_rate);
if (mdata->default_ot_rd_limit) {
struct sde_mdp_set_ot_params ot_params;
@@ -1708,6 +1715,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
ot_params.fmt = ctx->is_traffic_shaping ?
SDE_PIX_FMT_ABGR_8888 :
entry->perf->config.input.format;
+ ot_params.rotsts_base = rot->mdss_base + ROTTOP_STATUS;
+ ot_params.rotsts_busy_mask = ROT_BUSY_BIT;
sde_mdp_set_ot_limit(&ot_params);
}
@@ -1728,6 +1737,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
ot_params.fmt = ctx->is_traffic_shaping ?
SDE_PIX_FMT_ABGR_8888 :
entry->perf->config.input.format;
+ ot_params.rotsts_base = rot->mdss_base + ROTTOP_STATUS;
+ ot_params.rotsts_busy_mask = ROT_BUSY_BIT;
sde_mdp_set_ot_limit(&ot_params);
}
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c
index da6c68d43b53..fc89a2ea772e 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.c
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2147,8 +2147,10 @@ static int mdp3_ctrl_lut_config(struct msm_fb_data_type *mfd,
dma = mdp3_session->dma;
- if (cfg->cmap.start + cfg->cmap.len > MDP_LUT_SIZE) {
- pr_err("Invalid arguments\n");
+ if ((cfg->cmap.start > MDP_LUT_SIZE) ||
+ (cfg->cmap.len > MDP_LUT_SIZE) ||
+ (cfg->cmap.start + cfg->cmap.len > MDP_LUT_SIZE)) {
+ pr_err("Invalid arguments.\n");
return -EINVAL;
}
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index f3c36c5c6b5a..2199f923260f 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -129,6 +129,40 @@ static int mdss_dp_is_clk_prefix(const char *clk_prefix, const char *clk_name)
return !strncmp(clk_name, clk_prefix, strlen(clk_prefix));
}
+static int mdss_dp_parse_prop(struct platform_device *pdev,
+ struct mdss_dp_drv_pdata *dp_drv)
+{
+ int len = 0, i = 0;
+ const char *data;
+
+ data = of_get_property(pdev->dev.of_node,
+ "qcom,aux-cfg-settings", &len);
+ if ((!data) || (len != AUX_CFG_LEN)) {
+ pr_err("%s:%d, Unable to read DP AUX CFG settings",
+ __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < len; i++)
+ dp_drv->aux_cfg[i] = data[i];
+
+ data = of_get_property(pdev->dev.of_node,
+ "qcom,logical2physical-lane-map", &len);
+ if ((!data) || (len != DP_MAX_PHY_LN)) {
+ pr_debug("%s:%d, lane mapping not defined, use default",
+ __func__, __LINE__);
+ dp_drv->l_map[DP_PHY_LN0] = DP_ML0;
+ dp_drv->l_map[DP_PHY_LN1] = DP_ML1;
+ dp_drv->l_map[DP_PHY_LN2] = DP_ML2;
+ dp_drv->l_map[DP_PHY_LN3] = DP_ML3;
+ } else {
+ for (i = 0; i < len; i++)
+ dp_drv->l_map[i] = data[i];
+ }
+
+ return 0;
+}
+
static int mdss_dp_init_clk_power_data(struct device *dev,
struct mdss_dp_drv_pdata *pdata)
{
@@ -304,7 +338,25 @@ static int mdss_dp_clk_init(struct mdss_dp_drv_pdata *dp_drv,
goto ctrl_get_error;
}
+ dp_drv->pixel_clk_rcg = devm_clk_get(dev, "pixel_clk_rcg");
+ if (IS_ERR(dp_drv->pixel_clk_rcg)) {
+ pr_debug("%s: Unable to get DP pixel clk RCG\n",
+ __func__);
+ dp_drv->pixel_clk_rcg = NULL;
+ }
+
+ dp_drv->pixel_parent = devm_clk_get(dev,
+ "pixel_parent");
+ if (IS_ERR(dp_drv->pixel_parent)) {
+ pr_debug("%s: Unable to get DP pixel RCG parent\n",
+ __func__);
+ dp_drv->pixel_parent = NULL;
+ }
} else {
+ if (dp_drv->pixel_parent)
+ devm_clk_put(dev, dp_drv->pixel_parent);
+ if (dp_drv->pixel_clk_rcg)
+ devm_clk_put(dev, dp_drv->pixel_clk_rcg);
msm_dss_put_clk(ctrl_power_data->clk_config,
ctrl_power_data->num_clk);
msm_dss_put_clk(core_power_data->clk_config,
@@ -1151,10 +1203,9 @@ static inline void mdss_dp_ack_state(struct mdss_dp_drv_pdata *dp, int val)
* given usb plug orientation.
*/
static int mdss_dp_get_lane_mapping(struct mdss_dp_drv_pdata *dp,
- enum plug_orientation orientation,
- struct lane_mapping *lane_map)
+ enum plug_orientation orientation, char *lane_map)
{
- int ret = 0;
+ int ret = 0, i = 0, j = 0;
pr_debug("enter: orientation = %d\n", orientation);
@@ -1164,22 +1215,35 @@ static int mdss_dp_get_lane_mapping(struct mdss_dp_drv_pdata *dp,
goto exit;
}
- /* Set the default lane mapping */
- lane_map->lane0 = 2;
- lane_map->lane1 = 3;
- lane_map->lane2 = 1;
- lane_map->lane3 = 0;
-
+ /* For flip case, swap phy lanes with ML0 and ML3, ML1 and ML2 */
if (orientation == ORIENTATION_CC2) {
- lane_map->lane0 = 1;
- lane_map->lane1 = 0;
- lane_map->lane2 = 2;
- lane_map->lane3 = 3;
+ for (i = 0; i < DP_MAX_PHY_LN; i++) {
+ if (dp->l_map[i] == DP_ML0) {
+ for (j = 0; j < DP_MAX_PHY_LN; j++) {
+ if (dp->l_map[j] == DP_ML3) {
+ lane_map[i] = DP_ML3;
+ lane_map[j] = DP_ML0;
+ break;
+ }
+ }
+ } else if (dp->l_map[i] == DP_ML1) {
+ for (j = 0; j < DP_MAX_PHY_LN; j++) {
+ if (dp->l_map[j] == DP_ML2) {
+ lane_map[i] = DP_ML2;
+ lane_map[j] = DP_ML1;
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ /* Normal orientation */
+ for (i = 0; i < DP_MAX_PHY_LN; i++)
+ lane_map[i] = dp->l_map[i];
}
pr_debug("lane0 = %d, lane1 = %d, lane2 =%d, lane3 =%d\n",
- lane_map->lane0, lane_map->lane1, lane_map->lane2,
- lane_map->lane3);
+ lane_map[0], lane_map[1], lane_map[2], lane_map[3]);
exit:
return ret;
@@ -1212,6 +1276,9 @@ static int mdss_dp_enable_mainlink_clocks(struct mdss_dp_drv_pdata *dp)
{
int ret = 0;
+ if (dp->pixel_clk_rcg && dp->pixel_parent)
+ clk_set_parent(dp->pixel_clk_rcg, dp->pixel_parent);
+
mdss_dp_set_clock_rate(dp, "ctrl_link_clk",
(dp->link_rate * DP_LINK_RATE_MULTIPLIER) / DP_KHZ_TO_HZ);
@@ -1248,9 +1315,9 @@ static void mdss_dp_disable_mainlink_clocks(struct mdss_dp_drv_pdata *dp_drv)
* configuration, output format and sink/panel timing information.
*/
static void mdss_dp_configure_source_params(struct mdss_dp_drv_pdata *dp,
- struct lane_mapping *lane_map)
+ char *lane_map)
{
- mdss_dp_ctrl_lane_mapping(&dp->ctrl_io, *lane_map);
+ mdss_dp_ctrl_lane_mapping(&dp->ctrl_io, lane_map);
mdss_dp_fill_link_cfg(dp);
mdss_dp_mainlink_ctrl(&dp->ctrl_io, true);
mdss_dp_config_ctrl(dp);
@@ -1318,7 +1385,7 @@ end:
static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed)
{
int ret = 0;
- struct lane_mapping ln_map;
+ char ln_map[4];
/* wait until link training is completed */
pr_debug("enter, lt_needed=%s\n", lt_needed ? "true" : "false");
@@ -1331,13 +1398,14 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed)
dp_init_panel_info(dp_drv, dp_drv->vic);
ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation,
- &ln_map);
+ ln_map);
if (ret)
goto exit_loop;
mdss_dp_phy_share_lane_config(&dp_drv->phy_io,
dp_drv->orientation,
- dp_drv->dpcd.max_lane_count);
+ dp_drv->dpcd.max_lane_count,
+ dp_drv->phy_reg_offset);
if (lt_needed) {
/*
@@ -1352,7 +1420,7 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed)
goto exit_loop;
}
- mdss_dp_configure_source_params(dp_drv, &ln_map);
+ mdss_dp_configure_source_params(dp_drv, ln_map);
reinit_completion(&dp_drv->idle_comp);
@@ -1385,7 +1453,7 @@ exit_loop:
int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
{
int ret = 0;
- struct lane_mapping ln_map;
+ char ln_map[4];
/* wait until link training is completed */
mutex_lock(&dp_drv->train_mutex);
@@ -1404,7 +1472,7 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
}
mdss_dp_hpd_configure(&dp_drv->ctrl_io, true);
- ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation, &ln_map);
+ ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation, ln_map);
if (ret)
goto exit;
@@ -1419,7 +1487,7 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
}
mdss_dp_phy_share_lane_config(&dp_drv->phy_io, dp_drv->orientation,
- dp_drv->dpcd.max_lane_count);
+ dp_drv->dpcd.max_lane_count, dp_drv->phy_reg_offset);
ret = mdss_dp_enable_mainlink_clocks(dp_drv);
if (ret)
@@ -1427,7 +1495,7 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
reinit_completion(&dp_drv->idle_comp);
- mdss_dp_configure_source_params(dp_drv, &ln_map);
+ mdss_dp_configure_source_params(dp_drv, ln_map);
if (dp_drv->psm_enabled) {
ret = mdss_dp_aux_send_psm_request(dp_drv, false);
@@ -1689,7 +1757,8 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
mdss_dp_get_ctrl_hw_version(&dp_drv->ctrl_io),
mdss_dp_get_phy_hw_version(&dp_drv->phy_io));
- mdss_dp_phy_aux_setup(&dp_drv->phy_io);
+ mdss_dp_phy_aux_setup(&dp_drv->phy_io, dp_drv->aux_cfg,
+ dp_drv->phy_reg_offset);
mdss_dp_irq_enable(dp_drv);
dp_drv->dp_initialized = true;
@@ -2743,6 +2812,11 @@ static int mdss_retrieve_dp_ctrl_resources(struct platform_device *pdev,
return rc;
}
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,phy-register-offset", &dp_drv->phy_reg_offset);
+ if (rc)
+ dp_drv->phy_reg_offset = 0;
+
rc = msm_dss_ioremap_byname(pdev, &dp_drv->tcsr_reg_io,
"tcsr_regs");
if (rc) {
@@ -3704,6 +3778,13 @@ static int mdss_dp_probe(struct platform_device *pdev)
goto probe_err;
}
+ ret = mdss_dp_parse_prop(pdev, dp_drv);
+ if (ret) {
+ DEV_ERR("DP properties parsing failed.ret=%d\n",
+ ret);
+ goto probe_err;
+ }
+
ret = mdss_dp_irq_setup(dp_drv);
if (ret)
goto probe_err;
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index bf74a8a4d7df..d6f5d160aef2 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -36,6 +36,8 @@
#define AUX_CMD_MAX 16
#define AUX_CMD_I2C_MAX 128
+#define AUX_CFG_LEN 10
+
#define EDP_PORT_MAX 1
#define EDP_SINK_CAP_LEN 16
@@ -460,6 +462,7 @@ struct mdss_dp_drv_pdata {
struct dss_io_data dp_cc_io;
struct dss_io_data qfprom_io;
struct dss_io_data hdcp_io;
+ u32 phy_reg_offset;
int base_size;
unsigned char *mmss_cc_base;
bool override_config;
@@ -486,6 +489,10 @@ struct mdss_dp_drv_pdata {
struct edp_edid edid;
struct dpcd_cap dpcd;
+ /* DP Pixel clock RCG and PLL parent */
+ struct clk *pixel_clk_rcg;
+ struct clk *pixel_parent;
+
/* regulators */
struct dss_module_power power_data[DP_MAX_PM];
struct dp_pinctrl_res pin_res;
@@ -536,6 +543,10 @@ struct mdss_dp_drv_pdata {
struct mdss_dp_event_data dp_event;
struct task_struct *ev_thread;
+ /* dt settings */
+ char l_map[4];
+ u32 aux_cfg[AUX_CFG_LEN];
+
struct workqueue_struct *workq;
struct delayed_work hdcp_cb_work;
spinlock_t lock;
@@ -554,6 +565,21 @@ struct mdss_dp_drv_pdata {
struct list_head attention_head;
};
+enum dp_phy_lane_num {
+ DP_PHY_LN0 = 0,
+ DP_PHY_LN1 = 1,
+ DP_PHY_LN2 = 2,
+ DP_PHY_LN3 = 3,
+ DP_MAX_PHY_LN = 4,
+};
+
+enum dp_mainlink_lane_num {
+ DP_ML0 = 0,
+ DP_ML1 = 1,
+ DP_ML2 = 2,
+ DP_ML3 = 3,
+};
+
enum dp_lane_count {
DP_LANE_COUNT_1 = 1,
DP_LANE_COUNT_2 = 2,
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c
index 1dcf83f094c1..f89b86f72b52 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.c
+++ b/drivers/video/fbdev/msm/mdss_dp_util.c
@@ -859,31 +859,38 @@ void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate,
pr_debug("dp_tu=0x%x\n", dp_tu);
}
-void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io,
- struct lane_mapping l_map)
+void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io, char *l_map)
{
u8 bits_per_lane = 2;
- u32 lane_map = ((l_map.lane0 << (bits_per_lane * 0))
- | (l_map.lane1 << (bits_per_lane * 1))
- | (l_map.lane2 << (bits_per_lane * 2))
- | (l_map.lane3 << (bits_per_lane * 3)));
+ u32 lane_map = ((l_map[0] << (bits_per_lane * 0))
+ | (l_map[1] << (bits_per_lane * 1))
+ | (l_map[2] << (bits_per_lane * 2))
+ | (l_map[3] << (bits_per_lane * 3)));
pr_debug("%s: lane mapping reg = 0x%x\n", __func__, lane_map);
writel_relaxed(lane_map,
ctrl_io->base + DP_LOGICAL2PHYSCIAL_LANE_MAPPING);
}
-void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io)
+void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io, u32 *aux_cfg,
+ u32 phy_reg_offset)
{
- writel_relaxed(0x3d, phy_io->base + DP_PHY_PD_CTL);
- writel_relaxed(0x13, phy_io->base + DP_PHY_AUX_CFG1);
- writel_relaxed(0x10, phy_io->base + DP_PHY_AUX_CFG3);
- writel_relaxed(0x0a, phy_io->base + DP_PHY_AUX_CFG4);
- writel_relaxed(0x26, phy_io->base + DP_PHY_AUX_CFG5);
- writel_relaxed(0x0a, phy_io->base + DP_PHY_AUX_CFG6);
- writel_relaxed(0x03, phy_io->base + DP_PHY_AUX_CFG7);
- writel_relaxed(0x8b, phy_io->base + DP_PHY_AUX_CFG8);
- writel_relaxed(0x03, phy_io->base + DP_PHY_AUX_CFG9);
- writel_relaxed(0x1f, phy_io->base + DP_PHY_AUX_INTERRUPT_MASK);
+ void __iomem *adjusted_phy_io_base = phy_io->base + phy_reg_offset;
+
+ writel_relaxed(0x3d, adjusted_phy_io_base + DP_PHY_PD_CTL);
+
+ /* DP AUX CFG register programming */
+ writel_relaxed(aux_cfg[0], adjusted_phy_io_base + DP_PHY_AUX_CFG0);
+ writel_relaxed(aux_cfg[1], adjusted_phy_io_base + DP_PHY_AUX_CFG1);
+ writel_relaxed(aux_cfg[2], adjusted_phy_io_base + DP_PHY_AUX_CFG2);
+ writel_relaxed(aux_cfg[3], adjusted_phy_io_base + DP_PHY_AUX_CFG3);
+ writel_relaxed(aux_cfg[4], adjusted_phy_io_base + DP_PHY_AUX_CFG4);
+ writel_relaxed(aux_cfg[5], adjusted_phy_io_base + DP_PHY_AUX_CFG5);
+ writel_relaxed(aux_cfg[6], adjusted_phy_io_base + DP_PHY_AUX_CFG6);
+ writel_relaxed(aux_cfg[7], adjusted_phy_io_base + DP_PHY_AUX_CFG7);
+ writel_relaxed(aux_cfg[8], adjusted_phy_io_base + DP_PHY_AUX_CFG8);
+ writel_relaxed(aux_cfg[9], adjusted_phy_io_base + DP_PHY_AUX_CFG9);
+
+ writel_relaxed(0x1f, adjusted_phy_io_base + DP_PHY_AUX_INTERRUPT_MASK);
}
int mdss_dp_irq_setup(struct mdss_dp_drv_pdata *dp_drv)
@@ -1036,14 +1043,14 @@ u32 mdss_dp_usbpd_gen_config_pkt(struct mdss_dp_drv_pdata *dp)
}
void mdss_dp_phy_share_lane_config(struct dss_io_data *phy_io,
- u8 orientation, u8 ln_cnt)
+ u8 orientation, u8 ln_cnt, u32 phy_reg_offset)
{
u32 info = 0x0;
info |= (ln_cnt & 0x0F);
info |= ((orientation & 0x0F) << 4);
pr_debug("Shared Info = 0x%x\n", info);
- writel_relaxed(info, phy_io->base + DP_PHY_SPARE0);
+ writel_relaxed(info, phy_io->base + phy_reg_offset + DP_PHY_SPARE0);
}
void mdss_dp_config_audio_acr_ctrl(struct dss_io_data *ctrl_io, char link_rate)
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h
index cb62d145960f..b3b15a3579fa 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.h
+++ b/drivers/video/fbdev/msm/mdss_dp_util.h
@@ -206,13 +206,6 @@
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA11 (0x01C)
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA12 (0x020)
-struct lane_mapping {
- char lane0;
- char lane1;
- char lane2;
- char lane3;
-};
-
struct edp_cmd {
char read; /* 1 == read, 0 == write */
char i2c; /* 1 == i2c cmd, 0 == native cmd */
@@ -292,12 +285,12 @@ 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, struct mdss_panel_info *pinfo);
void mdss_dp_config_misc(struct mdss_dp_drv_pdata *dp, u32 bd, u32 cc);
-void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io);
+void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io, u32 *aux_cfg,
+ u32 phy_reg_offset);
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);
void mdss_dp_mainlink_ctrl(struct dss_io_data *ctrl_io, bool enable);
-void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io,
- struct lane_mapping l_map);
+void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io, char *l_map);
int mdss_dp_mainlink_ready(struct mdss_dp_drv_pdata *dp, u32 which);
void mdss_dp_timing_cfg(struct dss_io_data *ctrl_io,
struct mdss_panel_info *pinfo);
@@ -311,10 +304,8 @@ void mdss_dp_sw_config_msa(struct dss_io_data *ctrl_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);
-void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io,
- struct lane_mapping l_map);
void mdss_dp_phy_share_lane_config(struct dss_io_data *phy_io,
- u8 orientation, u8 ln_cnt);
+ u8 orientation, u8 ln_cnt, u32 phy_reg_offset);
void mdss_dp_config_audio_acr_ctrl(struct dss_io_data *ctrl_io,
char link_rate);
void mdss_dp_audio_setup_sdps(struct dss_io_data *ctrl_io, u32 num_of_channels);
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index fbbcc16f48b5..37a3876d3570 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -2138,6 +2138,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
set_bit(MDSS_CAPS_3D_MUX_UNDERRUN_RECOVERY_SUPPORTED,
mdata->mdss_caps_map);
set_bit(MDSS_CAPS_QSEED3, mdata->mdss_caps_map);
+ set_bit(MDSS_CAPS_DEST_SCALER, mdata->mdss_caps_map);
set_bit(MDSS_CAPS_MDP_VOTE_CLK_NOT_SUPPORTED,
mdata->mdss_caps_map);
mdss_mdp_init_default_prefill_factors(mdata);