Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Documentation/devicetree/bindings/display/msm/dp-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ properties:
"#sound-dai-cells":
const: 0

radxa,display-controller-index:
$ref: /schemas/types.yaml#/definitions/uint32
description: Index of the display controller used by board audio firmware.
maximum: 1

radxa,force-audio:
type: boolean
description:
Forces audio support for a DP-to-HDMI bridge whose fixed EDID omits the
CTA audio data block.

vdda-0p9-supply:
deprecated: true
vdda-1p2-supply:
Expand Down
3 changes: 3 additions & 0 deletions Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ properties:
- qcom,sm8650-sndcard
- const: qcom,sm8450-sndcard
- enum:
- radxa,vmarc-q9075-sndcard
- qcom,apq8016-sbc-sndcard
- qcom,msm8916-qdsp6-sndcard
- qcom,qrb5165-rb5-sndcard
- qcom,qcs9075-sndcard
- qcom,qcs9100-sndcard
- qcom,sc7180-qdsp6-sndcard
- qcom,sc8280xp-sndcard
- qcom,sdm845-sndcard
Expand Down
27 changes: 27 additions & 0 deletions arch/arm64/boot/dts/qcom/qcs9075-radxa-vmarc-q9075.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,27 @@
stdout-path = "serial0:115200n8";
};

sound {
compatible = "radxa,vmarc-q9075-sndcard";
model = "VMARC-Q9075-DP";

dp0-dai-link {
link-name = "DISPLAY_PORT-RX";

cpu {
sound-dai = <&q6apmbedai DISPLAY_PORT_RX_0>;
};

codec {
sound-dai = <&mdss0_dp0>;
};

platform {
sound-dai = <&q6apm>;
};
};
};

vcc_5v0_regulator: vcc-5v0-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc_5v0";
Expand Down Expand Up @@ -692,9 +713,15 @@
};

&mdss0_dp0 {
radxa,display-controller-index = <0>;
radxa,force-audio;
status = "okay";
};

&mdss1_dp0 {
radxa,display-controller-index = <1>;
};

&mdss0_dp0_out {
data-lanes = <0 1 2 3>;
link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/configs/qcom_addons.config
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,4 @@ CONFIG_VIRT_DRIVERS=y
CONFIG_SENSORS_EMC2305=y
CONFIG_HWMON=y
CONFIG_SND_SOC_QCS9100=m

CONFIG_SND_SOC_SC8280XP=m
4 changes: 3 additions & 1 deletion drivers/gpu/drm/msm/dp/dp_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,9 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)

dp->msm_dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;

dp->audio_supported = info->has_audio;
dp->audio_supported = info->has_audio ||
of_property_read_bool(dp->msm_dp_display.pdev->dev.of_node,
"radxa,force-audio");
msm_dp_panel_handle_sink_request(dp->panel);

/*
Expand Down
4 changes: 3 additions & 1 deletion drivers/misc/fastrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1616,7 +1616,9 @@ static int fastrpc_mmap_remove_pdr(struct fastrpc_user *fl)
if (session < 0)
return -EUSERS;

if (atomic_read(&fl->cctx->spd[session].ispdup) == 0)
/* The service cannot be up before its initial static PD is created. */
if (fl->cctx->spd[session].pdrcount &&
atomic_read(&fl->cctx->spd[session].ispdup) == 0)
return -ENOTCONN;

if (fl->cctx->spd[session].pdrcount !=
Expand Down
24 changes: 22 additions & 2 deletions sound/soc/qcom/qdsp6/audioreach.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,13 @@ struct apm_display_port_module_intf_cfg {
} __packed;
#define APM_DP_INTF_CFG_PSIZE ALIGN(sizeof(struct apm_display_port_module_intf_cfg), 8)

struct apm_vmarc_display_ctrl_cfg {
struct apm_module_param_data param_data;
struct param_id_vmarc_display_ctrl_cfg cfg;
} __packed;

#define APM_VMARC_DISPLAY_CTRL_CFG_PSIZE ALIGN(sizeof(struct apm_vmarc_display_ctrl_cfg), 8)

static void *__audioreach_alloc_pkt(int payload_size, uint32_t opcode, uint32_t token,
uint32_t src_port, uint32_t dest_port, bool has_cmd_hdr)
{
Expand Down Expand Up @@ -611,20 +618,22 @@ static int audioreach_display_port_set_media_format(struct q6apm_graph *graph,
struct audioreach_module_config *cfg)
{
struct apm_display_port_module_intf_cfg *intf_cfg;
struct apm_vmarc_display_ctrl_cfg *ctrl_cfg;
struct apm_module_frame_size_factor_cfg *fs_cfg;
struct apm_module_param_data *param_data;
struct apm_module_hw_ep_mf_cfg *hw_cfg;
int ic_sz, ep_sz, fs_sz, dl_sz;
int ic_sz, ep_sz, fs_sz, ctrl_sz, dl_sz;
int rc, payload_size;
struct gpr_pkt *pkt;
void *p;

ic_sz = APM_DP_INTF_CFG_PSIZE;
ep_sz = APM_HW_EP_CFG_PSIZE;
fs_sz = APM_FS_CFG_PSIZE;
ctrl_sz = cfg->has_display_ctrl_idx ? APM_VMARC_DISPLAY_CTRL_CFG_PSIZE : 0;
dl_sz = 0;

payload_size = ic_sz + ep_sz + fs_sz + dl_sz;
payload_size = ic_sz + ep_sz + fs_sz + ctrl_sz + dl_sz;

pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
if (IS_ERR(pkt))
Expand Down Expand Up @@ -654,6 +663,17 @@ static int audioreach_display_port_set_media_format(struct q6apm_graph *graph,
fs_cfg->frame_size_factor = 1;
p += fs_sz;

if (cfg->has_display_ctrl_idx) {
ctrl_cfg = p;
param_data = &ctrl_cfg->param_data;
param_data->module_instance_id = module->instance_id;
param_data->error_code = 0;
param_data->param_id = PARAM_ID_VMARC_DISPLAY_CTRL_CFG;
param_data->param_size = ctrl_sz - APM_MODULE_PARAM_DATA_SIZE;
ctrl_cfg->cfg.display_ctrl_idx = cfg->display_ctrl_idx;
p += ctrl_sz;
}

intf_cfg = p;
param_data = &intf_cfg->param_data;
param_data->module_instance_id = module->instance_id;
Expand Down
8 changes: 8 additions & 0 deletions sound/soc/qcom/qdsp6/audioreach.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,12 @@ struct param_id_display_port_intf_cfg {
uint32_t dptx_idx;
} __packed;

#define PARAM_ID_VMARC_DISPLAY_CTRL_CFG 0x0800F001

struct param_id_vmarc_display_ctrl_cfg {
u32 display_ctrl_idx;
} __packed;

#define PARAM_ID_HW_EP_MF_CFG 0x08001017
struct param_id_hw_ep_mf {
uint32_t sample_rate;
Expand Down Expand Up @@ -757,6 +763,8 @@ struct audioreach_module_config {
u16 num_channels;
u16 active_channels_mask;
u16 dp_idx;
u8 display_ctrl_idx;
bool has_display_ctrl_idx;
u32 channel_allocation;
u32 sd_line_mask;
int fmt;
Expand Down
48 changes: 48 additions & 0 deletions sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,47 @@ static int q6dma_set_channel_map(struct snd_soc_dai *dai,
return 0;
}

/*
* Resolve the codec device node of a DAI link from the sound card's DT node.
* The DAI link component's of_node is not populated for links parsed by
* snd_soc_of_get_dai_link_codecs(), so walk the "link-name" matching child and
* dereference its "codec"/"sound-dai" phandle instead.
*/
static struct device_node *q6hdmi_codec_of_node(struct snd_soc_pcm_runtime *rtd)
{
struct device_node *sound_np = rtd->card->dev->of_node;
struct device_node *link_np, *codec_np, *codec_of = NULL;
const char *link_name;

if (!sound_np || !rtd->dai_link->name)
return NULL;

for_each_child_of_node(sound_np, link_np) {
if (of_property_read_string(link_np, "link-name", &link_name))
continue;
if (strcmp(link_name, rtd->dai_link->name))
continue;

codec_np = of_get_child_by_name(link_np, "codec");
if (codec_np) {
codec_of = of_parse_phandle(codec_np, "sound-dai", 0);
of_node_put(codec_np);
}
of_node_put(link_np);
break;
}

return codec_of;
}

static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
struct audioreach_module_config *cfg = &dai_data->module_config[dai->id];
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct device_node *dp_np = q6hdmi_codec_of_node(rtd);
u32 display_ctrl_idx;
int channels = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
int ret;

Expand All @@ -130,6 +166,18 @@ static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
break;
}

cfg->has_display_ctrl_idx = false;
if (dp_np &&
!of_property_read_u32(dp_np, "radxa,display-controller-index", &display_ctrl_idx)) {
if (display_ctrl_idx > 1) {
of_node_put(dp_np);
return -EINVAL;
}
cfg->display_ctrl_idx = display_ctrl_idx;
cfg->has_display_ctrl_idx = true;
}
of_node_put(dp_np);

ret = q6dsp_get_channel_allocation(channels);
if (ret < 0)
return ret;
Expand Down
11 changes: 11 additions & 0 deletions sound/soc/qcom/sc8280xp.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ static struct snd_soc_dapm_widget qcs9100_dapm_widgets[] = {
SND_SOC_DAPM_SPK("DP0 Jack", NULL),
};

static const struct snd_soc_dapm_widget vmarc_q9075_dapm_widgets[] = {
SND_SOC_DAPM_SPK("DP0 Jack", NULL),
};

static const struct snd_soc_dapm_route qcs9100_dapm_routes[] = {
{"Speaker", NULL, "MI2S_PINCTRL"},
{"DMic", NULL, "MI2S_PINCTRL"},
Expand All @@ -70,6 +74,12 @@ static struct snd_soc_common qcs9100_priv_data = {
.num_dapm_routes = ARRAY_SIZE(qcs9100_dapm_routes),
};

static const struct snd_soc_common vmarc_q9075_priv_data = {
.driver_name = "sa8775p",
.dapm_widgets = vmarc_q9075_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(vmarc_q9075_dapm_widgets),
};

static struct snd_soc_common lemans_amr_priv_data = {
.driver_name = "sa8775p",
.dapm_widgets = sc8280xp_dapm_widgets,
Expand Down Expand Up @@ -341,6 +351,7 @@ static int sc8280xp_platform_probe(struct platform_device *pdev)
}

static const struct of_device_id snd_sc8280xp_dt_match[] = {
{.compatible = "radxa,vmarc-q9075-sndcard", .data = &vmarc_q9075_priv_data},
{.compatible = "qcom,qcm6490-idp-sndcard", .data = &qcm6490_priv_data},
{.compatible = "qcom,qcs615-sndcard", .data = &qcs615_priv_data},
{.compatible = "qcom,qcs6490-rb3gen2-sndcard", .data = &qcs6490_priv_data},
Expand Down