Loading Documentation/devicetree/bindings/fb/mdss-dp.txt +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 { Loading Loading @@ -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>; Loading arch/arm/boot/dts/qcom/msm8998-mdss.dtsi +4 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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>; Loading drivers/video/fbdev/msm/mdss_dp.c +86 −26 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -1151,10 +1185,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); Loading @@ -1164,22 +1197,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; Loading Loading @@ -1248,9 +1294,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); Loading Loading @@ -1318,7 +1364,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"); Loading @@ -1331,13 +1377,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) { /* Loading @@ -1352,7 +1399,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); Loading Loading @@ -1385,7 +1432,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); Loading @@ -1404,7 +1451,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; Loading @@ -1419,7 +1466,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) Loading @@ -1427,7 +1474,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); Loading Loading @@ -1689,7 +1736,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; Loading Loading @@ -2743,6 +2791,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) { Loading Loading @@ -3704,6 +3757,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; Loading drivers/video/fbdev/msm/mdss_dp.h +22 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -536,6 +539,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; Loading @@ -554,6 +561,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, Loading drivers/video/fbdev/msm/mdss_dp_util.c +26 −19 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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) Loading Loading
Documentation/devicetree/bindings/fb/mdss-dp.txt +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 { Loading Loading @@ -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>; Loading
arch/arm/boot/dts/qcom/msm8998-mdss.dtsi +4 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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>; Loading
drivers/video/fbdev/msm/mdss_dp.c +86 −26 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -1151,10 +1185,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); Loading @@ -1164,22 +1197,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; Loading Loading @@ -1248,9 +1294,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); Loading Loading @@ -1318,7 +1364,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"); Loading @@ -1331,13 +1377,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) { /* Loading @@ -1352,7 +1399,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); Loading Loading @@ -1385,7 +1432,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); Loading @@ -1404,7 +1451,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; Loading @@ -1419,7 +1466,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) Loading @@ -1427,7 +1474,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); Loading Loading @@ -1689,7 +1736,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; Loading Loading @@ -2743,6 +2791,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) { Loading Loading @@ -3704,6 +3757,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; Loading
drivers/video/fbdev/msm/mdss_dp.h +22 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -536,6 +539,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; Loading @@ -554,6 +561,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, Loading
drivers/video/fbdev/msm/mdss_dp_util.c +26 −19 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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) Loading