summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSivan Reinstein <sivanr@codeaurora.org>2016-02-16 10:14:57 +0200
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-25 16:04:01 -0700
commitf40be251f93ad90cd947e6b4e0ce8bb2e4b46de0 (patch)
treea7e07e0d97884b8bc72cb01954a69498f82d3627
parentb1d55b705b31628df6df0e926cc6cf7f33f2f371 (diff)
msm: ipa3: add support for FW loading on MSMs
For MSMs, the IPA FWs (GSI FW/MCS, HPS and DPS) will be loaded via a secure PIL process. Change-Id: Ie3c3c46d52921e558e926ec2be57a885e04c924d CRs-Fixed: 970340 Acked-by: David Arinzon <darinzon@qti.qualcomm.com> Signed-off-by: Sivan Reinstein <sivanr@codeaurora.org>
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa.c69
1 files changed, 54 insertions, 15 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 130efbb057f7..01c5f5ba74c0 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -36,6 +36,8 @@
#include <linux/time.h>
#include <linux/hashtable.h>
#include <linux/hash.h>
+#include <soc/qcom/subsystem_restart.h>
+#define IPA_SUBSYSTEM_NAME "ipa_fws"
#include "ipa_i.h"
#include "ipa_rm_i.h"
#include "ipahal/ipahal.h"
@@ -3740,8 +3742,6 @@ static int ipa3_gsi_pre_fw_load_init(void)
{
int result;
- /* GSI already enabled by TZ */
-
result = gsi_configure_regs(ipa3_res.transport_mem_base,
ipa3_res.transport_mem_size,
ipa3_res.ipa_mem_base);
@@ -3919,7 +3919,7 @@ fail_register_device:
return result;
}
-static void ipa3_trigger_fw_loading(void)
+static int ipa3_trigger_fw_loading_mdms(void)
{
int result;
const struct firmware *fw;
@@ -3929,11 +3929,11 @@ static void ipa3_trigger_fw_loading(void)
result = request_firmware(&fw, IPA_FWS_PATH, ipa3_ctx->dev);
if (result < 0) {
IPAERR("request_firmware failed, error %d\n", result);
- return;
+ return result;
}
if (fw == NULL) {
IPAERR("Firmware is NULL!\n");
- return;
+ return -EINVAL;
}
IPADBG("FWs are available for loading\n");
@@ -3941,26 +3941,45 @@ static void ipa3_trigger_fw_loading(void)
result = ipa3_load_fws(fw);
if (result) {
IPAERR("IPA FWs loading has failed\n");
- return;
+ release_firmware(fw);
+ return result;
}
result = gsi_enable_fw(ipa3_res.transport_mem_base,
ipa3_res.transport_mem_size);
if (result) {
IPAERR("Failed to enable GSI FW\n");
- return;
+ release_firmware(fw);
+ return result;
}
release_firmware(fw);
IPADBG("FW loading process is complete\n");
- ipa3_post_init(&ipa3_res, ipa3_ctx->dev);
+ return 0;
+}
+
+static int ipa3_trigger_fw_loading_msms(void)
+{
+ void *subsystem_get_retval = NULL;
+
+ IPADBG("FW loading process initiated\n");
+
+ subsystem_get_retval = subsystem_get(IPA_SUBSYSTEM_NAME);
+ if (IS_ERR_OR_NULL(subsystem_get_retval)) {
+ IPAERR("Unable to trigger PIL process for FW loading\n");
+ return -EINVAL;
+ }
+
+ IPADBG("FW loading process is complete\n");
+ return 0;
}
static ssize_t ipa3_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
unsigned long missing;
+ int result = -EINVAL;
char dbg_buff[16] = { 0 };
@@ -3982,9 +4001,23 @@ static ssize_t ipa3_write(struct file *file, const char __user *buf,
* We will trigger the process only if we're in GSI mode, otherwise,
* we just ignore the write.
*/
- if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI)
- ipa3_trigger_fw_loading();
+ if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
+ IPA_ACTIVE_CLIENTS_INC_SIMPLE();
+
+ if (ipa3_ctx->ipa_hw_type == IPA_HW_v3_0)
+ result = ipa3_trigger_fw_loading_mdms();
+ else if (ipa3_ctx->ipa_hw_type == IPA_HW_v3_1)
+ result = ipa3_trigger_fw_loading_msms();
+ /* No IPAv3.x chipsets that don't support FW loading */
+ IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
+
+ if (result) {
+ IPAERR("FW loading process has failed\n");
+ BUG();
+ } else
+ ipa3_post_init(&ipa3_res, ipa3_ctx->dev);
+ }
return count;
}
@@ -4471,11 +4504,17 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
* the GSI FW to be up and running before the registration.
*/
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
- result = ipa3_gsi_pre_fw_load_init();
- if (result) {
- IPAERR("ipa gsi pre FW loading procedure failed\n");
- result = -ENODEV;
- goto fail_ipa_init_interrupts;
+ /*
+ * For IPA3.0, the GSI configuration is done by the GSI driver.
+ * For IPA3.1 (and on), the GSI configuration is done by TZ.
+ */
+ if (ipa3_ctx->ipa_hw_type == IPA_HW_v3_0) {
+ result = ipa3_gsi_pre_fw_load_init();
+ if (result) {
+ IPAERR("gsi pre FW loading config failed\n");
+ result = -ENODEV;
+ goto fail_ipa_init_interrupts;
+ }
}
}
/* For BAM (No other mode), we can just carry on with initialization */