drm/msm: enable hdmi audio function for sde
Register ext_disp and provide audio codec ops. This enables HDMI audio functionality for DRM driver. CRs-Fixed: 2010135 Change-Id: Ide661456ab42bf6a8f13359819e39317f439a255 Signed-off-by: Ray Zhang <rayz@codeaurora.org>
This commit is contained in:
parent
49d57d9b26
commit
1c4ce7aa2c
5 changed files with 133 additions and 6 deletions
|
@ -18,10 +18,20 @@
|
||||||
label = "wb_display";
|
label = "wb_display";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
msm_ext_disp: qcom,msm_ext_disp {
|
||||||
|
compatible = "qcom,msm-ext-disp";
|
||||||
|
|
||||||
|
ext_disp_audio_codec: qcom,msm-ext-disp-audio-codec-rx {
|
||||||
|
compatible = "qcom,msm-ext-disp-audio-codec-rx";
|
||||||
|
qcom,msm_ext_disp = <&msm_ext_disp>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
sde_hdmi: qcom,hdmi-display {
|
sde_hdmi: qcom,hdmi-display {
|
||||||
compatible = "qcom,hdmi-display";
|
compatible = "qcom,hdmi-display";
|
||||||
label = "sde_hdmi";
|
label = "sde_hdmi";
|
||||||
qcom,display-type = "secondary";
|
qcom,display-type = "secondary";
|
||||||
|
qcom,msm_ext_disp = <&msm_ext_disp>;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -193,8 +193,6 @@
|
||||||
qcom,enable-load = <0>;
|
qcom,enable-load = <0>;
|
||||||
qcom,disable-load = <0>;
|
qcom,disable-load = <0>;
|
||||||
|
|
||||||
qcom,msm_ext_disp = <&msm_ext_disp>;
|
|
||||||
|
|
||||||
clocks = <&clock_mmss clk_mmss_mnoc_ahb_clk>,
|
clocks = <&clock_mmss clk_mmss_mnoc_ahb_clk>,
|
||||||
<&clock_mmss clk_mmss_mdss_ahb_clk>,
|
<&clock_mmss clk_mmss_mdss_ahb_clk>,
|
||||||
<&clock_mmss clk_mmss_mdss_hdmi_clk>,
|
<&clock_mmss clk_mmss_mdss_hdmi_clk>,
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
|
||||||
#include "sde_kms.h"
|
#include "sde_kms.h"
|
||||||
#include "msm_drv.h"
|
#include "msm_drv.h"
|
||||||
|
@ -460,6 +461,114 @@ static irqreturn_t _sde_hdmi_irq(int irq, void *dev_id)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _sde_hdmi_audio_info_setup(struct platform_device *pdev,
|
||||||
|
struct msm_ext_disp_audio_setup_params *params)
|
||||||
|
{
|
||||||
|
int rc = -EPERM;
|
||||||
|
struct sde_hdmi *display = NULL;
|
||||||
|
struct hdmi *hdmi = NULL;
|
||||||
|
|
||||||
|
display = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
if (!display || !params) {
|
||||||
|
SDE_ERROR("invalid param(s), display %pK, params %pK\n",
|
||||||
|
display, params);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdmi = display->ctrl.ctrl;
|
||||||
|
|
||||||
|
if (hdmi->hdmi_mode)
|
||||||
|
rc = sde_hdmi_audio_on(hdmi, params);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _sde_hdmi_get_audio_edid_blk(struct platform_device *pdev,
|
||||||
|
struct msm_ext_disp_audio_edid_blk *blk)
|
||||||
|
{
|
||||||
|
struct sde_hdmi *display = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
if (!display || !blk) {
|
||||||
|
SDE_ERROR("invalid param(s), display %pK, blk %pK\n",
|
||||||
|
display, blk);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: add audio edid blk support */
|
||||||
|
blk->audio_data_blk = NULL;
|
||||||
|
blk->audio_data_blk_size = 0;
|
||||||
|
|
||||||
|
blk->spk_alloc_data_blk = NULL;
|
||||||
|
blk->spk_alloc_data_blk_size = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _sde_hdmi_get_cable_status(struct platform_device *pdev, u32 vote)
|
||||||
|
{
|
||||||
|
struct sde_hdmi *display = NULL;
|
||||||
|
struct hdmi *hdmi = NULL;
|
||||||
|
|
||||||
|
display = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
if (!display) {
|
||||||
|
SDE_ERROR("invalid param(s), display %pK\n", display);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdmi = display->ctrl.ctrl;
|
||||||
|
|
||||||
|
return hdmi->power_on && display->connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _sde_hdmi_ext_disp_init(struct sde_hdmi *display)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct device_node *pd_np;
|
||||||
|
const char *phandle = "qcom,msm_ext_disp";
|
||||||
|
|
||||||
|
if (!display) {
|
||||||
|
SDE_ERROR("[%s]Invalid params\n", display->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
display->ext_audio_data.type = EXT_DISPLAY_TYPE_HDMI;
|
||||||
|
display->ext_audio_data.pdev = display->pdev;
|
||||||
|
display->ext_audio_data.codec_ops.audio_info_setup =
|
||||||
|
_sde_hdmi_audio_info_setup;
|
||||||
|
display->ext_audio_data.codec_ops.get_audio_edid_blk =
|
||||||
|
_sde_hdmi_get_audio_edid_blk;
|
||||||
|
display->ext_audio_data.codec_ops.cable_status =
|
||||||
|
_sde_hdmi_get_cable_status;
|
||||||
|
|
||||||
|
if (!display->pdev->dev.of_node) {
|
||||||
|
SDE_ERROR("[%s]cannot find sde_hdmi of_node\n", display->name);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
pd_np = of_parse_phandle(display->pdev->dev.of_node, phandle, 0);
|
||||||
|
if (!pd_np) {
|
||||||
|
SDE_ERROR("[%s]cannot find %s device node\n",
|
||||||
|
display->name, phandle);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
display->ext_pdev = of_find_device_by_node(pd_np);
|
||||||
|
if (!display->ext_pdev) {
|
||||||
|
SDE_ERROR("[%s]cannot find %s platform device\n",
|
||||||
|
display->name, phandle);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = msm_ext_disp_register_intf(display->ext_pdev,
|
||||||
|
&display->ext_audio_data);
|
||||||
|
if (rc)
|
||||||
|
SDE_ERROR("[%s]failed to register disp\n", display->name);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
void sde_hdmi_set_mode(struct hdmi *hdmi, bool power_on)
|
void sde_hdmi_set_mode(struct hdmi *hdmi, bool power_on)
|
||||||
{
|
{
|
||||||
uint32_t ctrl = 0;
|
uint32_t ctrl = 0;
|
||||||
|
@ -778,6 +887,13 @@ static int sde_hdmi_bind(struct device *dev, struct device *master, void *data)
|
||||||
if (rc) {
|
if (rc) {
|
||||||
SDE_ERROR("[%s]Debugfs init failed, rc=%d\n",
|
SDE_ERROR("[%s]Debugfs init failed, rc=%d\n",
|
||||||
display->name, rc);
|
display->name, rc);
|
||||||
|
goto debug_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = _sde_hdmi_ext_disp_init(display);
|
||||||
|
if (rc) {
|
||||||
|
SDE_ERROR("[%s]Ext Disp init failed, rc=%d\n",
|
||||||
|
display->name, rc);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -787,6 +903,8 @@ static int sde_hdmi_bind(struct device *dev, struct device *master, void *data)
|
||||||
display->drm_dev = drm;
|
display->drm_dev = drm;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
(void)_sde_hdmi_debugfs_deinit(display);
|
||||||
|
debug_error:
|
||||||
mutex_unlock(&display->display_lock);
|
mutex_unlock(&display->display_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,9 @@ struct sde_hdmi {
|
||||||
|
|
||||||
struct sde_hdmi_ctrl ctrl;
|
struct sde_hdmi_ctrl ctrl;
|
||||||
|
|
||||||
|
struct platform_device *ext_pdev;
|
||||||
|
struct msm_ext_disp_init_data ext_audio_data;
|
||||||
|
|
||||||
bool non_pluggable;
|
bool non_pluggable;
|
||||||
u32 num_of_modes;
|
u32 num_of_modes;
|
||||||
struct list_head mode_list;
|
struct list_head mode_list;
|
||||||
|
|
|
@ -111,7 +111,6 @@ static void _sde_hdmi_bridge_pre_enable(struct drm_bridge *bridge)
|
||||||
if (!hdmi->power_on) {
|
if (!hdmi->power_on) {
|
||||||
_sde_hdmi_bridge_power_on(bridge);
|
_sde_hdmi_bridge_power_on(bridge);
|
||||||
hdmi->power_on = true;
|
hdmi->power_on = true;
|
||||||
hdmi_audio_update(hdmi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phy)
|
if (phy)
|
||||||
|
@ -140,6 +139,8 @@ static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge)
|
||||||
if (hdmi->hdcp_ctrl && hdmi->is_hdcp_supported)
|
if (hdmi->hdcp_ctrl && hdmi->is_hdcp_supported)
|
||||||
hdmi_hdcp_ctrl_off(hdmi->hdcp_ctrl);
|
hdmi_hdcp_ctrl_off(hdmi->hdcp_ctrl);
|
||||||
|
|
||||||
|
sde_hdmi_audio_off(hdmi);
|
||||||
|
|
||||||
DRM_DEBUG("power down");
|
DRM_DEBUG("power down");
|
||||||
sde_hdmi_set_mode(hdmi, false);
|
sde_hdmi_set_mode(hdmi, false);
|
||||||
|
|
||||||
|
@ -149,7 +150,6 @@ static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge)
|
||||||
if (hdmi->power_on) {
|
if (hdmi->power_on) {
|
||||||
_sde_hdmi_bridge_power_off(bridge);
|
_sde_hdmi_bridge_power_off(bridge);
|
||||||
hdmi->power_on = false;
|
hdmi->power_on = false;
|
||||||
hdmi_audio_update(hdmi);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,8 +342,6 @@ static void _sde_hdmi_bridge_mode_set(struct drm_bridge *bridge,
|
||||||
_sde_hdmi_bridge_set_spd_infoframe(hdmi, mode);
|
_sde_hdmi_bridge_set_spd_infoframe(hdmi, mode);
|
||||||
DRM_DEBUG("hdmi setup info frame\n");
|
DRM_DEBUG("hdmi setup info frame\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
hdmi_audio_update(hdmi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct drm_bridge_funcs _sde_hdmi_bridge_funcs = {
|
static const struct drm_bridge_funcs _sde_hdmi_bridge_funcs = {
|
||||||
|
|
Loading…
Add table
Reference in a new issue