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>
This commit is contained in:
parent
b1d55b705b
commit
f40be251f9
1 changed files with 54 additions and 15 deletions
|
@ -36,6 +36,8 @@
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/hashtable.h>
|
#include <linux/hashtable.h>
|
||||||
#include <linux/hash.h>
|
#include <linux/hash.h>
|
||||||
|
#include <soc/qcom/subsystem_restart.h>
|
||||||
|
#define IPA_SUBSYSTEM_NAME "ipa_fws"
|
||||||
#include "ipa_i.h"
|
#include "ipa_i.h"
|
||||||
#include "ipa_rm_i.h"
|
#include "ipa_rm_i.h"
|
||||||
#include "ipahal/ipahal.h"
|
#include "ipahal/ipahal.h"
|
||||||
|
@ -3740,8 +3742,6 @@ static int ipa3_gsi_pre_fw_load_init(void)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* GSI already enabled by TZ */
|
|
||||||
|
|
||||||
result = gsi_configure_regs(ipa3_res.transport_mem_base,
|
result = gsi_configure_regs(ipa3_res.transport_mem_base,
|
||||||
ipa3_res.transport_mem_size,
|
ipa3_res.transport_mem_size,
|
||||||
ipa3_res.ipa_mem_base);
|
ipa3_res.ipa_mem_base);
|
||||||
|
@ -3919,7 +3919,7 @@ fail_register_device:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ipa3_trigger_fw_loading(void)
|
static int ipa3_trigger_fw_loading_mdms(void)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
const struct firmware *fw;
|
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);
|
result = request_firmware(&fw, IPA_FWS_PATH, ipa3_ctx->dev);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
IPAERR("request_firmware failed, error %d\n", result);
|
IPAERR("request_firmware failed, error %d\n", result);
|
||||||
return;
|
return result;
|
||||||
}
|
}
|
||||||
if (fw == NULL) {
|
if (fw == NULL) {
|
||||||
IPAERR("Firmware is NULL!\n");
|
IPAERR("Firmware is NULL!\n");
|
||||||
return;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPADBG("FWs are available for loading\n");
|
IPADBG("FWs are available for loading\n");
|
||||||
|
@ -3941,26 +3941,45 @@ static void ipa3_trigger_fw_loading(void)
|
||||||
result = ipa3_load_fws(fw);
|
result = ipa3_load_fws(fw);
|
||||||
if (result) {
|
if (result) {
|
||||||
IPAERR("IPA FWs loading has failed\n");
|
IPAERR("IPA FWs loading has failed\n");
|
||||||
return;
|
release_firmware(fw);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = gsi_enable_fw(ipa3_res.transport_mem_base,
|
result = gsi_enable_fw(ipa3_res.transport_mem_base,
|
||||||
ipa3_res.transport_mem_size);
|
ipa3_res.transport_mem_size);
|
||||||
if (result) {
|
if (result) {
|
||||||
IPAERR("Failed to enable GSI FW\n");
|
IPAERR("Failed to enable GSI FW\n");
|
||||||
return;
|
release_firmware(fw);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
release_firmware(fw);
|
release_firmware(fw);
|
||||||
|
|
||||||
IPADBG("FW loading process is complete\n");
|
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,
|
static ssize_t ipa3_write(struct file *file, const char __user *buf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
unsigned long missing;
|
unsigned long missing;
|
||||||
|
int result = -EINVAL;
|
||||||
|
|
||||||
char dbg_buff[16] = { 0 };
|
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 will trigger the process only if we're in GSI mode, otherwise,
|
||||||
* we just ignore the write.
|
* we just ignore the write.
|
||||||
*/
|
*/
|
||||||
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI)
|
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
|
||||||
ipa3_trigger_fw_loading();
|
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;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4471,13 +4504,19 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
|
||||||
* the GSI FW to be up and running before the registration.
|
* the GSI FW to be up and running before the registration.
|
||||||
*/
|
*/
|
||||||
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
|
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
|
||||||
|
/*
|
||||||
|
* 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();
|
result = ipa3_gsi_pre_fw_load_init();
|
||||||
if (result) {
|
if (result) {
|
||||||
IPAERR("ipa gsi pre FW loading procedure failed\n");
|
IPAERR("gsi pre FW loading config failed\n");
|
||||||
result = -ENODEV;
|
result = -ENODEV;
|
||||||
goto fail_ipa_init_interrupts;
|
goto fail_ipa_init_interrupts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* For BAM (No other mode), we can just carry on with initialization */
|
/* For BAM (No other mode), we can just carry on with initialization */
|
||||||
else
|
else
|
||||||
return ipa3_post_init(resource_p, ipa_dev);
|
return ipa3_post_init(resource_p, ipa_dev);
|
||||||
|
|
Loading…
Add table
Reference in a new issue