Loading drivers/gpu/drm/msm/dp/dp_audio.c +67 −13 Original line number Diff line number Diff line /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2018, 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 @@ -299,8 +299,15 @@ static void dp_audio_isrc_sdp(struct dp_audio_private *audio) static void dp_audio_setup_sdp(struct dp_audio_private *audio) { /* always program stream 0 first before actual stream cfg */ audio->catalog->stream_id = DP_STREAM_0; audio->catalog->config_sdp(audio->catalog); if (audio->panel->stream_id == DP_STREAM_1) { audio->catalog->stream_id = DP_STREAM_1; audio->catalog->config_sdp(audio->catalog); } dp_audio_stream_sdp(audio); dp_audio_timestamp_sdp(audio); dp_audio_infoframe_sdp(audio); Loading Loading @@ -413,6 +420,12 @@ static int dp_audio_info_setup(struct platform_device *pdev, audio->channels = params->num_of_channels; if (audio->panel->stream_id >= DP_STREAM_MAX) { pr_err("invalid stream id: %d\n", audio->panel->stream_id); rc = -EINVAL; goto end; } dp_audio_setup_sdp(audio); dp_audio_setup_acr(audio); dp_audio_safe_to_exit_level(audio); Loading Loading @@ -553,18 +566,23 @@ static int dp_audio_codec_ready(struct platform_device *pdev) return rc; } static int dp_audio_init_ext_disp(struct dp_audio_private *audio) static int dp_audio_register_ext_disp(struct dp_audio *dp_audio) { int rc = 0; struct device_node *pd = NULL; const char *phandle = "qcom,ext-disp"; struct msm_ext_disp_init_data *ext; struct msm_ext_disp_audio_codec_ops *ops; struct dp_audio_private *audio; audio = container_of(dp_audio, struct dp_audio_private, dp_audio); ext = &audio->ext_audio_data; ops = &ext->codec_ops; ext->type = EXT_DISPLAY_TYPE_DP; ext->codec.type = EXT_DISPLAY_TYPE_DP; ext->codec.ctrl_id = 0; ext->codec.stream_id = audio->panel->stream_id; ext->pdev = audio->pdev; ext->intf_data = &audio->dp_audio; Loading Loading @@ -606,13 +624,53 @@ static int dp_audio_init_ext_disp(struct dp_audio_private *audio) return rc; } static int dp_audio_deregister_ext_disp(struct dp_audio *dp_audio) { int rc = 0; struct device_node *pd = NULL; const char *phandle = "qcom,ext-disp"; struct msm_ext_disp_init_data *ext; struct dp_audio_private *audio; audio = container_of(dp_audio, struct dp_audio_private, dp_audio); ext = &audio->ext_audio_data; if (!audio->pdev->dev.of_node) { pr_err("cannot find audio dev.of_node\n"); rc = -ENODEV; goto end; } pd = of_parse_phandle(audio->pdev->dev.of_node, phandle, 0); if (!pd) { pr_err("cannot parse %s handle\n", phandle); rc = -ENODEV; goto end; } audio->ext_pdev = of_find_device_by_node(pd); if (!audio->ext_pdev) { pr_err("cannot find %s pdev\n", phandle); rc = -ENODEV; goto end; } rc = msm_ext_disp_deregister_intf(audio->ext_pdev, ext); if (rc) pr_err("failed to deregister disp\n"); end: return rc; } static int dp_audio_notify(struct dp_audio_private *audio, u32 state) { int rc = 0; struct msm_ext_disp_init_data *ext = &audio->ext_audio_data; rc = ext->intf_ops.audio_notify(audio->ext_pdev, EXT_DISPLAY_TYPE_DP, state); &ext->codec, state); if (rc) { pr_err("failed to notify audio. state=%d err=%d\n", state, rc); goto end; Loading Loading @@ -653,7 +711,7 @@ static int dp_audio_on(struct dp_audio *dp_audio) audio->session_on = true; rc = ext->intf_ops.audio_config(audio->ext_pdev, EXT_DISPLAY_TYPE_DP, &ext->codec, EXT_DISPLAY_CABLE_CONNECT); if (rc) { pr_err("failed to config audio, err=%d\n", rc); Loading Loading @@ -695,7 +753,7 @@ static int dp_audio_off(struct dp_audio *dp_audio) pr_debug("success\n"); end: rc = ext->intf_ops.audio_config(audio->ext_pdev, EXT_DISPLAY_TYPE_DP, &ext->codec, EXT_DISPLAY_CABLE_DISCONNECT); if (rc) pr_err("failed to config audio, err=%d\n", rc); Loading Loading @@ -771,17 +829,13 @@ struct dp_audio *dp_audio_get(struct platform_device *pdev, dp_audio->on = dp_audio_on; dp_audio->off = dp_audio_off; rc = dp_audio_init_ext_disp(audio); if (rc) { goto error_ext_disp; } dp_audio->register_ext_disp = dp_audio_register_ext_disp; dp_audio->deregister_ext_disp = dp_audio_deregister_ext_disp; catalog->init(catalog); return dp_audio; error_ext_disp: dp_audio_destroy_notify_workqueue(audio); error_notify_workqueue: devm_kfree(&pdev->dev, audio); error: Loading drivers/gpu/drm/msm/dp/dp_audio.h +23 −1 Original line number Diff line number Diff line /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2018, 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 @@ -52,6 +52,28 @@ struct dp_audio { * Returns the error code in case of failure, 0 in success case. */ int (*off)(struct dp_audio *dp_audio); /** * register_ext_disp() * * Registers the audio with external display module. * * @dp_audio: an instance of struct dp_audio. * * Returns the error code in case of failure, 0 in success case. */ int (*register_ext_disp)(struct dp_audio *dp_audio); /** * deregister_ext_disp() * * Deregisters the audio with external display module. * * @dp_audio: an instance of struct dp_audio. * * Returns the error code in case of failure, 0 in success case. */ int (*deregister_ext_disp)(struct dp_audio *dp_audio); }; /** Loading drivers/gpu/drm/msm/dp/dp_catalog.c +16 −6 Original line number Diff line number Diff line Loading @@ -1678,16 +1678,26 @@ static void dp_catalog_audio_config_sdp(struct dp_catalog_audio *audio) { struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 sdp_cfg = 0; u32 sdp_cfg2 = 0; u32 sdp_cfg = 0, sdp_cfg_off = 0; u32 sdp_cfg2 = 0, sdp_cfg2_off = 0; if (!audio) return; if (audio->stream_id >= DP_STREAM_MAX) { pr_err("invalid stream id:%d\n", audio->stream_id); return; } if (audio->stream_id == DP_STREAM_1) { sdp_cfg_off = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG; sdp_cfg2_off = MMSS_DP1_SDP_CFG2 - MMSS_DP_SDP_CFG2; } catalog = dp_catalog_get_priv(audio); io_data = catalog->io.dp_link; sdp_cfg = dp_read(catalog, io_data, MMSS_DP_SDP_CFG); sdp_cfg = dp_read(catalog, io_data, MMSS_DP_SDP_CFG + sdp_cfg_off); /* AUDIO_TIMESTAMP_SDP_EN */ sdp_cfg |= BIT(1); Loading @@ -1701,16 +1711,16 @@ static void dp_catalog_audio_config_sdp(struct dp_catalog_audio *audio) sdp_cfg |= BIT(20); pr_debug("sdp_cfg = 0x%x\n", sdp_cfg); dp_write(catalog, io_data, MMSS_DP_SDP_CFG, sdp_cfg); dp_write(catalog, io_data, MMSS_DP_SDP_CFG + sdp_cfg_off, sdp_cfg); sdp_cfg2 = dp_read(catalog, io_data, MMSS_DP_SDP_CFG2); sdp_cfg2 = dp_read(catalog, io_data, MMSS_DP_SDP_CFG2 + sdp_cfg_off); /* IFRM_REGSRC -> Do not use reg values */ sdp_cfg2 &= ~BIT(0); /* AUDIO_STREAM_HB3_REGSRC-> Do not use reg values */ sdp_cfg2 &= ~BIT(1); pr_debug("sdp_cfg2 = 0x%x\n", sdp_cfg2); dp_write(catalog, io_data, MMSS_DP_SDP_CFG2, sdp_cfg2); dp_write(catalog, io_data, MMSS_DP_SDP_CFG2 + sdp_cfg_off, sdp_cfg2); } static void dp_catalog_audio_get_header(struct dp_catalog_audio *audio) Loading drivers/gpu/drm/msm/dp/dp_catalog.h +2 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,8 @@ struct dp_catalog_audio { enum dp_catalog_audio_header_type sdp_header; u32 data; enum dp_stream_id stream_id; void (*init)(struct dp_catalog_audio *audio); void (*enable)(struct dp_catalog_audio *audio); void (*config_acr)(struct dp_catalog_audio *audio); Loading drivers/gpu/drm/msm/dp/dp_catalog_v420.c +7 −5 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel, bool fixed_nvid) { u32 pixel_m, pixel_n; u32 mvid, nvid, reg_off = 0; u32 mvid, nvid, reg_off = 0, mvid_off = 0, nvid_off = 0; u64 mvid_calc; u32 const nvid_fixed = 0x8000; u32 const link_rate_hbr2 = 540000; Loading Loading @@ -199,12 +199,14 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel, io_data = catalog->io->dp_link; if (panel->stream_id == DP_STREAM_1) reg_off = DP1_SOFTWARE_MVID - DP_SOFTWARE_MVID; if (panel->stream_id == DP_STREAM_1) { mvid_off = DP1_SOFTWARE_MVID - DP_SOFTWARE_MVID; nvid_off = DP1_SOFTWARE_NVID - DP_SOFTWARE_NVID; } pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid); dp_write(catalog, io_data, DP_SOFTWARE_MVID + reg_off, mvid); dp_write(catalog, io_data, DP_SOFTWARE_NVID + reg_off, nvid); dp_write(catalog, io_data, DP_SOFTWARE_MVID + mvid_off, mvid); dp_write(catalog, io_data, DP_SOFTWARE_NVID + nvid_off, nvid); } static void dp_catalog_ctrl_phy_lane_cfg_v420(struct dp_catalog_ctrl *ctrl, Loading Loading
drivers/gpu/drm/msm/dp/dp_audio.c +67 −13 Original line number Diff line number Diff line /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2018, 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 @@ -299,8 +299,15 @@ static void dp_audio_isrc_sdp(struct dp_audio_private *audio) static void dp_audio_setup_sdp(struct dp_audio_private *audio) { /* always program stream 0 first before actual stream cfg */ audio->catalog->stream_id = DP_STREAM_0; audio->catalog->config_sdp(audio->catalog); if (audio->panel->stream_id == DP_STREAM_1) { audio->catalog->stream_id = DP_STREAM_1; audio->catalog->config_sdp(audio->catalog); } dp_audio_stream_sdp(audio); dp_audio_timestamp_sdp(audio); dp_audio_infoframe_sdp(audio); Loading Loading @@ -413,6 +420,12 @@ static int dp_audio_info_setup(struct platform_device *pdev, audio->channels = params->num_of_channels; if (audio->panel->stream_id >= DP_STREAM_MAX) { pr_err("invalid stream id: %d\n", audio->panel->stream_id); rc = -EINVAL; goto end; } dp_audio_setup_sdp(audio); dp_audio_setup_acr(audio); dp_audio_safe_to_exit_level(audio); Loading Loading @@ -553,18 +566,23 @@ static int dp_audio_codec_ready(struct platform_device *pdev) return rc; } static int dp_audio_init_ext_disp(struct dp_audio_private *audio) static int dp_audio_register_ext_disp(struct dp_audio *dp_audio) { int rc = 0; struct device_node *pd = NULL; const char *phandle = "qcom,ext-disp"; struct msm_ext_disp_init_data *ext; struct msm_ext_disp_audio_codec_ops *ops; struct dp_audio_private *audio; audio = container_of(dp_audio, struct dp_audio_private, dp_audio); ext = &audio->ext_audio_data; ops = &ext->codec_ops; ext->type = EXT_DISPLAY_TYPE_DP; ext->codec.type = EXT_DISPLAY_TYPE_DP; ext->codec.ctrl_id = 0; ext->codec.stream_id = audio->panel->stream_id; ext->pdev = audio->pdev; ext->intf_data = &audio->dp_audio; Loading Loading @@ -606,13 +624,53 @@ static int dp_audio_init_ext_disp(struct dp_audio_private *audio) return rc; } static int dp_audio_deregister_ext_disp(struct dp_audio *dp_audio) { int rc = 0; struct device_node *pd = NULL; const char *phandle = "qcom,ext-disp"; struct msm_ext_disp_init_data *ext; struct dp_audio_private *audio; audio = container_of(dp_audio, struct dp_audio_private, dp_audio); ext = &audio->ext_audio_data; if (!audio->pdev->dev.of_node) { pr_err("cannot find audio dev.of_node\n"); rc = -ENODEV; goto end; } pd = of_parse_phandle(audio->pdev->dev.of_node, phandle, 0); if (!pd) { pr_err("cannot parse %s handle\n", phandle); rc = -ENODEV; goto end; } audio->ext_pdev = of_find_device_by_node(pd); if (!audio->ext_pdev) { pr_err("cannot find %s pdev\n", phandle); rc = -ENODEV; goto end; } rc = msm_ext_disp_deregister_intf(audio->ext_pdev, ext); if (rc) pr_err("failed to deregister disp\n"); end: return rc; } static int dp_audio_notify(struct dp_audio_private *audio, u32 state) { int rc = 0; struct msm_ext_disp_init_data *ext = &audio->ext_audio_data; rc = ext->intf_ops.audio_notify(audio->ext_pdev, EXT_DISPLAY_TYPE_DP, state); &ext->codec, state); if (rc) { pr_err("failed to notify audio. state=%d err=%d\n", state, rc); goto end; Loading Loading @@ -653,7 +711,7 @@ static int dp_audio_on(struct dp_audio *dp_audio) audio->session_on = true; rc = ext->intf_ops.audio_config(audio->ext_pdev, EXT_DISPLAY_TYPE_DP, &ext->codec, EXT_DISPLAY_CABLE_CONNECT); if (rc) { pr_err("failed to config audio, err=%d\n", rc); Loading Loading @@ -695,7 +753,7 @@ static int dp_audio_off(struct dp_audio *dp_audio) pr_debug("success\n"); end: rc = ext->intf_ops.audio_config(audio->ext_pdev, EXT_DISPLAY_TYPE_DP, &ext->codec, EXT_DISPLAY_CABLE_DISCONNECT); if (rc) pr_err("failed to config audio, err=%d\n", rc); Loading Loading @@ -771,17 +829,13 @@ struct dp_audio *dp_audio_get(struct platform_device *pdev, dp_audio->on = dp_audio_on; dp_audio->off = dp_audio_off; rc = dp_audio_init_ext_disp(audio); if (rc) { goto error_ext_disp; } dp_audio->register_ext_disp = dp_audio_register_ext_disp; dp_audio->deregister_ext_disp = dp_audio_deregister_ext_disp; catalog->init(catalog); return dp_audio; error_ext_disp: dp_audio_destroy_notify_workqueue(audio); error_notify_workqueue: devm_kfree(&pdev->dev, audio); error: Loading
drivers/gpu/drm/msm/dp/dp_audio.h +23 −1 Original line number Diff line number Diff line /* * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2018, 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 @@ -52,6 +52,28 @@ struct dp_audio { * Returns the error code in case of failure, 0 in success case. */ int (*off)(struct dp_audio *dp_audio); /** * register_ext_disp() * * Registers the audio with external display module. * * @dp_audio: an instance of struct dp_audio. * * Returns the error code in case of failure, 0 in success case. */ int (*register_ext_disp)(struct dp_audio *dp_audio); /** * deregister_ext_disp() * * Deregisters the audio with external display module. * * @dp_audio: an instance of struct dp_audio. * * Returns the error code in case of failure, 0 in success case. */ int (*deregister_ext_disp)(struct dp_audio *dp_audio); }; /** Loading
drivers/gpu/drm/msm/dp/dp_catalog.c +16 −6 Original line number Diff line number Diff line Loading @@ -1678,16 +1678,26 @@ static void dp_catalog_audio_config_sdp(struct dp_catalog_audio *audio) { struct dp_catalog_private *catalog; struct dp_io_data *io_data; u32 sdp_cfg = 0; u32 sdp_cfg2 = 0; u32 sdp_cfg = 0, sdp_cfg_off = 0; u32 sdp_cfg2 = 0, sdp_cfg2_off = 0; if (!audio) return; if (audio->stream_id >= DP_STREAM_MAX) { pr_err("invalid stream id:%d\n", audio->stream_id); return; } if (audio->stream_id == DP_STREAM_1) { sdp_cfg_off = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG; sdp_cfg2_off = MMSS_DP1_SDP_CFG2 - MMSS_DP_SDP_CFG2; } catalog = dp_catalog_get_priv(audio); io_data = catalog->io.dp_link; sdp_cfg = dp_read(catalog, io_data, MMSS_DP_SDP_CFG); sdp_cfg = dp_read(catalog, io_data, MMSS_DP_SDP_CFG + sdp_cfg_off); /* AUDIO_TIMESTAMP_SDP_EN */ sdp_cfg |= BIT(1); Loading @@ -1701,16 +1711,16 @@ static void dp_catalog_audio_config_sdp(struct dp_catalog_audio *audio) sdp_cfg |= BIT(20); pr_debug("sdp_cfg = 0x%x\n", sdp_cfg); dp_write(catalog, io_data, MMSS_DP_SDP_CFG, sdp_cfg); dp_write(catalog, io_data, MMSS_DP_SDP_CFG + sdp_cfg_off, sdp_cfg); sdp_cfg2 = dp_read(catalog, io_data, MMSS_DP_SDP_CFG2); sdp_cfg2 = dp_read(catalog, io_data, MMSS_DP_SDP_CFG2 + sdp_cfg_off); /* IFRM_REGSRC -> Do not use reg values */ sdp_cfg2 &= ~BIT(0); /* AUDIO_STREAM_HB3_REGSRC-> Do not use reg values */ sdp_cfg2 &= ~BIT(1); pr_debug("sdp_cfg2 = 0x%x\n", sdp_cfg2); dp_write(catalog, io_data, MMSS_DP_SDP_CFG2, sdp_cfg2); dp_write(catalog, io_data, MMSS_DP_SDP_CFG2 + sdp_cfg_off, sdp_cfg2); } static void dp_catalog_audio_get_header(struct dp_catalog_audio *audio) Loading
drivers/gpu/drm/msm/dp/dp_catalog.h +2 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,8 @@ struct dp_catalog_audio { enum dp_catalog_audio_header_type sdp_header; u32 data; enum dp_stream_id stream_id; void (*init)(struct dp_catalog_audio *audio); void (*enable)(struct dp_catalog_audio *audio); void (*config_acr)(struct dp_catalog_audio *audio); Loading
drivers/gpu/drm/msm/dp/dp_catalog_v420.c +7 −5 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel, bool fixed_nvid) { u32 pixel_m, pixel_n; u32 mvid, nvid, reg_off = 0; u32 mvid, nvid, reg_off = 0, mvid_off = 0, nvid_off = 0; u64 mvid_calc; u32 const nvid_fixed = 0x8000; u32 const link_rate_hbr2 = 540000; Loading Loading @@ -199,12 +199,14 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel, io_data = catalog->io->dp_link; if (panel->stream_id == DP_STREAM_1) reg_off = DP1_SOFTWARE_MVID - DP_SOFTWARE_MVID; if (panel->stream_id == DP_STREAM_1) { mvid_off = DP1_SOFTWARE_MVID - DP_SOFTWARE_MVID; nvid_off = DP1_SOFTWARE_NVID - DP_SOFTWARE_NVID; } pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid); dp_write(catalog, io_data, DP_SOFTWARE_MVID + reg_off, mvid); dp_write(catalog, io_data, DP_SOFTWARE_NVID + reg_off, nvid); dp_write(catalog, io_data, DP_SOFTWARE_MVID + mvid_off, mvid); dp_write(catalog, io_data, DP_SOFTWARE_NVID + nvid_off, nvid); } static void dp_catalog_ctrl_phy_lane_cfg_v420(struct dp_catalog_ctrl *ctrl, Loading