Merge "ARM: dts: msm8974: Update MPM mapping to bypass few GIC interrupts"
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index a77b5ff..6277054 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -4,23 +4,29 @@
Required properties:
- - compatible : "qcom,msm-pcm-dsp"
+ - compatible : "qti,msm-pcm-dsp"
- - qcom,msm-pcm-dsp-id : device node id
+ - qti,msm-pcm-dsp-id : device node id
* msm-pcm-low-latency
Required properties:
- - compatible : "qcom,msm-pcm-dsp"
+ - compatible : "qti,msm-pcm-dsp"
- - qcom,msm-pcm-dsp-id : device node id
+ - qti,msm-pcm-dsp-id : device node id
Optional properties
- - qcom,msm-pcm-low-latency : Flag indicating whether
+ - qti,msm-pcm-low-latency : Flag indicating whether
the device node is of type low latency.
+ - qti,latency-level : Flag indicating whether the device node
+ is of type regular low latency or ultra
+ low latency.
+ regular : regular low latency stream
+ ultra : ultra low latency stream
+
* msm-pcm-routing
Required properties:
@@ -226,16 +232,16 @@
Example:
- qcom,msm-pcm {
- compatible = "qcom,msm-pcm-dsp";
- qcom,msm-pcm-dsp-id = <0>;
+ qti,msm-pcm {
+ compatible = "qti,msm-pcm-dsp";
+ qti,msm-pcm-dsp-id = <0>;
};
- qcom,msm-pcm-low-latency {
- compatible = "qcom,msm-pcm-dsp";
- qcom,msm-pcm-dsp-id = <1>;
- qcom,msm-pcm-low-latency;
- };
+ qti,msm-pcm-low-latency {
+ compatible = "qti,msm-pcm-dsp";
+ qti,msm-pcm-dsp-id = <1>;
+ qti,msm-pcm-low-latency;
+ };
qcom,msm-pcm-routing {
compatible = "qcom,msm-pcm-routing";
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index fc00411..baa81cc 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -429,19 +429,20 @@
qcom,tapan-codec-9302;
};
- qcom,msm-pcm {
- compatible = "qcom,msm-pcm-dsp";
- qcom,msm-pcm-dsp-id = <0>;
+ qti,msm-pcm {
+ compatible = "qti,msm-pcm-dsp";
+ qti,msm-pcm-dsp-id = <0>;
};
qcom,msm-pcm-routing {
compatible = "qcom,msm-pcm-routing";
};
- qcom,msm-pcm-low-latency {
- compatible = "qcom,msm-pcm-dsp";
- qcom,msm-pcm-dsp-id = <1>;
- qcom,msm-pcm-low-latency;
+ qti,msm-pcm-low-latency {
+ compatible = "qti,msm-pcm-dsp";
+ qti,msm-pcm-dsp-id = <1>;
+ qti,msm-pcm-low-latency;
+ qti,latency-level = "regular";
};
qcom,msm-pcm-lpa {
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 94a9db0..03ef738 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -615,15 +615,16 @@
qcom,model = "msm8x10-snd-card";
};
- qcom,msm-pcm {
- compatible = "qcom,msm-pcm-dsp";
- qcom,msm-pcm-dsp-id = <0>;
+ qti,msm-pcm {
+ compatible = "qti,msm-pcm-dsp";
+ qti,msm-pcm-dsp-id = <0>;
};
- qcom,msm-pcm-low-latency {
- compatible = "qcom,msm-pcm-dsp";
- qcom,msm-pcm-dsp-id = <1>;
- qcom,msm-pcm-low-latency;
+ qti,msm-pcm-low-latency {
+ compatible = "qti,msm-pcm-dsp";
+ qti,msm-pcm-dsp-id = <1>;
+ qti,msm-pcm-low-latency;
+ qti,latency-level = "ultra";
};
qcom,msm-pcm-routing {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index b4a3e55..a912da8 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1628,15 +1628,16 @@
compatible = "qcom,msm-audio-ion";
};
- qcom,msm-pcm {
- compatible = "qcom,msm-pcm-dsp";
- qcom,msm-pcm-dsp-id = <0>;
+ qti,msm-pcm {
+ compatible = "qti,msm-pcm-dsp";
+ qti,msm-pcm-dsp-id = <0>;
};
- qcom,msm-pcm-low-latency {
- compatible = "qcom,msm-pcm-dsp";
- qcom,msm-pcm-dsp-id = <1>;
- qcom,msm-pcm-low-latency;
+ qti,msm-pcm-low-latency {
+ compatible = "qti,msm-pcm-dsp";
+ qti,msm-pcm-dsp-id = <1>;
+ qti,msm-pcm-low-latency;
+ qti,latency-level = "regular";
};
qcom,msm-pcm-routing {
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
index fa313bf..6b62391 100644
--- a/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-mtp.dts
@@ -22,5 +22,5 @@
};
&sdhc_1 {
- qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-on = <0x7 0x4 0x4>; /* 16mA, 10mA, 10mA */
};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 0e7baf1..dee1f68 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -686,9 +686,9 @@
qcom,adsp-state = <2>;
};
- qcom,msm-pcm {
- compatible = "qcom,msm-pcm-dsp";
- qcom,msm-pcm-dsp-id = <0>;
+ qti,msm-pcm {
+ compatible = "qti,msm-pcm-dsp";
+ qti,msm-pcm-dsp-id = <0>;
};
qcom,msm-pcm-routing {
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h b/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
index 0a1cdd4..42cf6f9 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/rtac.h
@@ -45,7 +45,7 @@
};
void rtac_add_adm_device(u32 port_id, u32 copp_id, u32 path_id, u32 popp_id);
-void rtac_remove_adm_device(u32 port_id);
+void rtac_remove_adm_device(u32 port_id, u32 copp_id);
void rtac_remove_popp_from_adm_devices(u32 popp_id);
void rtac_add_voice(u32 cvs_handle, u32 cvp_handle, u32 rx_afe_port,
u32 tx_afe_port, u32 session_id);
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index 7d8899e..efb87a9 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -1902,7 +1902,7 @@
pr_debug("thermal node%x\n", btm_channel_num);
chip->sensor[sen_idx].mode = THERMAL_DEVICE_DISABLED;
chip->sensor[sen_idx].thermal_node = true;
- snprintf(name, sizeof(name),
+ snprintf(name, sizeof(name), "%s",
chip->adc->adc_channels[sen_idx].name);
chip->sensor[sen_idx].meas_interval =
QPNP_ADC_TM_MEAS_INTERVAL;
diff --git a/drivers/video/msm/mdss/mdp3.h b/drivers/video/msm/mdss/mdp3.h
index 28997ec..f1f0455 100644
--- a/drivers/video/msm/mdss/mdp3.h
+++ b/drivers/video/msm/mdss/mdp3.h
@@ -26,6 +26,7 @@
#include "mdss_fb.h"
#define MDP_VSYNC_CLK_RATE 19200000
+#define KOFF_TIMEOUT msecs_to_jiffies(84)
enum {
MDP3_CLK_AHB,
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index a6fc20d..6fc6195 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -91,6 +91,36 @@
return bufq->count;
}
+void mdp3_ctrl_notifier_register(struct mdp3_session_data *ses,
+ struct notifier_block *notifier)
+{
+ blocking_notifier_chain_register(&ses->notifier_head, notifier);
+}
+
+void mdp3_ctrl_notifier_unregister(struct mdp3_session_data *ses,
+ struct notifier_block *notifier)
+{
+ blocking_notifier_chain_unregister(&ses->notifier_head, notifier);
+}
+
+int mdp3_ctrl_notify(struct mdp3_session_data *ses, int event)
+{
+ return blocking_notifier_call_chain(&ses->notifier_head, event, ses);
+}
+
+static void mdp3_dispatch_dma_done(struct work_struct *work)
+{
+ struct mdp3_session_data *session;
+
+ pr_debug("%s\n", __func__);
+ session = container_of(work, struct mdp3_session_data,
+ dma_done_work);
+ if (!session)
+ return;
+
+ mdp3_ctrl_notify(session, MDP_NOTIFY_FRAME_DONE);
+}
+
static void mdp3_dispatch_clk_off(struct work_struct *work)
{
struct mdp3_session_data *session;
@@ -121,6 +151,12 @@
sysfs_notify_dirent(session->vsync_event_sd);
}
+void dma_done_notify_handler(void *arg)
+{
+ struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
+ schedule_work(&session->dma_done_work);
+}
+
void vsync_count_down(void *arg)
{
struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
@@ -140,8 +176,8 @@
static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable)
{
struct mdp3_session_data *mdp3_session;
- struct mdp3_vsync_notification vsync_client;
- struct mdp3_vsync_notification *arg = NULL;
+ struct mdp3_notification vsync_client;
+ struct mdp3_notification *arg = NULL;
pr_debug("mdp3_ctrl_vsync_enable =%d\n", enable);
mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
@@ -464,6 +500,7 @@
int frame_rate = mfd->panel_info->mipi.frame_rate;
int vbp, vfp, vspw;
int vtotal, vporch;
+ struct mdp3_notification dma_done_callback;
vbp = panel_info->lcdc.v_back_porch;
vfp = panel_info->lcdc.v_front_porch;
@@ -499,6 +536,13 @@
rc = dma->dma_config(dma, &sourceConfig, &outputConfig);
else
rc = -EINVAL;
+
+ if (outputConfig.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
+ dma_done_callback.handler = dma_done_notify_handler;
+ dma_done_callback.arg = mfd->mdp.private1;
+ dma->dma_done_notifier(dma, &dma_done_callback);
+ }
+
return rc;
}
@@ -527,6 +571,8 @@
}
mdp3_batfet_ctrl(true);
+ mdp3_ctrl_notifier_register(mdp3_session,
+ &mdp3_session->mfd->mdp_sync_pt_data.notifier);
rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
if (rc) {
@@ -658,6 +704,8 @@
if (rc)
pr_err("fail to dettach MDP DMA SMMU\n");
+ mdp3_ctrl_notifier_unregister(mdp3_session,
+ &mdp3_session->mfd->mdp_sync_pt_data.notifier);
mdp3_batfet_ctrl(false);
mdp3_session->vsync_enabled = 0;
atomic_set(&mdp3_session->vsync_countdown, 0);
@@ -677,7 +725,7 @@
struct mdp3_session_data *mdp3_session;
struct mdp3_dma *mdp3_dma;
struct mdss_panel_data *panel;
- struct mdp3_vsync_notification vsync_client;
+ struct mdp3_notification vsync_client;
pr_debug("mdp3_ctrl_reset_cmd\n");
mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
@@ -727,7 +775,7 @@
struct mdp3_session_data *mdp3_session;
struct mdp3_dma *mdp3_dma;
struct mdss_panel_data *panel;
- struct mdp3_vsync_notification vsync_client;
+ struct mdp3_notification vsync_client;
pr_debug("mdp3_ctrl_reset\n");
mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
@@ -969,13 +1017,27 @@
return -EPERM;
}
+ mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN);
data = mdp3_bufq_pop(&mdp3_session->bufq_in);
if (data) {
mdp3_ctrl_reset_countdown(mdp3_session, mfd);
mdp3_ctrl_clk_enable(mfd, 1);
- mdp3_session->dma->update(mdp3_session->dma,
+ rc = mdp3_session->dma->update(mdp3_session->dma,
(void *)data->addr,
mdp3_session->intf);
+ /* This is for the previous frame */
+ if (rc < 0) {
+ mdp3_ctrl_notify(mdp3_session,
+ MDP_NOTIFY_FRAME_TIMEOUT);
+ } else {
+ if (mdp3_ctrl_get_intf_type(mfd) ==
+ MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) {
+ mdp3_ctrl_notify(mdp3_session,
+ MDP_NOTIFY_FRAME_DONE);
+ }
+ }
+
+ mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_FLUSHED);
mdp3_bufq_push(&mdp3_session->bufq_out, data);
}
@@ -998,7 +1060,7 @@
mdss_fb_update_notify_update(mfd);
- return rc;
+ return 0;
}
static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd)
@@ -1008,6 +1070,7 @@
u32 offset;
int bpp;
struct mdss_panel_info *panel_info = mfd->panel_info;
+ int rc;
pr_debug("mdp3_ctrl_pan_display\n");
if (!mfd || !mfd->mdp.private1)
@@ -1044,10 +1107,23 @@
if (mfd->fbi->screen_base) {
mdp3_ctrl_reset_countdown(mdp3_session, mfd);
+ mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN);
mdp3_ctrl_clk_enable(mfd, 1);
- mdp3_session->dma->update(mdp3_session->dma,
- (void *)mfd->iova + offset,
+ rc = mdp3_session->dma->update(mdp3_session->dma,
+ (void *)(mfd->iova + offset),
mdp3_session->intf);
+ /* This is for the previous frame */
+ if (rc < 0) {
+ mdp3_ctrl_notify(mdp3_session,
+ MDP_NOTIFY_FRAME_TIMEOUT);
+ } else {
+ if (mdp3_ctrl_get_intf_type(mfd) ==
+ MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) {
+ mdp3_ctrl_notify(mdp3_session,
+ MDP_NOTIFY_FRAME_DONE);
+ }
+ }
+ mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_FLUSHED);
} else {
pr_debug("mdp3_ctrl_pan_display no memory, stop interface");
mdp3_clk_enable(1, 0);
@@ -1658,6 +1734,7 @@
memset(mdp3_session, 0, sizeof(struct mdp3_session_data));
mutex_init(&mdp3_session->lock);
INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off);
+ INIT_WORK(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done);
atomic_set(&mdp3_session->vsync_countdown, 0);
mutex_init(&mdp3_session->histo_lock);
mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL);
@@ -1693,6 +1770,7 @@
mdp3_bufq_init(&mdp3_session->bufq_out);
mdp3_session->histo_status = 0;
mdp3_session->lut_sel = 0;
+ BLOCKING_INIT_NOTIFIER_HEAD(&mdp3_session->notifier_head);
init_timer(&mdp3_session->vsync_timer);
mdp3_session->vsync_timer.function = mdp3_vsync_timer_func;
@@ -1721,8 +1799,11 @@
kobject_uevent(&dev->kobj, KOBJ_ADD);
pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");
- if (mdp3_get_cont_spash_en())
+ if (mdp3_get_cont_spash_en()) {
mdp3_session->clk_on = 1;
+ mdp3_ctrl_notifier_register(mdp3_session,
+ &mdp3_session->mfd->mdp_sync_pt_data.notifier);
+ }
if (splash_mismatch) {
pr_err("splash memory mismatch, stop splash\n");
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.h b/drivers/video/msm/mdss/mdp3_ctrl.h
index f2484ef..cfad1d3 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.h
+++ b/drivers/video/msm/mdss/mdp3_ctrl.h
@@ -49,6 +49,7 @@
struct mdp3_buffer_queue bufq_in;
struct mdp3_buffer_queue bufq_out;
struct work_struct clk_off_work;
+ struct work_struct dma_done_work;
int histo_status;
struct mutex histo_lock;
int lut_sel;
@@ -56,6 +57,7 @@
bool vsync_before_commit;
bool first_commit;
int clk_on;
+ struct blocking_notifier_head notifier_head;
int vsync_enabled;
atomic_t vsync_countdown; /* Used to count down */
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
index ae7598f..5cae2de 100644
--- a/drivers/video/msm/mdss/mdp3_dma.c
+++ b/drivers/video/msm/mdss/mdp3_dma.c
@@ -27,7 +27,7 @@
static void mdp3_vsync_intr_handler(int type, void *arg)
{
struct mdp3_dma *dma = (struct mdp3_dma *)arg;
- struct mdp3_vsync_notification vsync_client;
+ struct mdp3_notification vsync_client;
unsigned int wait_for_next_vs;
pr_debug("mdp3_vsync_intr_handler\n");
@@ -49,10 +49,16 @@
static void mdp3_dma_done_intr_handler(int type, void *arg)
{
struct mdp3_dma *dma = (struct mdp3_dma *)arg;
+ struct mdp3_notification dma_client;
pr_debug("mdp3_dma_done_intr_handler\n");
+ spin_lock(&dma->dma_lock);
+ dma_client = dma->dma_notifier_client;
complete(&dma->dma_comp);
+ spin_unlock(&dma->dma_lock);
mdp3_irq_disable_nosync(type);
+ if (dma_client.handler)
+ dma_client.handler(dma_client.arg);
}
static void mdp3_hist_done_intr_handler(int type, void *arg)
@@ -195,7 +201,7 @@
}
static void mdp3_dma_vsync_enable(struct mdp3_dma *dma,
- struct mdp3_vsync_notification *vsync_client)
+ struct mdp3_notification *vsync_client)
{
unsigned long flag;
int updated = 0;
@@ -226,6 +232,21 @@
}
}
+static void mdp3_dma_done_notifier(struct mdp3_dma *dma,
+ struct mdp3_notification *dma_client)
+{
+ unsigned long flag;
+
+ spin_lock_irqsave(&dma->dma_lock, flag);
+ if (dma_client) {
+ dma->dma_notifier_client = *dma_client;
+ } else {
+ dma->dma_notifier_client.handler = NULL;
+ dma->dma_notifier_client.arg = NULL;
+ }
+ spin_unlock_irqrestore(&dma->dma_lock, flag);
+}
+
static void mdp3_dma_clk_auto_gating(struct mdp3_dma *dma, int enable)
{
u32 cgc;
@@ -552,13 +573,20 @@
{
unsigned long flag;
int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC;
+ int rc = 0;
pr_debug("mdp3_dmap_update\n");
if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
cb_type = MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
- if (intf->active)
- wait_for_completion_killable(&dma->dma_comp);
+ if (intf->active) {
+ rc = wait_for_completion_timeout(&dma->dma_comp,
+ KOFF_TIMEOUT);
+ if (rc <= 0) {
+ WARN(1, "cmd kickoff timed out (%d)\n", rc);
+ rc = -1;
+ }
+ }
}
spin_lock_irqsave(&dma->dma_lock, flag);
MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)buf);
@@ -581,10 +609,14 @@
mdp3_dma_callback_enable(dma, cb_type);
pr_debug("mdp3_dmap_update wait for vsync_comp in\n");
- if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO)
- wait_for_completion_killable(&dma->vsync_comp);
+ if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) {
+ rc = wait_for_completion_timeout(&dma->vsync_comp,
+ KOFF_TIMEOUT);
+ if (rc <= 0)
+ rc = -1;
+ }
pr_debug("mdp3_dmap_update wait for vsync_comp out\n");
- return 0;
+ return rc;
}
static int mdp3_dmas_update(struct mdp3_dma *dma, void *buf,
@@ -878,6 +910,7 @@
dma->get_histo = mdp3_dmap_histo_get;
dma->histo_op = mdp3_dmap_histo_op;
dma->vsync_enable = mdp3_dma_vsync_enable;
+ dma->dma_done_notifier = mdp3_dma_done_notifier;
dma->start = mdp3_dma_start;
dma->stop = mdp3_dma_stop;
dma->config_stride = mdp3_dma_stride_config;
diff --git a/drivers/video/msm/mdss/mdp3_dma.h b/drivers/video/msm/mdss/mdp3_dma.h
index 6ad4c79..04955d4 100644
--- a/drivers/video/msm/mdss/mdp3_dma.h
+++ b/drivers/video/msm/mdss/mdp3_dma.h
@@ -14,6 +14,7 @@
#ifndef MDP3_DMA_H
#define MDP3_DMA_H
+#include <linux/notifier.h>
#include <linux/sched.h>
#define MDP_HISTOGRAM_BL_SCALE_MAX 1024
@@ -227,7 +228,7 @@
u32 extra[2];
};
-struct mdp3_vsync_notification {
+struct mdp3_notification {
void (*handler)(void *arg);
void *arg;
};
@@ -245,7 +246,8 @@
struct completion vsync_comp;
struct completion dma_comp;
struct completion histo_comp;
- struct mdp3_vsync_notification vsync_client;
+ struct mdp3_notification vsync_client;
+ struct mdp3_notification dma_notifier_client;
struct mdp3_dma_output_config output_config;
struct mdp3_dma_source source_config;
@@ -291,7 +293,10 @@
void (*config_stride)(struct mdp3_dma *dma, int stride);
void (*vsync_enable)(struct mdp3_dma *dma,
- struct mdp3_vsync_notification *vsync_client);
+ struct mdp3_notification *vsync_client);
+
+ void (*dma_done_notifier)(struct mdp3_dma *dma,
+ struct mdp3_notification *dma_client);
};
struct mdp3_video_intf_cfg {
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 3daed18..555974b 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -1734,11 +1734,13 @@
if (mdss_pp_res == NULL) {
pr_err("%s mdss_pp_res allocation failed!", __func__);
ret = -ENOMEM;
- }
-
- for (i = 0; i < MDSS_MDP_MAX_DSPP; i++) {
- mutex_init(&mdss_pp_res->dspp_hist[i].hist_mutex);
- spin_lock_init(&mdss_pp_res->dspp_hist[i].hist_lock);
+ } else {
+ for (i = 0; i < MDSS_MDP_MAX_DSPP; i++) {
+ mutex_init(
+ &mdss_pp_res->dspp_hist[i].hist_mutex);
+ spin_lock_init(
+ &mdss_pp_res->dspp_hist[i].hist_lock);
+ }
}
}
if (mdata) {
diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h
index 6f121b3..5941f71 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -31,7 +31,7 @@
int srs_trumedia_open(int port_id, int srs_tech_id, void *srs_params);
int adm_open(int port, int path, int rate, int mode, int topology,
- bool perf_mode, uint16_t bits_per_sample);
+ int perf_mode, uint16_t bits_per_sample);
int adm_get_params(int port_id, uint32_t module_id, uint32_t param_id,
uint32_t params_length, char *params);
@@ -40,7 +40,7 @@
uint32_t params_length);
int adm_multi_ch_copp_open(int port, int path, int rate, int mode,
- int topology, bool perf_mode, uint16_t bits_per_sample);
+ int topology, int perf_mode, uint16_t bits_per_sample);
int adm_unmap_cal_blocks(void);
@@ -53,10 +53,10 @@
int adm_memory_unmap_regions(int port_id);
-int adm_close(int port, bool perf_mode);
+int adm_close(int port, int perf_mode);
int adm_matrix_map(int session_id, int path, int num_copps,
- unsigned int *port_id, int copp_id, bool perf_mode);
+ unsigned int *port_id, int copp_id, int perf_mode);
int adm_connect_afe_port(int mode, int session_id, int port_id);
@@ -64,6 +64,8 @@
int adm_get_copp_id(int port_id);
+int adm_get_lowlatency_copp_id(int port_id);
+
void adm_set_multi_ch_map(char *channel_map);
void adm_get_multi_ch_map(char *channel_map);
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index b00cfc9..a78c333 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -175,7 +175,7 @@
struct audio_port_data port[2];
wait_queue_head_t cmd_wait;
wait_queue_head_t time_wait;
- bool perf_mode;
+ int perf_mode;
int stream_id;
/* audio cache operations fptr*/
int (*fptr_cache_ops)(struct audio_buffer *abuff, int cache_op);
diff --git a/include/sound/q6audio-v2.h b/include/sound/q6audio-v2.h
index fd6a490..8ac835c 100644
--- a/include/sound/q6audio-v2.h
+++ b/include/sound/q6audio-v2.h
@@ -15,6 +15,13 @@
#include <mach/qdsp6v2/apr.h>
+enum {
+ LEGACY_PCM_MODE = 0,
+ LOW_LATENCY_PCM_MODE,
+ ULTRA_LOW_LATENCY_PCM_MODE,
+};
+
+
int q6audio_get_port_index(u16 port_id);
int q6audio_convert_virtual_to_portid(u16 port_id);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index fa8a793..e174693 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -184,6 +184,36 @@
return ret;
}
+#ifdef ENABLE_VMALLOC_SAVING
+int is_vmalloc_addr(const void *x)
+{
+ struct rb_node *n;
+ struct vmap_area *va;
+ int ret = 0;
+
+ spin_lock(&vmap_area_lock);
+
+ for (n = rb_first(vmap_area_root); n; rb_next(n)) {
+ va = rb_entry(n, struct vmap_area, rb_node);
+ if (x >= va->va_start && x < va->va_end) {
+ ret = 1;
+ break;
+ }
+ }
+
+ spin_unlock(&vmap_area_lock);
+ return ret;
+}
+#else
+int is_vmalloc_addr(const void *x)
+{
+ unsigned long addr = (unsigned long)x;
+
+ return addr >= VMALLOC_START && addr < VMALLOC_END;
+}
+#endif
+EXPORT_SYMBOL(is_vmalloc_addr);
+
int is_vmalloc_or_module_addr(const void *x)
{
/*
@@ -272,47 +302,6 @@
static unsigned long vmap_area_pcpu_hole;
-#ifdef CONFIG_ENABLE_VMALLOC_SAVING
-int is_vmalloc_addr(const void *x)
-{
- struct vmap_area *va;
- int ret = 0;
-
- spin_lock(&vmap_area_lock);
- list_for_each_entry(va, &vmap_area_list, list) {
- if (va->flags & (VM_LAZY_FREE | VM_LAZY_FREEING))
- continue;
-
- if (!(va->flags & VM_VM_AREA))
- continue;
-
- if (va->vm == NULL)
- continue;
-
- if (va->vm->flags & VM_LOWMEM)
- continue;
-
- if ((unsigned long)x >= va->va_start &&
- (unsigned long)x < va->va_end) {
- ret = 1;
- break;
- }
- }
- spin_unlock(&vmap_area_lock);
- return ret;
-}
-#else
-int is_vmalloc_addr(const void *x)
-{
- unsigned long addr = (unsigned long)x;
-
- return addr >= VMALLOC_START && addr < VMALLOC_END;
-}
-#endif
-EXPORT_SYMBOL(is_vmalloc_addr);
-
-
-
static struct vmap_area *__find_vmap_area(unsigned long addr)
{
struct rb_node *n = vmap_area_root.rb_node;
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index bddb720..b094741 100755
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1510,8 +1510,8 @@
if (wiphy_idx_valid(reg_request->wiphy_idx))
wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
- if (reg_initiator == NL80211_REGDOM_SET_BY_DRIVER &&
- !wiphy) {
+ if ((reg_initiator == NL80211_REGDOM_SET_BY_DRIVER ||
+ reg_initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) && !wiphy) {
kfree(reg_request);
return;
}
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index c62f875..f874c43 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -3404,6 +3404,7 @@
TAIKO_A_TX_7_MBHC_EN, 0x80, 00);
ret |= taiko_codec_enable_anc(w, kcontrol, event);
}
+ break;
case SND_SOC_DAPM_POST_PMD:
ret = taiko_hph_pa_event(w, kcontrol, event);
break;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index f25f746..3ddc3e0 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -25,6 +25,7 @@
#include <sound/pcm.h>
#include <sound/initval.h>
#include <sound/control.h>
+#include <sound/q6audio-v2.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
#include <linux/msm_audio_ion.h>
@@ -916,11 +917,12 @@
int rc;
int id;
struct msm_plat_data *pdata;
+ const char *latency_level;
rc = of_property_read_u32(pdev->dev.of_node,
- "qcom,msm-pcm-dsp-id", &id);
+ "qti,msm-pcm-dsp-id", &id);
if (rc) {
- dev_err(&pdev->dev, "%s: qcom,msm-pcm-dsp-id missing in DT node\n",
+ dev_err(&pdev->dev, "%s: qti,msm-pcm-dsp-id missing in DT node\n",
__func__);
return rc;
}
@@ -932,10 +934,17 @@
}
if (of_property_read_bool(pdev->dev.of_node,
- "qcom,msm-pcm-low-latency"))
- pdata->perf_mode = 1;
- else
- pdata->perf_mode = 0;
+ "qti,msm-pcm-low-latency")) {
+
+ pdata->perf_mode = LOW_LATENCY_PCM_MODE;
+ rc = of_property_read_string(pdev->dev.of_node,
+ "qti,latency-level", &latency_level);
+ if (!rc) {
+ if (!strcmp(latency_level, "ultra"))
+ pdata->perf_mode = ULTRA_LOW_LATENCY_PCM_MODE;
+ }
+ } else
+ pdata->perf_mode = LEGACY_PCM_MODE;
dev_set_drvdata(&pdev->dev, pdata);
@@ -957,7 +966,7 @@
return 0;
}
static const struct of_device_id msm_pcm_dt_match[] = {
- {.compatible = "qcom,msm-pcm-dsp"},
+ {.compatible = "qti,msm-pcm-dsp"},
{}
};
MODULE_DEVICE_TABLE(of, msm_pcm_dt_match);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 711291da..91c0744 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -290,7 +290,7 @@
/* Track performance mode of all front-end multimedia sessions.
* Performance mode is only valid when session is valid.
*/
-static bool fe_dai_perf_mode[MSM_FRONTEND_DAI_MM_SIZE][2];
+static int fe_dai_perf_mode[MSM_FRONTEND_DAI_MM_SIZE][2];
static uint8_t is_be_dai_extproc(int be_dai)
{
@@ -303,7 +303,7 @@
}
static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
- int path_type, bool perf_mode)
+ int path_type, int perf_mode)
{
int i, port_type;
struct route_payload payload;
@@ -365,7 +365,7 @@
mutex_unlock(&routing_lock);
}
-void msm_pcm_routing_reg_phy_stream(int fedai_id, bool perf_mode,
+void msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
int dspst_id, int stream_type)
{
int i, session_type, path_type, port_type, port_id, topology;
@@ -437,7 +437,7 @@
port_id = srs_port_id = msm_bedais[i].port_id;
srs_send_params(srs_port_id, 1, 0);
if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
- (!perf_mode))
+ (perf_mode == LEGACY_PCM_MODE))
if (dolby_dap_init(port_id,
msm_bedais[i].channel) < 0)
pr_err("%s: Err init dolby dap\n",
@@ -494,7 +494,8 @@
adm_close(msm_bedais[i].port_id,
fe_dai_perf_mode[fedai_id][session_type]);
if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
- (fe_dai_perf_mode[fedai_id][session_type] == false))
+ (fe_dai_perf_mode[fedai_id][session_type] ==
+ LEGACY_PCM_MODE))
dolby_dap_deinit(msm_bedais[i].port_id);
}
}
@@ -604,7 +605,8 @@
port_id = srs_port_id = msm_bedais[reg].port_id;
srs_send_params(srs_port_id, 1, 0);
if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
- (fe_dai_perf_mode[val][session_type] == false))
+ (fe_dai_perf_mode[val][session_type] ==
+ LEGACY_PCM_MODE))
if (dolby_dap_init(port_id, channels) < 0)
pr_err("%s: Err init dolby dap\n",
__func__);
@@ -621,7 +623,8 @@
adm_close(msm_bedais[reg].port_id,
fe_dai_perf_mode[val][session_type]);
if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
- (fe_dai_perf_mode[val][session_type] == false))
+ (fe_dai_perf_mode[val][session_type] ==
+ LEGACY_PCM_MODE))
dolby_dap_deinit(msm_bedais[reg].port_id);
msm_pcm_routing_build_matrix(val,
fdai->strm_id, path_type,
@@ -3960,7 +3963,8 @@
fe_dai_perf_mode[i][session_type]);
srs_port_id = -1;
if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
- (fe_dai_perf_mode[i][session_type] == false))
+ (fe_dai_perf_mode[i][session_type] ==
+ LEGACY_PCM_MODE))
dolby_dap_deinit(bedai->port_id);
}
}
@@ -4060,7 +4064,8 @@
port_id = srs_port_id = bedai->port_id;
srs_send_params(srs_port_id, 1, 0);
if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology) &&
- (fe_dai_perf_mode[i][session_type] == false))
+ (fe_dai_perf_mode[i][session_type] ==
+ LEGACY_PCM_MODE))
if (dolby_dap_init(port_id, channels) < 0)
pr_err("%s: Err init dolby dap\n",
__func__);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 4f7c4e3..54f5e4a 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -143,7 +143,7 @@
* dspst_id: DSP audio stream ID
* stream_type: playback or capture
*/
-void msm_pcm_routing_reg_phy_stream(int fedai_id, bool perf_mode, int dspst_id,
+void msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode, int dspst_id,
int stream_type);
void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id,
int stream_type);
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 6cb7ce1..54b1263 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -702,7 +702,8 @@
return;
}
-static int send_adm_cal_block(int port_id, struct acdb_cal_block *aud_cal)
+static int send_adm_cal_block(int port_id, struct acdb_cal_block *aud_cal,
+ int perf_mode)
{
s32 result = 0;
struct adm_cmd_set_pp_params_v5 adm_params;
@@ -731,7 +732,14 @@
adm_params.hdr.src_port = port_id;
adm_params.hdr.dest_svc = APR_SVC_ADM;
adm_params.hdr.dest_domain = APR_DOMAIN_ADSP;
- adm_params.hdr.dest_port = atomic_read(&this_adm.copp_id[index]);
+
+ if (perf_mode == LEGACY_PCM_MODE)
+ adm_params.hdr.dest_port =
+ atomic_read(&this_adm.copp_id[index]);
+ else
+ adm_params.hdr.dest_port =
+ atomic_read(&this_adm.copp_low_latency_id[index]);
+
adm_params.hdr.token = port_id;
adm_params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
adm_params.payload_addr_lsw = aud_cal->cal_paddr;
@@ -767,7 +775,7 @@
return result;
}
-static void send_adm_cal(int port_id, int path)
+static void send_adm_cal(int port_id, int path, int perf_mode)
{
int result = 0;
s32 acdb_path;
@@ -808,7 +816,7 @@
}
}
- if (!send_adm_cal_block(port_id, &aud_cal))
+ if (!send_adm_cal_block(port_id, &aud_cal, perf_mode))
pr_debug("%s: Audproc cal sent for port id: %#x, path %d\n",
__func__, port_id, acdb_path);
else
@@ -842,7 +850,7 @@
}
}
- if (!send_adm_cal_block(port_id, &aud_cal))
+ if (!send_adm_cal_block(port_id, &aud_cal, perf_mode))
pr_debug("%s: Audvol cal sent for port id: %#x, path %d\n",
__func__, port_id, acdb_path);
else
@@ -1048,7 +1056,7 @@
}
int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
- bool perf_mode, uint16_t bits_per_sample)
+ int perf_mode, uint16_t bits_per_sample)
{
struct adm_cmd_device_open_v5 open;
int ret = 0;
@@ -1079,7 +1087,7 @@
rtac_set_adm_handle(this_adm.apr);
}
- if (!perf_mode) {
+ if (perf_mode == LEGACY_PCM_MODE) {
atomic_set(&this_adm.copp_perf_mode[index], 0);
send_adm_custom_topology(port_id);
} else {
@@ -1087,8 +1095,9 @@
}
/* Create a COPP if port id are not enabled */
- if ((!perf_mode && (atomic_read(&this_adm.copp_cnt[index]) == 0)) ||
- (perf_mode &&
+ if ((perf_mode == LEGACY_PCM_MODE &&
+ (atomic_read(&this_adm.copp_cnt[index]) == 0)) ||
+ (perf_mode != LEGACY_PCM_MODE &&
(atomic_read(&this_adm.copp_low_latency_cnt[index]) == 0))) {
pr_debug("%s:opening ADM: perf_mode: %d\n", __func__,
perf_mode);
@@ -1103,12 +1112,12 @@
open.hdr.dest_port = tmp_port;
open.hdr.token = port_id;
open.hdr.opcode = ADM_CMD_DEVICE_OPEN_V5;
- open.flags = 0x00;
- if (perf_mode) {
- open.flags |= ADM_ULTRA_LOW_LATENCY_DEVICE_SESSION;
- } else {
- open.flags |= ADM_LEGACY_DEVICE_SESSION;
- }
+ if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE)
+ open.flags = ADM_ULTRA_LOW_LATENCY_DEVICE_SESSION;
+ else if (perf_mode == LOW_LATENCY_PCM_MODE)
+ open.flags = ADM_LOW_LATENCY_DEVICE_SESSION;
+ else
+ open.flags = ADM_LEGACY_DEVICE_SESSION;
open.mode_of_operation = path;
open.endpoint_id_1 = tmp_port;
@@ -1125,7 +1134,7 @@
(open.topology_id == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY))
rate = 16000;
- if (perf_mode) {
+ if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) {
open.topology_id = NULL_COPP_TOPOLOGY;
rate = ULL_SUPPORTED_SAMPLE_RATE;
if(channel_mode > ULL_MAX_SUPPORTED_CHANNEL)
@@ -1133,7 +1142,8 @@
}
open.dev_num_channel = channel_mode & 0x00FF;
open.bit_width = bits_per_sample;
- WARN_ON(perf_mode && (rate != 48000));
+ WARN_ON(perf_mode == ULTRA_LOW_LATENCY_PCM_MODE &&
+ (rate != 48000));
open.sample_rate = rate;
memset(open.dev_channel_mapping, 0, 8);
@@ -1208,7 +1218,8 @@
goto fail_cmd;
}
}
- if (perf_mode) {
+ if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+ perf_mode == LOW_LATENCY_PCM_MODE) {
atomic_inc(&this_adm.copp_low_latency_cnt[index]);
pr_debug("%s: index: %d coppid: %d", __func__, index,
atomic_read(&this_adm.copp_low_latency_id[index]));
@@ -1225,7 +1236,7 @@
}
int adm_multi_ch_copp_open(int port_id, int path, int rate, int channel_mode,
- int topology, bool perf_mode, uint16_t bits_per_sample)
+ int topology, int perf_mode, uint16_t bits_per_sample)
{
int ret = 0;
@@ -1236,7 +1247,7 @@
}
int adm_matrix_map(int session_id, int path, int num_copps,
- unsigned int *port_id, int copp_id, bool perf_mode)
+ unsigned int *port_id, int copp_id, int perf_mode)
{
struct adm_cmd_matrix_map_routings_v5 *route;
struct adm_session_map_node_v5 *node;
@@ -1275,7 +1286,8 @@
route->hdr.src_port = copp_id;
route->hdr.dest_svc = APR_SVC_ADM;
route->hdr.dest_domain = APR_DOMAIN_ADSP;
- if (perf_mode) {
+ if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+ perf_mode == LOW_LATENCY_PCM_MODE) {
route->hdr.dest_port =
atomic_read(&this_adm.copp_low_latency_id[index]);
} else {
@@ -1313,7 +1325,8 @@
if (tmp >= 0 && tmp < AFE_MAX_PORTS) {
- if (perf_mode)
+ if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+ perf_mode == LOW_LATENCY_PCM_MODE)
copps_list[i] =
atomic_read(&this_adm.copp_low_latency_id[tmp]);
else
@@ -1323,8 +1336,7 @@
else
continue;
pr_debug("%s: port_id[%#x]: %d, index: %d act coppid[0x%x]\n",
- __func__, i, port_id[i], tmp,
- atomic_read(&this_adm.copp_id[tmp]));
+ __func__, i, port_id[i], tmp, copps_list[i]);
}
atomic_set(&this_adm.copp_stat[index], 0);
@@ -1344,25 +1356,31 @@
ret = -EINVAL;
goto fail_cmd;
}
- if (!perf_mode) {
+
+ if (perf_mode != ULTRA_LOW_LATENCY_PCM_MODE) {
for (i = 0; i < num_copps; i++)
- send_adm_cal(port_id[i], path);
+ send_adm_cal(port_id[i], path, perf_mode);
for (i = 0; i < num_copps; i++) {
- int tmp;
+ int tmp, copp_id;
tmp = afe_get_port_index(port_id[i]);
if (tmp >= 0 && tmp < AFE_MAX_PORTS) {
+ if (perf_mode == LEGACY_PCM_MODE)
+ copp_id = atomic_read(
+ &this_adm.copp_id[tmp]);
+ else
+ copp_id = atomic_read(
+ &this_adm.copp_low_latency_id[tmp]);
rtac_add_adm_device(port_id[i],
- atomic_read(&this_adm.copp_id[tmp]),
- path, session_id);
- pr_debug("%s, copp_id: %d\n", __func__,
- atomic_read(&this_adm.copp_id[tmp]));
- } else {
+ copp_id, path, session_id);
+ pr_debug("%s, copp_id: %d\n",
+ __func__, copp_id);
+ } else
pr_debug("%s: Invalid port index %d",
- __func__, tmp);
- }
+ __func__, tmp);
}
}
+
fail_cmd:
kfree(matrix_map);
return ret;
@@ -1514,8 +1532,26 @@
return ret;
}
+#ifdef CONFIG_RTAC
int adm_get_copp_id(int port_index)
{
+ int copp_id;
+ pr_debug("%s\n", __func__);
+
+ if (port_index < 0) {
+ pr_err("%s: invalid port_id = %d\n", __func__, port_index);
+ return -EINVAL;
+ }
+
+ copp_id = atomic_read(&this_adm.copp_id[port_index]);
+ if (copp_id == RESET_COPP_ID)
+ copp_id = atomic_read(
+ &this_adm.copp_low_latency_id[port_index]);
+ return copp_id;
+}
+
+int adm_get_lowlatency_copp_id(int port_index)
+{
pr_debug("%s\n", __func__);
if (port_index < 0) {
@@ -1523,8 +1559,19 @@
return -EINVAL;
}
- return atomic_read(&this_adm.copp_id[port_index]);
+ return atomic_read(&this_adm.copp_low_latency_id[port_index]);
}
+#else
+int adm_get_copp_id(int port_index)
+{
+ return -EINVAL;
+}
+
+int adm_get_lowlatency_copp_id(int port_index)
+{
+ return -EINVAL;
+}
+#endif /* #ifdef CONFIG_RTAC */
void adm_ec_ref_rx_id(int port_id)
{
@@ -1532,12 +1579,13 @@
pr_debug("%s ec_ref_rx:%d", __func__, this_adm.ec_ref_rx);
}
-int adm_close(int port_id, bool perf_mode)
+int adm_close(int port_id, int perf_mode)
{
struct apr_hdr close;
int ret = 0;
int index = 0;
+ int copp_id = RESET_COPP_ID;
port_id = q6audio_convert_virtual_to_portid(port_id);
@@ -1548,7 +1596,8 @@
pr_debug("%s port_id=%#x index %d perf_mode: %d\n", __func__, port_id,
index, perf_mode);
- if (perf_mode) {
+ if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+ perf_mode == LOW_LATENCY_PCM_MODE) {
if (!(atomic_read(&this_adm.copp_low_latency_cnt[index]))) {
pr_err("%s: copp count for port[%#x]is 0\n", __func__,
port_id);
@@ -1563,8 +1612,9 @@
}
atomic_dec(&this_adm.copp_cnt[index]);
}
- if ((!perf_mode && !(atomic_read(&this_adm.copp_cnt[index]))) ||
- (perf_mode &&
+ if ((perf_mode == LEGACY_PCM_MODE &&
+ !(atomic_read(&this_adm.copp_cnt[index]))) ||
+ ((perf_mode != LEGACY_PCM_MODE) &&
!(atomic_read(&this_adm.copp_low_latency_cnt[index])))) {
pr_debug("%s:Closing ADM: perf_mode: %d\n", __func__,
@@ -1577,7 +1627,8 @@
close.src_port = port_id;
close.dest_svc = APR_SVC_ADM;
close.dest_domain = APR_DOMAIN_ADSP;
- if (perf_mode)
+ if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+ perf_mode == LOW_LATENCY_PCM_MODE)
close.dest_port =
atomic_read(&this_adm.copp_low_latency_id[index]);
else
@@ -1587,18 +1638,23 @@
atomic_set(&this_adm.copp_stat[index], 0);
- if (perf_mode) {
+ if (perf_mode == ULTRA_LOW_LATENCY_PCM_MODE ||
+ perf_mode == LOW_LATENCY_PCM_MODE) {
+ copp_id = atomic_read(
+ &this_adm.copp_low_latency_id[index]);
pr_debug("%s:coppid %d portid=%#x index=%d coppcnt=%d\n",
- __func__,
- atomic_read(&this_adm.copp_low_latency_id[index]),
- port_id, index,
- atomic_read(&this_adm.copp_low_latency_cnt[index]));
+ __func__,
+ copp_id,
+ port_id, index,
+ atomic_read(
+ &this_adm.copp_low_latency_cnt[index]));
atomic_set(&this_adm.copp_low_latency_id[index],
RESET_COPP_ID);
} else {
+ copp_id = atomic_read(&this_adm.copp_id[index]);
pr_debug("%s:coppid %d portid=%#x index=%d coppcnt=%d\n",
__func__,
- atomic_read(&this_adm.copp_id[index]),
+ copp_id,
port_id, index,
atomic_read(&this_adm.copp_cnt[index]));
atomic_set(&this_adm.copp_id[index],
@@ -1623,9 +1679,9 @@
}
}
- if (!perf_mode) {
+ if (perf_mode != ULTRA_LOW_LATENCY_PCM_MODE) {
pr_debug("%s: remove adm device from rtac\n", __func__);
- rtac_remove_adm_device(port_id);
+ rtac_remove_adm_device(port_id, copp_id);
}
fail_cmd:
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 631e9bd..24f5f3b 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -39,6 +39,7 @@
#include <sound/apr_audio-v2.h>
#include <sound/q6asm-v2.h>
+#include <sound/q6audio-v2.h>
#include "audio_acdb.h"
@@ -354,7 +355,7 @@
session[ac->session] = 0;
mutex_unlock(&session_lock);
ac->session = 0;
- ac->perf_mode = 0;
+ ac->perf_mode = LEGACY_PCM_MODE;
ac->fptr_cache_ops = NULL;
return;
}
@@ -810,7 +811,7 @@
ac->cb = cb;
ac->priv = priv;
ac->io_mode = SYNC_IO_MODE;
- ac->perf_mode = false;
+ ac->perf_mode = LEGACY_PCM_MODE;
ac->fptr_cache_ops = NULL;
ac->apr = apr_register("ADSP", "ASM", \
(apr_fn)q6asm_callback,\
@@ -1695,7 +1696,7 @@
open.bits_per_sample = bits_per_sample;
open.mode_flags = 0x0;
- if (ac->perf_mode) {
+ if (ac->perf_mode == LOW_LATENCY_PCM_MODE) {
open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION <<
ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
} else {
@@ -1781,8 +1782,10 @@
open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V3;
open.mode_flags = 0x00;
- if (ac->perf_mode)
+ if (ac->perf_mode == ULTRA_LOW_LATENCY_PCM_MODE)
open.mode_flags |= ASM_ULTRA_LOW_LATENCY_STREAM_SESSION;
+ else if (ac->perf_mode == LOW_LATENCY_PCM_MODE)
+ open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION;
else {
open.mode_flags |= ASM_LEGACY_STREAM_SESSION;
if (is_gapless_mode)
diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c
index f74dbe2..701dfef 100644
--- a/sound/soc/msm/qdsp6v2/rtac.c
+++ b/sound/soc/msm/qdsp6v2/rtac.c
@@ -556,7 +556,8 @@
/* Check if device already added */
if (rtac_adm_data.num_of_dev != 0) {
for (; i < rtac_adm_data.num_of_dev; i++) {
- if (rtac_adm_data.device[i].afe_port == port_id) {
+ if (rtac_adm_data.device[i].afe_port == port_id &&
+ rtac_adm_data.device[i].copp == copp_id) {
add_popp(i, port_id, popp_id);
goto done;
}
@@ -609,7 +610,7 @@
}
}
-void rtac_remove_adm_device(u32 port_id)
+void rtac_remove_adm_device(u32 port_id, u32 copp_id)
{
s32 i;
pr_debug("%s: port_id = %d\n", __func__, port_id);
@@ -619,7 +620,8 @@
/* look for device */
for (i = 0; i < rtac_adm_data.num_of_dev; i++) {
- if (rtac_adm_data.device[i].afe_port == port_id) {
+ if (rtac_adm_data.device[i].afe_port == port_id &&
+ rtac_adm_data.device[i].copp == copp_id) {
memset(&rtac_adm_data.device[i], 0,
sizeof(rtac_adm_data.device[i]));
rtac_adm_data.num_of_dev--;
@@ -870,6 +872,8 @@
for (port_index = 0; port_index < AFE_MAX_PORTS; port_index++) {
if (adm_get_copp_id(port_index) == copp_id)
break;
+ if (adm_get_lowlatency_copp_id(port_index) == copp_id)
+ break;
}
if (port_index >= AFE_MAX_PORTS) {
pr_err("%s: Could not find port index for copp = %d\n",