diff options
| -rw-r--r-- | Documentation/devicetree/bindings/fb/mdss-dp.txt | 7 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msm8998-mdss.dtsi | 7 | ||||
| -rw-r--r-- | drivers/media/platform/msm/sde/rotator/sde_rotator_base.c | 15 | ||||
| -rw-r--r-- | drivers/media/platform/msm/sde/rotator/sde_rotator_base.h | 2 | ||||
| -rw-r--r-- | drivers/media/platform/msm/sde/rotator/sde_rotator_core.c | 6 | ||||
| -rw-r--r-- | drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c | 4 | ||||
| -rw-r--r-- | drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c | 2 | ||||
| -rw-r--r-- | drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c | 13 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp3_ctrl.c | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.c | 133 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.h | 26 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_util.c | 45 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_util.h | 17 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 1 |
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); |
