6db4831e98
Android 14
2788 lines
80 KiB
C
2788 lines
80 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2019 MediaTek Inc.
|
|
*/
|
|
|
|
#include <linux/list.h>
|
|
#include <linux/device.h>
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/err.h>
|
|
#include <linux/kdev_t.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/kobject.h>
|
|
#include <linux/atomic.h>
|
|
#include <linux/of.h>
|
|
|
|
#include "ccci_config.h"
|
|
#include "ccci_common_config.h"
|
|
#include "ccci_platform.h"
|
|
#include "ccci_core.h"
|
|
#include "ccci_bm.h"
|
|
#include "modem_sys.h"
|
|
#include "ccci_hif.h"
|
|
#include "ccci_platform.h"
|
|
#include "md_sys1_platform.h"
|
|
|
|
#ifdef CONFIG_OF
|
|
#include <linux/of.h>
|
|
#include <linux/of_fdt.h>
|
|
#include <linux/of_irq.h>
|
|
#include <linux/of_address.h>
|
|
#endif
|
|
|
|
#include <memory-amms.h>
|
|
#include "mt-plat/mtk_ccci_common.h"
|
|
#include <mt-plat/mtk_boot_common.h>
|
|
|
|
#if defined(ENABLE_32K_CLK_LESS)
|
|
//#include <mt-plat/mtk_rtc.h>
|
|
#include "ccci_rtc.h"
|
|
#endif
|
|
|
|
#define TAG "md"
|
|
|
|
struct ccci_modem *modem_sys[MAX_MD_NUM];
|
|
|
|
/* flag for MD1_MD3_SMEM clear.
|
|
* if it is been cleared by md1 bootup flow, set it to 1.
|
|
* then it will not be cleared by md1 bootup flow
|
|
*/
|
|
static atomic_t md1_md3_smem_clear = ATOMIC_INIT(0);
|
|
|
|
#define DBM_S (CCCI_SMEM_SIZE_DBM + CCCI_SMEM_SIZE_DBM_GUARD * 2)
|
|
#define CCB_CACHE_MIN_SIZE (2 * 1024 * 1024)
|
|
static const char *s_smem_user_names[SMEM_USER_MAX];
|
|
|
|
#define MD_SMEM_FLAG_NORMAL 0
|
|
#define MD_SMEM_FLAG_PADDING 1
|
|
#define MD_SMEM_FLAG_OVERLAP 2
|
|
|
|
#define MD_SMEM_FLAG_SIZE_ZERO 1000
|
|
#define MD_SMEM_FLAG_LAST_REGION 1001
|
|
|
|
#define MD_SMEM_BUF_SIZE 1024
|
|
static char g_md_smem_buf[MD_SMEM_BUF_SIZE];
|
|
static unsigned int g_md_smem_pos;
|
|
|
|
#define STR_SIZE 100
|
|
|
|
struct ccci_smem_region md1_6297_noncacheable_fat[] = {
|
|
{SMEM_USER_RAW_DFD, 0, 0, 0, },
|
|
{SMEM_USER_RAW_UDC_DATA, 0, 0, 0, },
|
|
{SMEM_USER_MD_WIFI_PROXY, 0, 0, 0,},
|
|
#ifdef ENABLE_SECURITY_SHARE_MEMORY
|
|
{SMEM_USER_SECURITY_SMEM, 0, 0, SMF_NCLR_FIRST, },
|
|
#endif
|
|
{SMEM_USER_RAW_AMMS_POS, 0, 0, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_RAW_MDCCCI_DBG, 0, 2*1024, 0, },
|
|
{SMEM_USER_RAW_MDSS_DBG, 0, 14*1024, 0, },
|
|
{SMEM_USER_RAW_RESERVED, 0, 42*1024, 0, },
|
|
{SMEM_USER_RAW_RUNTIME_DATA, 0, 4*1024, 0, },
|
|
{SMEM_USER_RAW_FORCE_ASSERT, 0, 1*1024, 0, },
|
|
{SMEM_USER_LOW_POWER, 0, 512, 0, },
|
|
{SMEM_USER_RAW_DBM, 0, 512, 0, },
|
|
{SMEM_USER_CCISM_SCP, 0, 32*1024, 0, },
|
|
{SMEM_USER_RAW_CCB_CTRL, 0, 4*1024, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_RAW_NETD, 0, 8*1024, 0, },
|
|
{SMEM_USER_RAW_USB, 0, 4*1024, 0, },
|
|
{SMEM_USER_RAW_AUDIO, 0, 52*1024, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_CCISM_MCU, 0, (720+1)*1024, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_CCISM_MCU_EXP, 0, (120+1)*1024, SMF_NCLR_FIRST, },
|
|
#ifdef CUST_FT_BIGDATA
|
|
{SMEM_USER_MD_BIGDATA, 0, 512, 0},
|
|
{SMEM_USER_MD_IPCA_BIGDATA, 0, 128, 0},
|
|
#endif
|
|
{SMEM_USER_MAX, }, /* tail guard */
|
|
};
|
|
struct ccci_smem_region md1_6297_cacheable[] = {
|
|
/*
|
|
* all CCB user should be put together, and the total size is set
|
|
* in the first one, all reset CCB users' address, offset and size
|
|
* will be re-calculated during port initialization. and please be
|
|
* aware of that CCB user's size will be aligned to 4KB.
|
|
*/
|
|
{SMEM_USER_RAW_MD_CONSYS, 0, 0, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_MD_NVRAM_CACHE, 0, 0, 0, },
|
|
{SMEM_USER_CCB_DHL, 0, 0, 0, },
|
|
{SMEM_USER_CCB_MD_MONITOR, 0, 0, 0, },
|
|
{SMEM_USER_CCB_META, 0, 0, 0, },
|
|
{SMEM_USER_RAW_DHL, 0, 0, 0, },
|
|
{SMEM_USER_RAW_MDM, 0, 0, 0, },
|
|
{SMEM_USER_RAW_UDC_DESCTAB, 0, 0, 0, },
|
|
{SMEM_USER_RAW_USIP, 0, 0, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_MAX, },
|
|
};
|
|
|
|
struct ccci_smem_region md1_6293_noncacheable_fat[] = {
|
|
{SMEM_USER_RAW_MDCCCI_DBG, 0, 2*1024, 0, },
|
|
{SMEM_USER_RAW_MDSS_DBG, 2*1024, 10*1024, 0, },
|
|
{SMEM_USER_RAW_RESERVED, 12*1024, 46*1024, 0, },
|
|
{SMEM_USER_RAW_RUNTIME_DATA, 58*1024, 4*1024, 0, },
|
|
{SMEM_USER_RAW_FORCE_ASSERT, 62*1024, 1*1024, 0, },
|
|
{SMEM_USER_RAW_DBM, 64*1024-DBM_S, DBM_S, 0, },
|
|
{SMEM_USER_CCISM_SCP, 64*1024, 32*1024, 0, },
|
|
{SMEM_USER_RAW_CCB_CTRL, 96*1024, 4*1024, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_RAW_NETD, 100*1024, 4*1024, 0, },
|
|
{SMEM_USER_RAW_USB, 104*1024, 4*1024, 0, },
|
|
{SMEM_USER_RAW_AUDIO, 108*1024, 52*1024, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_CCISM_MCU, 160*1024, (720+1)*1024, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_CCISM_MCU_EXP, 881*1024, (120+1)*1024, SMF_NCLR_FIRST, },
|
|
#ifdef CUST_FT_BIGDATA
|
|
{SMEM_USER_MD_BIGDATA, 1002*1024, 512, 0},
|
|
{SMEM_USER_MD_IPCA_BIGDATA, 1002*1024+512, 128, 0},
|
|
#endif
|
|
{SMEM_USER_RAW_DFD, 1*1024*1024, 0, 0, },
|
|
{SMEM_USER_RAW_UDC_DATA, (1*1024+448)*1024, 0*1024*1024, 0, },
|
|
{SMEM_USER_RAW_AMMS_POS, (1*1024 + 448)*1024, 0,
|
|
SMF_NCLR_FIRST, },
|
|
{SMEM_USER_RAW_ALIGN_PADDING, (1*1024 + 448)*1024, 0,
|
|
SMF_NCLR_FIRST, },
|
|
|
|
/* for SIB */
|
|
{SMEM_USER_RAW_LWA, (1*1024+448)*1024, 0*1024*1024, 0, },
|
|
{SMEM_USER_RAW_PHY_CAP, (1*1024+448)*1024, 0*1024*1024, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_MAX, }, /* tail guard */
|
|
};
|
|
#define CCB_CACHE_MIN_SIZE (2 * 1024 * 1024)
|
|
static const char *s_smem_user_names[SMEM_USER_MAX];
|
|
|
|
struct ccci_smem_region md1_6293_cacheable[] = {
|
|
/*
|
|
* all CCB user should be put together, and the total size is set
|
|
* in the first one, all reset CCB users' address, offset and size
|
|
* will be re-calculated during port initialization. and please be
|
|
* aware of that CCB user's size will be aligned to 4KB.
|
|
*/
|
|
{SMEM_USER_CCB_DHL, 0*1024*1024, CCB_CACHE_MIN_SIZE, 0, },
|
|
{SMEM_USER_CCB_MD_MONITOR, 0*1024*1024, CCB_CACHE_MIN_SIZE, 0, },
|
|
{SMEM_USER_CCB_META, 0*1024*1024, CCB_CACHE_MIN_SIZE, 0, },
|
|
{SMEM_USER_RAW_DHL, CCB_CACHE_MIN_SIZE, 20*1024*1024, 0, },
|
|
{SMEM_USER_RAW_MDM, CCB_CACHE_MIN_SIZE, 20*1024*1024, 0, },
|
|
{SMEM_USER_RAW_UDC_DESCTAB, 0*1024*1024, 0*1024*1024, 0, },
|
|
{SMEM_USER_RAW_MD_CONSYS, 0*1024*1024, 0*1024*1024, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_RAW_USIP, 0*1024*1024, 0*1024, SMF_NCLR_FIRST, },
|
|
{SMEM_USER_MAX, },
|
|
};
|
|
|
|
static void init_smem_user_name(void)
|
|
{
|
|
s_smem_user_names[SMEM_USER_RAW_DBM] = "RAW_DBM";
|
|
s_smem_user_names[SMEM_USER_CCB_DHL] = "CCB_DHL";
|
|
s_smem_user_names[SMEM_USER_CCB_MD_MONITOR] = "CCB_MD_MONITOR";
|
|
s_smem_user_names[SMEM_USER_CCB_META] = "CCB_META";
|
|
s_smem_user_names[SMEM_USER_RAW_CCB_CTRL] = "RAW_CCB_CTRL";
|
|
s_smem_user_names[SMEM_USER_RAW_DHL] = "RAW_DHL";
|
|
s_smem_user_names[SMEM_USER_RAW_MDM] = "RAW_MDM";
|
|
s_smem_user_names[SMEM_USER_RAW_NETD] = "RAW_NETD";
|
|
s_smem_user_names[SMEM_USER_RAW_USB] = "RAW_USB";
|
|
s_smem_user_names[SMEM_USER_RAW_AUDIO] = "RAW_AUDIO";
|
|
s_smem_user_names[SMEM_USER_RAW_DFD] = "RAW_DFD";
|
|
s_smem_user_names[SMEM_USER_RAW_LWA] = "RAW_LWA";
|
|
s_smem_user_names[SMEM_USER_RAW_MDCCCI_DBG] = "RAW_MDCCCI_DBG";
|
|
s_smem_user_names[SMEM_USER_RAW_MDSS_DBG] = "RAW_MDSS_DBG";
|
|
s_smem_user_names[SMEM_USER_RAW_RUNTIME_DATA] = "RAW_RUNTIME_DATA";
|
|
s_smem_user_names[SMEM_USER_RAW_FORCE_ASSERT] = "RAW_FORCE_ASSERT";
|
|
s_smem_user_names[SMEM_USER_CCISM_SCP] = "CCISM_SCP";
|
|
s_smem_user_names[SMEM_USER_RAW_MD2MD] = "RAW_MD2MD";
|
|
s_smem_user_names[SMEM_USER_RAW_RESERVED] = "RAW_RESERVED";
|
|
s_smem_user_names[SMEM_USER_CCISM_MCU] = "CCISM_MCU";
|
|
s_smem_user_names[SMEM_USER_CCISM_MCU_EXP] = "CCISM_MCU_EXP";
|
|
#ifdef CUST_FT_BIGDATA
|
|
s_smem_user_names[SMEM_USER_MD_BIGDATA] = "BIGDATA_CRASHINFO";
|
|
s_smem_user_names[SMEM_USER_MD_IPCA_BIGDATA] = "IPCA_BIGDATA_CRASHINFO";
|
|
#endif
|
|
s_smem_user_names[SMEM_USER_SMART_LOGGING] = "SMART_LOGGING";
|
|
s_smem_user_names[SMEM_USER_RAW_MD_CONSYS] = "RAW_MD_CONSYS";
|
|
s_smem_user_names[SMEM_USER_RAW_PHY_CAP] = "RAW_PHY_CAP";
|
|
s_smem_user_names[SMEM_USER_RAW_USIP] = "RAW_USIP";
|
|
s_smem_user_names[SMEM_USER_RESV_0] = "RESV_0";
|
|
s_smem_user_names[SMEM_USER_ALIGN_PADDING] = "ALIGN_PADDING";
|
|
s_smem_user_names[SMEM_USER_RAW_UDC_DATA] = "RAW_UDC_DATA";
|
|
s_smem_user_names[SMEM_USER_RAW_UDC_DESCTAB] = "RAW_UDC_DESCTAB";
|
|
s_smem_user_names[SMEM_USER_RAW_AMMS_POS] = "RAW_AMMS_POS";
|
|
s_smem_user_names[SMEM_USER_RAW_ALIGN_PADDING] = "RAW_ALIGN_PADDING";
|
|
s_smem_user_names[SMEM_USER_MD_WIFI_PROXY] = "MD_WIFI_PROXY";
|
|
s_smem_user_names[SMEM_USER_MD_NVRAM_CACHE] = "MD_NVRAM_CACHE";
|
|
s_smem_user_names[SMEM_USER_LOW_POWER] = "LOW_POWER";
|
|
#ifdef ENABLE_SECURITY_SHARE_MEMORY
|
|
s_smem_user_names[SMEM_USER_SECURITY_SMEM] = "SECURITY_SMEM";
|
|
#endif
|
|
}
|
|
|
|
|
|
static const char *get_smem_user_name(int user_id)
|
|
{
|
|
if (user_id < 0 || user_id >= SMEM_USER_MAX)
|
|
return "";
|
|
|
|
return s_smem_user_names[user_id];
|
|
}
|
|
|
|
static struct ccci_smem_region *get_smem_by_user_id(
|
|
struct ccci_smem_region *regions, enum SMEM_USER_ID user_id)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; ; i++) {
|
|
if (!regions || regions[i].id == SMEM_USER_MAX)
|
|
return NULL;
|
|
|
|
if (regions[i].id == user_id) {
|
|
if (!get_modem_is_enabled(MD_SYS3) &&
|
|
(regions[i].flag & SMF_MD3_RELATED))
|
|
return NULL;
|
|
else
|
|
return regions + i;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void append_string_to_md_smem_buf(const char *str)
|
|
{
|
|
int n;
|
|
|
|
if (g_md_smem_pos >= (MD_SMEM_BUF_SIZE - 1))
|
|
return;
|
|
|
|
n = snprintf(g_md_smem_buf + g_md_smem_pos,
|
|
MD_SMEM_BUF_SIZE - g_md_smem_pos,
|
|
"%s", str);
|
|
|
|
if (n <= 0) {
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"[%s] warning: snprintf() fail: %d\n",
|
|
__func__, n);
|
|
return;
|
|
}
|
|
|
|
if (n >= (MD_SMEM_BUF_SIZE - g_md_smem_pos)) {
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"[%s] warning: g_md_smem_buf is too small: %u,%d\n",
|
|
__func__, g_md_smem_pos, n);
|
|
|
|
g_md_smem_pos = MD_SMEM_BUF_SIZE - 1;
|
|
|
|
} else
|
|
g_md_smem_pos += n;
|
|
|
|
g_md_smem_buf[g_md_smem_pos] = '\0';
|
|
}
|
|
|
|
static void calc_smem_overlap_and_padding(
|
|
struct ccci_smem_region *regions,
|
|
int flag, int index, int *overlap_index)
|
|
{
|
|
int i = 0, n = 0;
|
|
char str[STR_SIZE] = {0};
|
|
|
|
CCCI_BOOTUP_LOG(-1, TAG,
|
|
"[%s] flag: %d; index: %d; overlap_index: %d\n",
|
|
__func__, flag, index, (*overlap_index));
|
|
|
|
if ((flag != MD_SMEM_FLAG_SIZE_ZERO) &&
|
|
((*overlap_index) != -1)) { //overlap
|
|
int s = 0, c = 0;
|
|
unsigned int overlap_off = 0, overlap_size = 0;
|
|
char lap[STR_SIZE] = {0};
|
|
|
|
i = (*overlap_index);
|
|
|
|
while (i < index) {
|
|
if (regions[i].size == 0) {
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
if ((regions[i].offset < overlap_off) ||
|
|
(overlap_off == 0))
|
|
overlap_off = regions[i].offset;
|
|
|
|
if ((regions[i].offset + regions[i].size)
|
|
- overlap_off > overlap_size)
|
|
overlap_size =
|
|
(regions[i].offset + regions[i].size)
|
|
- overlap_off;
|
|
|
|
if (i == (*overlap_index))
|
|
n = snprintf(lap + s, STR_SIZE - s,
|
|
"%d", regions[i].id);
|
|
else
|
|
n = snprintf(lap + s, STR_SIZE - s,
|
|
"|%d", regions[i].id);
|
|
|
|
if (n >= (STR_SIZE - s))
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"[%s] warning: buf size too small: %d,%d\n",
|
|
__func__, s, n);
|
|
|
|
else if (n < 0) {
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"[%s] warning: snprintf() fail: %d,%d\n",
|
|
__func__, s, n);
|
|
break;
|
|
}
|
|
|
|
s += n;
|
|
c++;
|
|
i++;
|
|
|
|
if (s >= STR_SIZE)
|
|
break;
|
|
}
|
|
|
|
if (c > 1) {
|
|
n = snprintf(str, STR_SIZE, "%d-%s-%X|%X\n",
|
|
MD_SMEM_FLAG_OVERLAP,
|
|
lap, overlap_off, overlap_size);
|
|
|
|
if (n >= STR_SIZE)
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"[%s] warning: str buf size too small, %d\n",
|
|
__func__, n);
|
|
|
|
if (n > 0)
|
|
append_string_to_md_smem_buf(str);
|
|
}
|
|
|
|
*overlap_index = -1;
|
|
}
|
|
|
|
if (flag == MD_SMEM_FLAG_SIZE_ZERO)
|
|
flag = MD_SMEM_FLAG_NORMAL;
|
|
|
|
if (flag == MD_SMEM_FLAG_NORMAL ||
|
|
flag == MD_SMEM_FLAG_PADDING) { //normal and padding
|
|
|
|
if (flag == MD_SMEM_FLAG_PADDING) {
|
|
int pad_off = regions[index-1].offset
|
|
+ regions[index-1].size;
|
|
|
|
n = snprintf(str, STR_SIZE, "%d-%d-%X|%X\n", flag,
|
|
regions[index].id,
|
|
pad_off,
|
|
regions[index].offset - pad_off);
|
|
|
|
if (n >= STR_SIZE)
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"[%s] warning: str buf size too small, %d\n",
|
|
__func__, n);
|
|
|
|
if (n > 0)
|
|
append_string_to_md_smem_buf(str);
|
|
|
|
flag = MD_SMEM_FLAG_NORMAL;
|
|
}
|
|
|
|
n = snprintf(str, STR_SIZE, "%d-%d-%X|%X\n", flag,
|
|
regions[index].id,
|
|
regions[index].offset, regions[index].size);
|
|
|
|
if (n >= STR_SIZE)
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"[%s] warning: str buf size too small, %d\n",
|
|
__func__, n);
|
|
|
|
if (n > 0)
|
|
append_string_to_md_smem_buf(str);
|
|
}
|
|
}
|
|
|
|
static void init_smem_regions(struct ccci_smem_region *regions,
|
|
phys_addr_t base_ap_view_phy,
|
|
void __iomem *base_ap_view_vir,
|
|
phys_addr_t base_md_view_phy)
|
|
{
|
|
int i;
|
|
int calc_offset = 0;
|
|
int overlap_index = -1;
|
|
|
|
for (i = 0; ; i++) {
|
|
if (!regions || regions[i].id == SMEM_USER_MAX)
|
|
break;
|
|
|
|
if (!get_modem_is_enabled(MD_SYS3) &&
|
|
(regions[i].flag & SMF_MD3_RELATED))
|
|
continue;
|
|
|
|
regions[i].base_ap_view_phy =
|
|
base_ap_view_phy + regions[i].offset;
|
|
regions[i].base_ap_view_vir =
|
|
base_ap_view_vir + regions[i].offset;
|
|
regions[i].base_md_view_phy =
|
|
base_md_view_phy + regions[i].offset;
|
|
|
|
if ((i > 0) && (regions[i].size != 0) &&
|
|
(calc_offset != regions[i].offset)) {
|
|
|
|
if (regions[i].offset > calc_offset) { // padding
|
|
CCCI_BOOTUP_LOG(-1, TAG,
|
|
"[%s] <%d>(%s) padding size: %x\n",
|
|
__func__, regions[i].id,
|
|
get_smem_user_name(regions[i].id),
|
|
regions[i].offset - calc_offset);
|
|
|
|
calc_smem_overlap_and_padding(regions,
|
|
MD_SMEM_FLAG_PADDING, i,
|
|
&overlap_index);
|
|
|
|
calc_offset = regions[i].offset + regions[i].size;
|
|
|
|
} else { //overlap
|
|
CCCI_BOOTUP_LOG(-1, TAG,
|
|
"[%s] (%s) and (%s) is overlap.\n",
|
|
__func__,
|
|
get_smem_user_name(regions[i-1].id),
|
|
get_smem_user_name(regions[i].id));
|
|
|
|
if (overlap_index == -1)
|
|
overlap_index = i-1;
|
|
|
|
if ((regions[i].offset + regions[i].size) >
|
|
calc_offset) //range is larger than before
|
|
calc_offset = regions[i].offset +
|
|
regions[i].size;
|
|
}
|
|
|
|
} else {
|
|
if (regions[i].size != 0) { //normal region
|
|
calc_offset = regions[i].offset + regions[i].size;
|
|
|
|
calc_smem_overlap_and_padding(regions,
|
|
MD_SMEM_FLAG_NORMAL, i,
|
|
&overlap_index);
|
|
|
|
} else // region size is 0
|
|
calc_smem_overlap_and_padding(regions,
|
|
MD_SMEM_FLAG_SIZE_ZERO, i,
|
|
&overlap_index);
|
|
|
|
}
|
|
|
|
CCCI_BOOTUP_LOG(-1, TAG,
|
|
"%s: reg[%d](%s)<%d>(%lx %lx %lx)[%x]\n", __func__,
|
|
i, get_smem_user_name(regions[i].id), regions[i].id,
|
|
(unsigned long)regions[i].base_ap_view_phy,
|
|
(unsigned long)regions[i].base_ap_view_vir,
|
|
(unsigned long)regions[i].base_md_view_phy,
|
|
regions[i].size);
|
|
}
|
|
|
|
calc_smem_overlap_and_padding(regions,
|
|
MD_SMEM_FLAG_LAST_REGION, i,
|
|
&overlap_index);
|
|
}
|
|
|
|
static void clear_smem_region(struct ccci_smem_region *regions, int first_boot)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; ; i++) {
|
|
if (!regions || regions[i].id == SMEM_USER_MAX)
|
|
break;
|
|
|
|
if (!get_modem_is_enabled(MD_SYS3) &&
|
|
(regions[i].flag & SMF_MD3_RELATED))
|
|
continue;
|
|
if (first_boot) {
|
|
|
|
if (!(regions[i].flag & SMF_NCLR_FIRST)) {
|
|
if (regions[i].id == SMEM_USER_RAW_MD2MD) {
|
|
if (atomic_add_unless(
|
|
&md1_md3_smem_clear, 1, 1))
|
|
memset_io(
|
|
regions[i].base_ap_view_vir,
|
|
0, regions[i].size);
|
|
} else if (regions[i].size) {
|
|
memset_io(regions[i].base_ap_view_vir,
|
|
0, regions[i].size);
|
|
}
|
|
}
|
|
} else {
|
|
if (regions[i].flag & SMF_CLR_RESET && regions[i].size)
|
|
memset_io(regions[i].base_ap_view_vir,
|
|
0, regions[i].size);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* setup function is only for data structure initialization */
|
|
struct ccci_modem *ccci_md_alloc(int private_size)
|
|
{
|
|
struct ccci_modem *md = kzalloc(sizeof(struct ccci_modem), GFP_KERNEL);
|
|
|
|
if (!md) {
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"fail to allocate memory for modem structure\n");
|
|
goto out;
|
|
}
|
|
if (private_size > 0)
|
|
md->private_data = kzalloc(private_size, GFP_KERNEL);
|
|
else
|
|
md->private_data = NULL;
|
|
md->per_md_data.config.setting |= MD_SETTING_FIRST_BOOT;
|
|
md->per_md_data.is_in_ee_dump = 0;
|
|
md->is_force_asserted = 0;
|
|
md->per_md_data.md_dbg_dump_flag = MD_DBG_DUMP_AP_REG;
|
|
|
|
out:
|
|
return md;
|
|
}
|
|
|
|
static inline int log2_remain(unsigned int value)
|
|
{
|
|
int x = 0;
|
|
int y;
|
|
|
|
if (value < 32)
|
|
return -1;
|
|
|
|
/* value = (2^x)*y */
|
|
while (!(value & (1 << x)))
|
|
x++;
|
|
y = (value >> x);
|
|
if ((1 << x) * y != value)
|
|
WARN_ON(1);
|
|
|
|
return y;
|
|
}
|
|
|
|
phys_addr_t __attribute__((weak)) amms_cma_allocate(unsigned long size)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int __attribute__((weak)) amms_cma_free(phys_addr_t addr, unsigned long size)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#if (MD_GENERATION >= 6297)
|
|
static inline int update_smem_region(struct ccci_smem_region *region)
|
|
{
|
|
unsigned int offset, size;
|
|
int ret = 0;
|
|
|
|
if (get_nc_smem_region_info(region->id, &offset, NULL, &size)) {
|
|
region->offset = offset;
|
|
region->size = size;
|
|
ret = 1;
|
|
CCCI_BOOTUP_LOG(MD_SYS1, TAG, "Update <%d>:0x%x 0x%x\n",
|
|
region->id, region->offset, region->size);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static void ccci_6297_md_smem_layout_config(struct ccci_modem *md)
|
|
{
|
|
struct ccci_mem_layout *mm_str = &md->mem_layout;
|
|
unsigned int md_resv_mem_offset = 0, ccb_offset = 0;
|
|
unsigned int md_resv_mem_size = 0, ccb_size = 0;
|
|
unsigned int i;
|
|
phys_addr_t md_resv_smem_addr = 0, smem_amms_pos_addr = 0;
|
|
int size;
|
|
|
|
/* non-cacheable start */
|
|
get_md_resv_mem_info(md->index, NULL, NULL, &md_resv_smem_addr, NULL);
|
|
|
|
#ifdef CCCI_USE_DFD_OFFSET_0
|
|
for (i = 0; i < (sizeof(md1_6297_noncacheable_fat)/
|
|
sizeof(struct ccci_smem_region)); i++) {
|
|
|
|
update_smem_region(&md1_6297_noncacheable_fat[i]);
|
|
if (i == 0)
|
|
continue;
|
|
|
|
if (md1_6297_noncacheable_fat[i].offset == 0)
|
|
#else
|
|
for (i = 1; i < (sizeof(md1_6297_noncacheable_fat)/
|
|
sizeof(struct ccci_smem_region)); i++) {
|
|
|
|
update_smem_region(&md1_6297_noncacheable_fat[i]);
|
|
if (md1_6297_noncacheable_fat[i].size == 0)
|
|
#endif
|
|
/* update offset */
|
|
md1_6297_noncacheable_fat[i].offset =
|
|
md1_6297_noncacheable_fat[i-1].offset
|
|
+ md1_6297_noncacheable_fat[i-1].size;
|
|
|
|
/* Special case */
|
|
switch (md1_6297_noncacheable_fat[i].id) {
|
|
case SMEM_USER_RAW_AMMS_POS:
|
|
size = get_smem_amms_pos_size(MD_SYS1);
|
|
if (size >= 0) {
|
|
/* free AMMS POS smem*/
|
|
smem_amms_pos_addr = md_resv_smem_addr
|
|
+ md1_6297_noncacheable_fat[i].offset;
|
|
amms_cma_free(smem_amms_pos_addr, size);
|
|
}
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"smem amms pos size:%d\n",
|
|
md1_6297_noncacheable_fat[i].size);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
mm_str->md_bank4_noncacheable = md1_6297_noncacheable_fat;
|
|
get_md_resv_csmem_info(md->index,
|
|
&mm_str->md_bank4_cacheable_total.base_ap_view_phy,
|
|
&mm_str->md_bank4_cacheable_total.size);
|
|
/* cacheable start */
|
|
if (mm_str->md_bank4_cacheable_total.base_ap_view_phy &&
|
|
mm_str->md_bank4_cacheable_total.size)
|
|
mm_str->md_bank4_cacheable_total.base_ap_view_vir =
|
|
ccci_map_phy_addr(
|
|
mm_str->md_bank4_cacheable_total.base_ap_view_phy,
|
|
mm_str->md_bank4_cacheable_total.size);
|
|
else
|
|
CCCI_ERROR_LOG(md->index, TAG,
|
|
"get cacheable info base:%lx size:%x\n",
|
|
(unsigned long)
|
|
mm_str->md_bank4_cacheable_total.base_ap_view_phy,
|
|
mm_str->md_bank4_cacheable_total.size);
|
|
|
|
mm_str->md_bank4_cacheable_total.base_md_view_phy = 0x40000000
|
|
+ get_md_smem_cachable_offset(MD_SYS1)
|
|
+ mm_str->md_bank4_cacheable_total.base_ap_view_phy -
|
|
round_down(mm_str->md_bank4_cacheable_total.base_ap_view_phy,
|
|
0x00100000);
|
|
|
|
/* specially, CCB size. */
|
|
/* get_md_resv_ccb_info(md->index, &ccb_offset, &ccb_size); */
|
|
get_md_cache_region_info(SMEM_USER_CCB_START,
|
|
&ccb_offset,
|
|
&ccb_size);
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"ccb totoal :offset = 0x%x, size = 0x%x\n",
|
|
ccb_offset, ccb_size);
|
|
for (i = 0; i < (sizeof(md1_6297_cacheable)/
|
|
sizeof(struct ccci_smem_region)); i++) {
|
|
|
|
switch (md1_6297_cacheable[i].id) {
|
|
case SMEM_USER_CCB_DHL:
|
|
case SMEM_USER_CCB_MD_MONITOR:
|
|
case SMEM_USER_CCB_META:
|
|
md1_6297_cacheable[i].size =
|
|
(ccb_size > CCB_CACHE_MIN_SIZE) ?
|
|
CCB_CACHE_MIN_SIZE:0;
|
|
md1_6297_cacheable[i].offset = ccb_offset;
|
|
break;
|
|
case SMEM_USER_RAW_DHL:
|
|
case SMEM_USER_RAW_MDM:
|
|
md1_6297_cacheable[i].size =
|
|
(ccb_size > CCB_CACHE_MIN_SIZE) ?
|
|
(ccb_size - CCB_CACHE_MIN_SIZE):0;
|
|
md1_6297_cacheable[i].offset =
|
|
(ccb_size > CCB_CACHE_MIN_SIZE) ?
|
|
(ccb_offset + CCB_CACHE_MIN_SIZE):ccb_offset;
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"[%d]RAW size:%d\n", md1_6297_cacheable[i].id,
|
|
md1_6297_cacheable[i].size);
|
|
break;
|
|
case SMEM_USER_RAW_MD_CONSYS: /* go through */
|
|
case SMEM_USER_MD_NVRAM_CACHE: /* go through */
|
|
case SMEM_USER_RAW_UDC_DESCTAB: /* go through */
|
|
case SMEM_USER_RAW_USIP:
|
|
get_md_cache_region_info(md1_6297_cacheable[i].id,
|
|
&md_resv_mem_offset,
|
|
&md_resv_mem_size);
|
|
|
|
md1_6297_cacheable[i].size = md_resv_mem_size;
|
|
if (md_resv_mem_offset || md_resv_mem_size)
|
|
md1_6297_cacheable[i].offset =
|
|
md_resv_mem_offset; /* LK config */
|
|
else if (i == 0)
|
|
md1_6297_cacheable[i].offset = 0;
|
|
else
|
|
md1_6297_cacheable[i].offset =
|
|
md1_6297_cacheable[i - 1].offset +
|
|
md1_6297_cacheable[i - 1].size;
|
|
break;
|
|
default:
|
|
md1_6297_cacheable[i].size = 0;
|
|
md1_6297_cacheable[i].offset = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
mm_str->md_bank4_cacheable = md1_6297_cacheable;
|
|
}
|
|
#endif
|
|
|
|
#if (MD_GENERATION == 6295)
|
|
static void ccci_6295_md_smem_layout_config(struct ccci_modem *md)
|
|
{
|
|
struct ccci_mem_layout *mm_str = &md->mem_layout;
|
|
unsigned int md_resv_mem_offset = 0, ccb_offset = 0;
|
|
unsigned int md_resv_mem_size = 0, ccb_size = 0;
|
|
unsigned int offset_adjust_flag = 0;
|
|
unsigned int i;
|
|
phys_addr_t md_resv_smem_addr = 0, smem_amms_pos_addr = 0,
|
|
smem_align_padding_addr = 0;
|
|
unsigned int udc_noncache_size = 0, udc_cache_size = 0;
|
|
int size;
|
|
|
|
/* non-cacheable start */
|
|
get_md_resv_mem_info(md->index, NULL, NULL, &md_resv_smem_addr, NULL);
|
|
for (i = 0; i < (sizeof(md1_6293_noncacheable_fat)/
|
|
sizeof(struct ccci_smem_region)); i++) {
|
|
/* update offset */
|
|
if (offset_adjust_flag == 1)
|
|
md1_6293_noncacheable_fat[i].offset =
|
|
md1_6293_noncacheable_fat[i-1].offset
|
|
+ md1_6293_noncacheable_fat[i-1].size;
|
|
switch (md1_6293_noncacheable_fat[i].id) {
|
|
case SMEM_USER_RAW_PHY_CAP:
|
|
md1_6293_noncacheable_fat[i].size =
|
|
get_md_resv_phy_cap_size(MD_SYS1);
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"PHY size:%d\n",
|
|
md1_6293_noncacheable_fat[i].size);
|
|
break;
|
|
case SMEM_USER_RAW_DFD:
|
|
size = get_md_smem_dfd_size(MD_SYS1);
|
|
if (size >= 0 && size !=
|
|
md1_6293_noncacheable_fat[i].size) {
|
|
md1_6293_noncacheable_fat[i].size = size;
|
|
offset_adjust_flag = 1;
|
|
}
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"dfd size:%d\n",
|
|
md1_6293_noncacheable_fat[i].size);
|
|
break;
|
|
case SMEM_USER_RAW_AMMS_POS:
|
|
size = get_smem_amms_pos_size(MD_SYS1);
|
|
if (size >= 0 && size !=
|
|
md1_6293_noncacheable_fat[i].size) {
|
|
md1_6293_noncacheable_fat[i].size = size;
|
|
offset_adjust_flag = 1;
|
|
/* free AMMS POS smem*/
|
|
smem_amms_pos_addr = md_resv_smem_addr
|
|
+ md1_6293_noncacheable_fat[i].offset;
|
|
amms_cma_free(smem_amms_pos_addr, size);
|
|
}
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"smem amms pos size:%d\n",
|
|
md1_6293_noncacheable_fat[i].size);
|
|
break;
|
|
case SMEM_USER_RAW_ALIGN_PADDING:
|
|
size = get_smem_align_padding_size(MD_SYS1);
|
|
if (size >= 0 && size !=
|
|
md1_6293_noncacheable_fat[i].size) {
|
|
md1_6293_noncacheable_fat[i].size = size;
|
|
offset_adjust_flag = 1;
|
|
/* free POS padding smem*/
|
|
smem_align_padding_addr = md_resv_smem_addr
|
|
+ md1_6293_noncacheable_fat[i].offset;
|
|
amms_cma_free(smem_align_padding_addr, size);
|
|
}
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"smem align padding size:%d\n",
|
|
md1_6293_noncacheable_fat[i].size);
|
|
break;
|
|
case SMEM_USER_RAW_UDC_DATA:
|
|
get_md_resv_udc_info(md->index,
|
|
&udc_noncache_size, &udc_cache_size);
|
|
if (udc_noncache_size > 0 && udc_noncache_size !=
|
|
md1_6293_noncacheable_fat[i].size) {
|
|
md1_6293_noncacheable_fat[i].size =
|
|
udc_noncache_size;
|
|
offset_adjust_flag = 1;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
mm_str->md_bank4_noncacheable = md1_6293_noncacheable_fat;
|
|
get_md_resv_csmem_info(md->index,
|
|
&mm_str->md_bank4_cacheable_total.base_ap_view_phy,
|
|
&mm_str->md_bank4_cacheable_total.size);
|
|
/* cacheable start */
|
|
if (mm_str->md_bank4_cacheable_total.base_ap_view_phy &&
|
|
mm_str->md_bank4_cacheable_total.size)
|
|
mm_str->md_bank4_cacheable_total.base_ap_view_vir =
|
|
ccci_map_phy_addr(
|
|
mm_str->md_bank4_cacheable_total.base_ap_view_phy,
|
|
mm_str->md_bank4_cacheable_total.size);
|
|
else
|
|
CCCI_ERROR_LOG(md->index, TAG,
|
|
"get cacheable info base:%lx size:%x\n",
|
|
(unsigned long)
|
|
mm_str->md_bank4_cacheable_total.base_ap_view_phy,
|
|
mm_str->md_bank4_cacheable_total.size);
|
|
|
|
mm_str->md_bank4_cacheable_total.base_md_view_phy = 0x40000000
|
|
+ get_md_smem_cachable_offset(MD_SYS1)
|
|
+ mm_str->md_bank4_cacheable_total.base_ap_view_phy -
|
|
round_down(mm_str->md_bank4_cacheable_total.base_ap_view_phy,
|
|
0x00100000);
|
|
|
|
/* specially, CCB size. */
|
|
/* get_md_resv_ccb_info(md->index, &ccb_offset, &ccb_size); */
|
|
get_md_cache_region_info(SMEM_USER_CCB_START,
|
|
&ccb_offset,
|
|
&ccb_size);
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"ccb totoal :offset = 0x%x, size = 0x%x\n",
|
|
ccb_offset, ccb_size);
|
|
for (i = 0; i < (sizeof(md1_6293_cacheable)/
|
|
sizeof(struct ccci_smem_region)); i++) {
|
|
|
|
switch (md1_6293_cacheable[i].id) {
|
|
case SMEM_USER_CCB_DHL:
|
|
case SMEM_USER_CCB_MD_MONITOR:
|
|
case SMEM_USER_CCB_META:
|
|
md1_6293_cacheable[i].size =
|
|
(ccb_size > CCB_CACHE_MIN_SIZE) ?
|
|
CCB_CACHE_MIN_SIZE:0;
|
|
md1_6293_cacheable[i].offset = ccb_offset;
|
|
break;
|
|
case SMEM_USER_RAW_DHL:
|
|
case SMEM_USER_RAW_MDM:
|
|
md1_6293_cacheable[i].size =
|
|
(ccb_size > CCB_CACHE_MIN_SIZE) ?
|
|
(ccb_size - CCB_CACHE_MIN_SIZE):0;
|
|
md1_6293_cacheable[i].offset =
|
|
(ccb_size > CCB_CACHE_MIN_SIZE) ?
|
|
(ccb_offset + CCB_CACHE_MIN_SIZE):ccb_offset;
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"[%d]RAW size:%d\n", md1_6293_cacheable[i].id,
|
|
md1_6293_cacheable[i].size);
|
|
break;
|
|
case SMEM_USER_RAW_MD_CONSYS:
|
|
case SMEM_USER_RAW_USIP:
|
|
get_md_cache_region_info(md1_6293_cacheable[i].id,
|
|
&md_resv_mem_offset,
|
|
&md_resv_mem_size);
|
|
md1_6293_cacheable[i].size = md_resv_mem_size;
|
|
|
|
if (md_resv_mem_offset || md_resv_mem_size)
|
|
md1_6293_cacheable[i].offset =
|
|
md_resv_mem_offset; /* LK config */
|
|
else if (i == 0)
|
|
md1_6293_cacheable[i].offset = 0;
|
|
else
|
|
md1_6293_cacheable[i].offset =
|
|
md1_6293_cacheable[i - 1].offset +
|
|
md1_6293_cacheable[i - 1].size;
|
|
break;
|
|
case SMEM_USER_RAW_UDC_DESCTAB:
|
|
get_md_cache_region_info(md1_6293_cacheable[i].id,
|
|
&md_resv_mem_offset,
|
|
&md_resv_mem_size);
|
|
md1_6293_cacheable[i].size = md_resv_mem_size;
|
|
|
|
if (md_resv_mem_offset || md_resv_mem_size)
|
|
md1_6293_cacheable[i].offset =
|
|
md_resv_mem_offset; /* LK config */
|
|
else if (i == 0)
|
|
md1_6293_cacheable[i].offset = 0;
|
|
else
|
|
md1_6293_cacheable[i].offset =
|
|
md1_6293_cacheable[i - 1].offset +
|
|
md1_6293_cacheable[i - 1].size;
|
|
break;
|
|
default:
|
|
md1_6293_cacheable[i].size = 0;
|
|
md1_6293_cacheable[i].offset = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
mm_str->md_bank4_cacheable = md1_6293_cacheable;
|
|
/* md_smem_layout_parsing(md); */
|
|
}
|
|
#endif
|
|
|
|
#if (MD_GENERATION == 6293)
|
|
static void ccci_6293_md_smem_config_layout(struct ccci_modem *md)
|
|
{
|
|
int dfd_size;
|
|
phys_addr_t smem_amms_pos_addr = 0;
|
|
unsigned int offset_adjust_flag = 0;
|
|
unsigned int udc_noncache_size = 0;
|
|
unsigned int udc_cache_size = 0;
|
|
int size;
|
|
unsigned int md_bank4_cacheable_total_size = 0;
|
|
phys_addr_t smem_align_padding_addr = 0;
|
|
phys_addr_t md_resv_smem_addr = 0;
|
|
unsigned int i;
|
|
|
|
/* Get udc cache&noncache size */
|
|
get_md_resv_udc_info(md->index,
|
|
&udc_noncache_size, &udc_cache_size);
|
|
|
|
md_bank4_cacheable_total_size
|
|
= md->mem_layout.md_bank4_cacheable_total.size;
|
|
if (md->index == MD_SYS1) {
|
|
md->mem_layout.md_bank4_noncacheable
|
|
= md1_6293_noncacheable_fat;
|
|
md->mem_layout.md_bank4_cacheable
|
|
= md1_6293_cacheable;
|
|
/* Runtime adjust md_phy_capture and udc noncache size */
|
|
for (i = 0; i < (sizeof(md1_6293_noncacheable_fat)/
|
|
sizeof(struct ccci_smem_region)); i++) {
|
|
if (offset_adjust_flag == 1)
|
|
md1_6293_noncacheable_fat[i].offset =
|
|
md1_6293_noncacheable_fat[i-1].offset
|
|
+ md1_6293_noncacheable_fat[i-1].size;
|
|
if (md1_6293_noncacheable_fat[i].id ==
|
|
SMEM_USER_RAW_PHY_CAP) {
|
|
md1_6293_noncacheable_fat[i].size =
|
|
get_md_resv_phy_cap_size(MD_SYS1);
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"PHY size:%d\n",
|
|
md1_6293_noncacheable_fat[i].size);
|
|
}
|
|
if (md1_6293_noncacheable_fat[i].id ==
|
|
SMEM_USER_RAW_UDC_DATA) {
|
|
md1_6293_noncacheable_fat[i].size =
|
|
udc_noncache_size;
|
|
offset_adjust_flag = 1;
|
|
}
|
|
if (md1_6293_noncacheable_fat[i].id ==
|
|
SMEM_USER_RAW_DFD) {
|
|
dfd_size = get_md_smem_dfd_size(MD_SYS1);
|
|
if (dfd_size >= 0 && dfd_size !=
|
|
md1_6293_noncacheable_fat[i].size) {
|
|
md1_6293_noncacheable_fat[i].size =
|
|
dfd_size;
|
|
offset_adjust_flag = 1;
|
|
}
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"dfd size:%d\n",
|
|
md1_6293_noncacheable_fat[i].size);
|
|
}
|
|
if (md1_6293_noncacheable_fat[i].id ==
|
|
SMEM_USER_RAW_AMMS_POS) {
|
|
size = get_smem_amms_pos_size(MD_SYS1);
|
|
if (size >= 0 && size !=
|
|
md1_6293_noncacheable_fat[i].size) {
|
|
md1_6293_noncacheable_fat[i].size =
|
|
size;
|
|
offset_adjust_flag = 1;
|
|
/* free AMMS POS smem*/
|
|
smem_amms_pos_addr = md_resv_smem_addr
|
|
+ md1_6293_noncacheable_fat[i].offset;
|
|
amms_cma_free(smem_amms_pos_addr, size);
|
|
}
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"smem amms pos size:%d\n",
|
|
md1_6293_noncacheable_fat[i].size);
|
|
}
|
|
if (md1_6293_noncacheable_fat[i].id ==
|
|
SMEM_USER_RAW_ALIGN_PADDING) {
|
|
size = get_smem_align_padding_size(MD_SYS1);
|
|
if (size >= 0 && size !=
|
|
md1_6293_noncacheable_fat[i].size) {
|
|
md1_6293_noncacheable_fat[i].size =
|
|
size;
|
|
offset_adjust_flag = 1;
|
|
/* free POS padding smem*/
|
|
smem_align_padding_addr =
|
|
md_resv_smem_addr
|
|
+ md1_6293_noncacheable_fat[i].offset;
|
|
amms_cma_free(
|
|
smem_align_padding_addr,
|
|
size);
|
|
}
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"smem align padding size:%d\n",
|
|
md1_6293_noncacheable_fat[i].size);
|
|
}
|
|
|
|
}
|
|
if (md_bank4_cacheable_total_size
|
|
>= CCB_CACHE_MIN_SIZE) {
|
|
/*
|
|
* 2M is control part size,
|
|
*md1_6293_cacheable[0].size
|
|
* initial value but changed by collect_ccb_info
|
|
*/
|
|
for (i = (SMEM_USER_CCB_END -
|
|
SMEM_USER_CCB_START + 1);
|
|
i < (sizeof(md1_6293_cacheable)/
|
|
sizeof(struct ccci_smem_region)); i++) {
|
|
if (md1_6293_cacheable[i].id >
|
|
SMEM_USER_CCB_END) {
|
|
/* for rumtime udc offset */
|
|
if (md1_6293_cacheable[i].id ==
|
|
SMEM_USER_RAW_UDC_DESCTAB) {
|
|
md1_6293_cacheable[i].offset =
|
|
md1_6293_cacheable[i-1].offset +
|
|
md1_6293_cacheable[i-1].size;
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"UDC offset:%d\n",
|
|
md1_6293_cacheable[i].offset);
|
|
md1_6293_cacheable[i].size
|
|
= udc_cache_size;
|
|
continue;
|
|
}
|
|
md1_6293_cacheable[i].size =
|
|
md_bank4_cacheable_total_size -
|
|
udc_cache_size -
|
|
CCB_CACHE_MIN_SIZE;
|
|
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"RAW size:%d\n",
|
|
md1_6293_cacheable[i].size);
|
|
}
|
|
}
|
|
} else if (udc_cache_size) {
|
|
for (i = 0; i < (sizeof(md1_6293_cacheable)/
|
|
sizeof(struct ccci_smem_region)); i++) {
|
|
if (md1_6293_cacheable[i].id ==
|
|
SMEM_USER_RAW_UDC_DESCTAB) {
|
|
md1_6293_cacheable[i].offset
|
|
= 0;
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"UDC offset:%d\n",
|
|
md1_6293_cacheable[i].offset);
|
|
md1_6293_cacheable[i].size
|
|
= udc_cache_size;
|
|
continue;
|
|
}
|
|
md1_6293_cacheable[i].offset = 0;
|
|
md1_6293_cacheable[i].size = 0;
|
|
}
|
|
} else
|
|
md->mem_layout.md_bank4_cacheable = NULL;
|
|
} else
|
|
WARN_ON(1);
|
|
}
|
|
#endif
|
|
|
|
void ccci_md_config(struct ccci_modem *md)
|
|
{
|
|
phys_addr_t md_resv_mem_addr = 0,
|
|
md_resv_smem_addr = 0, md1_md3_smem_phy = 0;
|
|
unsigned int md_resv_mem_size = 0,
|
|
md_resv_smem_size = 0, md1_md3_smem_size = 0;
|
|
int amms_pos_size = 0;
|
|
phys_addr_t bank4_phy_addr;
|
|
|
|
/* setup config */
|
|
md->per_md_data.config.load_type = get_md_img_type(md->index);
|
|
if (get_modem_is_enabled(md->index))
|
|
md->per_md_data.config.setting |= MD_SETTING_ENABLE;
|
|
else
|
|
md->per_md_data.config.setting &= ~MD_SETTING_ENABLE;
|
|
|
|
/* Get memory info */
|
|
get_md_resv_mem_info(md->index, &md_resv_mem_addr,
|
|
&md_resv_mem_size, &md_resv_smem_addr, &md_resv_smem_size);
|
|
get_md1_md3_resv_smem_info(md->index, &md1_md3_smem_phy,
|
|
&md1_md3_smem_size);
|
|
/* setup memory layout */
|
|
/* MD image */
|
|
md->mem_layout.md_bank0.base_ap_view_phy = md_resv_mem_addr;
|
|
md->mem_layout.md_bank0.size = md_resv_mem_size;
|
|
/* do not remap whole region, consume too much vmalloc space */
|
|
/* Share memory */
|
|
/*
|
|
* MD bank4 is remap to nearest 32M aligned address
|
|
* assume share memoy layout is:
|
|
* |---AP/MD1--| <--MD1 bank4 0x0 (non-cacheable)
|
|
* |--MD1/MD3--| <--MD3 bank4 0x0 (non-cacheable)
|
|
* |---AP/MD3--|
|
|
* |--non-used_-|
|
|
* |--cacheable--| <-- MD1 bank4 0x8000000 (for 6292)
|
|
* this should align with LK's remap setting
|
|
*/
|
|
/* non-cacheable region */
|
|
if (md->index == MD_SYS1)
|
|
md->mem_layout.md_bank4_noncacheable_total.base_ap_view_phy
|
|
= md_resv_smem_addr;
|
|
else if (md->index == MD_SYS3)
|
|
md->mem_layout.md_bank4_noncacheable_total.base_ap_view_phy
|
|
= md1_md3_smem_phy;
|
|
md->mem_layout.md_bank4_noncacheable_total.size
|
|
= md_resv_smem_size + md1_md3_smem_size;
|
|
/* re-alloc smem for amms */
|
|
amms_pos_size = get_smem_amms_pos_size(MD_SYS1);
|
|
if (amms_pos_size > 0) {
|
|
bank4_phy_addr = amms_cma_allocate(md_resv_smem_size);
|
|
CCCI_BOOTUP_LOG(-1, TAG,
|
|
"AMMS get phy non-cache mem addr 0x%llx with size:0x%x\r\n",
|
|
(unsigned long long)bank4_phy_addr,
|
|
md_resv_smem_size);
|
|
if (bank4_phy_addr != md_resv_smem_addr) {
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"AMMS ret memory[0x%llx] miss sync with LK alloc[0x%llx]",
|
|
(unsigned long long)bank4_phy_addr,
|
|
(unsigned long long)md_resv_smem_addr);
|
|
return;
|
|
}
|
|
}
|
|
|
|
md->mem_layout.md_bank4_noncacheable_total.base_ap_view_vir =
|
|
ccci_map_phy_addr(
|
|
md->mem_layout.md_bank4_noncacheable_total.base_ap_view_phy,
|
|
md->mem_layout.md_bank4_noncacheable_total.size);
|
|
md->mem_layout.md_bank4_noncacheable_total.base_md_view_phy =
|
|
0x40000000 +
|
|
md->mem_layout.md_bank4_noncacheable_total.base_ap_view_phy -
|
|
round_down(
|
|
md->mem_layout.md_bank4_noncacheable_total.base_ap_view_phy,
|
|
0x02000000);
|
|
|
|
#if (MD_GENERATION >= 6297)
|
|
ccci_6297_md_smem_layout_config(md);
|
|
#elif (MD_GENERATION >= 6295)
|
|
ccci_6295_md_smem_layout_config(md);
|
|
#elif (MD_GENERATION >= 6292)
|
|
get_md_resv_ccb_info(md->index,
|
|
&md->mem_layout.md_bank4_cacheable_total.base_ap_view_phy,
|
|
&md->mem_layout.md_bank4_cacheable_total.size);
|
|
if (md->mem_layout.md_bank4_cacheable_total.base_ap_view_phy
|
|
&& md->mem_layout.md_bank4_cacheable_total.size)
|
|
md->mem_layout.md_bank4_cacheable_total.base_ap_view_vir
|
|
= ccci_map_phy_addr(
|
|
md->mem_layout.md_bank4_cacheable_total.base_ap_view_phy
|
|
, md->mem_layout.md_bank4_cacheable_total.size);
|
|
else
|
|
CCCI_ERROR_LOG(md->index, TAG,
|
|
"get ccb info base:%lx size:%x\n",
|
|
(unsigned long)
|
|
md->mem_layout.md_bank4_cacheable_total.base_ap_view_phy
|
|
, md->mem_layout.md_bank4_cacheable_total.size);
|
|
#if (MD_GENERATION >= 6293)
|
|
if (md->index == MD_SYS1) {
|
|
/* sync with lk:md1_bank4_cache_offset */
|
|
md->mem_layout.md_bank4_cacheable_total.base_md_view_phy
|
|
= 0x40000000 + get_md_smem_cachable_offset(MD_SYS1) +
|
|
md->mem_layout.md_bank4_cacheable_total.base_ap_view_phy
|
|
- round_down(
|
|
md->mem_layout.md_bank4_cacheable_total.base_ap_view_phy
|
|
, 0x00100000);
|
|
}
|
|
#else
|
|
if (md->index == MD_SYS1) {
|
|
md->mem_layout.md_bank4_cacheable_total.base_md_view_phy =
|
|
0x40000000 + get_md_smem_cachable_offset(MD_SYS1) +
|
|
md->mem_layout.md_bank4_cacheable_total.base_ap_view_phy
|
|
- round_down(
|
|
md->mem_layout.md_bank4_cacheable_total.base_ap_view_phy
|
|
, 0x00100000);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#if (MD_GENERATION == 6293)
|
|
CCCI_NORMAL_LOG(-1, TAG, "6293 config share memory layout\n");
|
|
ccci_6293_md_smem_config_layout(md);
|
|
#endif
|
|
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"smem info: (%lx %lx %llx %d) (%lx %lx %llx %d)\n",
|
|
(unsigned long)
|
|
md->mem_layout.md_bank4_noncacheable_total.base_ap_view_phy,
|
|
(unsigned long)
|
|
md->mem_layout.md_bank4_noncacheable_total.base_md_view_phy,
|
|
(u64)
|
|
md->mem_layout.md_bank4_noncacheable_total.base_ap_view_vir,
|
|
md->mem_layout.md_bank4_noncacheable_total.size,
|
|
(unsigned long)
|
|
md->mem_layout.md_bank4_cacheable_total.base_ap_view_phy,
|
|
(unsigned long)
|
|
md->mem_layout.md_bank4_cacheable_total.base_md_view_phy,
|
|
(u64)md->mem_layout.md_bank4_cacheable_total.base_ap_view_vir,
|
|
md->mem_layout.md_bank4_cacheable_total.size);
|
|
|
|
CCCI_BOOTUP_LOG(-1, TAG,
|
|
"[%s] init bank4 noncacheable:\n", __func__);
|
|
init_smem_regions(md->mem_layout.md_bank4_noncacheable,
|
|
md->mem_layout.md_bank4_noncacheable_total.base_ap_view_phy,
|
|
md->mem_layout.md_bank4_noncacheable_total.base_ap_view_vir,
|
|
md->mem_layout.md_bank4_noncacheable_total.base_md_view_phy);
|
|
|
|
CCCI_BOOTUP_LOG(-1, TAG,
|
|
"[%s] init bank4 cacheable:\n", __func__);
|
|
init_smem_regions(md->mem_layout.md_bank4_cacheable,
|
|
md->mem_layout.md_bank4_cacheable_total.base_ap_view_phy,
|
|
md->mem_layout.md_bank4_cacheable_total.base_ap_view_vir,
|
|
md->mem_layout.md_bank4_cacheable_total.base_md_view_phy);
|
|
|
|
/* updae image info */
|
|
md->per_md_data.img_info[IMG_MD].type = IMG_MD;
|
|
md->per_md_data.img_info[IMG_MD].address =
|
|
md->mem_layout.md_bank0.base_ap_view_phy;
|
|
md->per_md_data.img_info[IMG_DSP].type = IMG_DSP;
|
|
md->per_md_data.img_info[IMG_ARMV7].type = IMG_ARMV7;
|
|
}
|
|
|
|
int boot_md_show(int md_id, char *buf, int size)
|
|
{
|
|
int curr = 0;
|
|
|
|
if (get_modem_is_enabled(md_id))
|
|
curr += snprintf(&buf[curr], size, "md%d:%d",
|
|
md_id + 1, ccci_fsm_get_md_state(md_id));
|
|
return curr;
|
|
}
|
|
|
|
int boot_md_store(int md_id)
|
|
{
|
|
return -EACCES;
|
|
}
|
|
|
|
static void ccci_md_obj_release(struct kobject *kobj)
|
|
{
|
|
CCCI_ERROR_LOG(-1, CORE, "md kobject release\n");
|
|
}
|
|
|
|
static ssize_t ccci_md_attr_show(struct kobject *kobj, struct attribute *attr,
|
|
char *buf)
|
|
{
|
|
ssize_t len = 0;
|
|
struct ccci_md_attribute *a = container_of(attr,
|
|
struct ccci_md_attribute, attr);
|
|
|
|
if (a->show)
|
|
len = a->show(a->modem, buf);
|
|
|
|
return len;
|
|
}
|
|
|
|
static ssize_t ccci_md_attr_store(struct kobject *kobj, struct attribute *attr,
|
|
const char *buf, size_t count)
|
|
{
|
|
ssize_t len = 0;
|
|
struct ccci_md_attribute *a = container_of(attr,
|
|
struct ccci_md_attribute, attr);
|
|
|
|
if (a->store)
|
|
len = a->store(a->modem, buf, count);
|
|
|
|
return len;
|
|
}
|
|
|
|
static const struct sysfs_ops ccci_md_sysfs_ops = {
|
|
.show = ccci_md_attr_show,
|
|
.store = ccci_md_attr_store
|
|
};
|
|
|
|
static struct attribute *ccci_md_default_attrs[] = {
|
|
NULL
|
|
};
|
|
|
|
static struct kobj_type ccci_md_ktype = {
|
|
.release = ccci_md_obj_release,
|
|
.sysfs_ops = &ccci_md_sysfs_ops,
|
|
.default_attrs = ccci_md_default_attrs
|
|
};
|
|
|
|
void ccci_sysfs_add_md(int md_id, void *kobj)
|
|
{
|
|
ccci_sysfs_add_modem(md_id, (void *)kobj, (void *)&ccci_md_ktype,
|
|
boot_md_show, boot_md_store);
|
|
}
|
|
|
|
int ccci_md_register(struct ccci_modem *md)
|
|
{
|
|
int ret;
|
|
|
|
/* init per-modem sub-system */
|
|
CCCI_INIT_LOG(md->index, TAG, "register modem\n");
|
|
init_smem_user_name();
|
|
|
|
/* init modem */
|
|
ret = md->ops->init(md);
|
|
if (ret < 0)
|
|
return ret;
|
|
ccci_md_config(md);
|
|
|
|
modem_sys[md->index] = md;
|
|
ccci_sysfs_add_md(md->index, (void *)&md->kobj);
|
|
ccci_platform_init(md);
|
|
ccci_fsm_init(md->index);
|
|
ccci_port_init(md->index);
|
|
return 0;
|
|
}
|
|
|
|
int ccci_md_set_boot_data(unsigned char md_id, unsigned int data[], int len)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
unsigned int rat_flag;
|
|
unsigned int rat_str_int[MD_CFG_RAT_STR5 - MD_CFG_RAT_STR0 + 1];
|
|
unsigned int wm_idx;
|
|
char *rat_str;
|
|
int i, ret;
|
|
|
|
if (len < 0 || data == NULL)
|
|
return -1;
|
|
|
|
md->mdlg_mode = data[MD_CFG_MDLOG_MODE];
|
|
md->sbp_code = data[MD_CFG_SBP_CODE];
|
|
md->per_md_data.md_dbg_dump_flag =
|
|
data[MD_CFG_DUMP_FLAG] == MD_DBG_DUMP_INVALID ?
|
|
md->per_md_data.md_dbg_dump_flag : data[MD_CFG_DUMP_FLAG];
|
|
|
|
rat_flag = data[MD_CFG_RAT_CHK_FLAG];
|
|
if (rat_flag) {
|
|
if (check_rat_at_md_img(md_id, "C") == 0) {
|
|
char aee_info[32];
|
|
|
|
i = scnprintf(aee_info, sizeof(aee_info),
|
|
"C2K DEP check fail(0x%x)",
|
|
get_md_bin_capability(md_id));
|
|
if (i >= (sizeof(aee_info) - 1))
|
|
CCCI_ERROR_LOG(md_id, TAG, "buf not enough\n");
|
|
CCCI_ERROR_LOG(md_id, TAG, "C2K DEP check fail\n");
|
|
#ifdef CONFIG_MTK_AEE_FEATURE
|
|
aed_md_exception_api(NULL, 0, NULL,
|
|
0, aee_info, DB_OPT_DEFAULT);
|
|
#endif
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < (MD_CFG_RAT_STR5 - MD_CFG_RAT_STR0 + 1); i++)
|
|
rat_str_int[i] = data[MD_CFG_RAT_STR0 + i];
|
|
rat_str = (char *)rat_str_int;
|
|
rat_str[sizeof(rat_str_int) - 1] = 0;
|
|
|
|
wm_idx = data[MD_CFG_WM_IDX];
|
|
if (set_soc_md_rt_rat_by_idx(md_id, wm_idx) == 0) {
|
|
CCCI_NORMAL_LOG(-1, TAG, "Using WM IDX: %u\n", wm_idx);
|
|
return 0;
|
|
}
|
|
|
|
ret = set_soc_md_rt_rat_str(md_id, rat_str);
|
|
if (ret < 0) {
|
|
CCCI_ERROR_LOG(md_id, TAG,
|
|
"Current setting has mistake!!\n");
|
|
return -1;
|
|
}
|
|
|
|
if (ret == 1)
|
|
CCCI_ERROR_LOG(md_id, TAG,
|
|
"runtime rat setting abnormal, using default!!\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct ccci_mem_layout *ccci_md_get_mem(int md_id)
|
|
{
|
|
if (md_id >= MAX_MD_NUM || md_id < 0)
|
|
return NULL;
|
|
return &modem_sys[md_id]->mem_layout;
|
|
}
|
|
|
|
struct ccci_smem_region *ccci_md_get_smem_by_user_id(int md_id,
|
|
enum SMEM_USER_ID user_id)
|
|
{
|
|
struct ccci_smem_region *curr = NULL;
|
|
|
|
if (md_id >= MAX_MD_NUM || md_id < 0)
|
|
return NULL;
|
|
|
|
if (modem_sys[md_id] == NULL) {
|
|
CCCI_ERROR_LOG(md_id, TAG,
|
|
"md%d not enable/ before driver int, return NULL\n",
|
|
md_id);
|
|
return NULL;
|
|
}
|
|
|
|
curr = get_smem_by_user_id(
|
|
modem_sys[md_id]->mem_layout.md_bank4_noncacheable, user_id);
|
|
if (curr)
|
|
return curr;
|
|
curr = get_smem_by_user_id(
|
|
modem_sys[md_id]->mem_layout.md_bank4_cacheable, user_id);
|
|
return curr;
|
|
}
|
|
EXPORT_SYMBOL(ccci_md_get_smem_by_user_id);
|
|
|
|
void ccci_md_clear_smem(int md_id, int first_boot)
|
|
{
|
|
struct ccci_smem_region *region;
|
|
unsigned int size;
|
|
|
|
if (md_id < 0 || md_id >= MAX_MD_NUM) {
|
|
CCCI_ERROR_LOG(md_id, TAG, "invalid md_id %d!!\n", md_id);
|
|
return;
|
|
}
|
|
/* MD will clear share memory itself after the first boot */
|
|
clear_smem_region(modem_sys[md_id]->mem_layout.md_bank4_noncacheable,
|
|
first_boot);
|
|
clear_smem_region(modem_sys[md_id]->mem_layout.md_bank4_cacheable,
|
|
first_boot);
|
|
if (!first_boot) {
|
|
CCCI_NORMAL_LOG(-1, TAG, "clear buffer ! first_boot\n");
|
|
region = ccci_md_get_smem_by_user_id(md_id, SMEM_USER_CCB_DHL);
|
|
if (region && region->size) {
|
|
/*clear ccb data smem*/
|
|
memset_io(region->base_ap_view_vir, 0, region->size);
|
|
}
|
|
region = ccci_md_get_smem_by_user_id(md_id, SMEM_USER_RAW_DHL);
|
|
if (region && region->size) {
|
|
/* clear first 1k bytes in dsp log buffer */
|
|
size = (region->size > (128 * sizeof(long long))) ?
|
|
(128 * sizeof(long long))
|
|
: region->size;
|
|
memset_io(region->base_ap_view_vir, 0, size);
|
|
CCCI_NORMAL_LOG(-1, TAG,
|
|
"clear buffer user_id = SMEM_USER_RAW_DHL, szie = 0x%x\n",
|
|
size);
|
|
}
|
|
}
|
|
}
|
|
|
|
int ccci_md_pre_stop(unsigned char md_id, unsigned int stop_type)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
return md->ops->pre_stop(md, stop_type);
|
|
}
|
|
|
|
int ccci_md_stop(unsigned char md_id, unsigned int stop_type)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
return md->ops->stop(md, stop_type);
|
|
}
|
|
|
|
int __weak md_cd_vcore_config(unsigned int md_id, unsigned int hold_req)
|
|
{
|
|
pr_debug("[ccci/dummy] %s is not supported!\n", __func__);
|
|
return 0;
|
|
}
|
|
|
|
int ccci_md_pre_start(unsigned char md_id)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
if (md->hw_info->plat_ptr->vcore_config)
|
|
return md->hw_info->plat_ptr->vcore_config(md_id, 1);
|
|
return -1;
|
|
}
|
|
int ccci_md_start(unsigned char md_id)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
return md->ops->start(md);
|
|
}
|
|
int ccci_md_post_start(unsigned char md_id)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
if (md->hw_info->plat_ptr->vcore_config)
|
|
return md->hw_info->plat_ptr->vcore_config(md_id, 0);
|
|
return -1;
|
|
}
|
|
int ccci_md_soft_stop(unsigned char md_id, unsigned int sim_mode)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
if (md->ops->soft_stop)
|
|
return md->ops->soft_stop(md, sim_mode);
|
|
return -1;
|
|
}
|
|
int ccci_md_soft_start(unsigned char md_id, unsigned int sim_mode)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
if (md->ops->soft_start)
|
|
return md->ops->soft_start(md, sim_mode);
|
|
return -1;
|
|
}
|
|
|
|
int ccci_md_send_runtime_data(unsigned char md_id)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
return md->ops->send_runtime_data(md, CCCI_CONTROL_TX, 0, 0);
|
|
}
|
|
|
|
int ccci_md_reset_pccif(unsigned char md_id)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
if (md->ops->reset_pccif)
|
|
return md->ops->reset_pccif(md);
|
|
return -1;
|
|
}
|
|
|
|
void ccci_md_dump_info(unsigned char md_id, enum MODEM_DUMP_FLAG flag,
|
|
void *buff, int length)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
if (md)
|
|
md->ops->dump_info(md, flag, buff, length);
|
|
else
|
|
CCCI_ERROR_LOG(md_id, TAG, "invalid md_id %d!!\n", md_id);
|
|
}
|
|
EXPORT_SYMBOL(ccci_md_dump_info);
|
|
|
|
void ccci_md_exception_handshake(unsigned char md_id, int timeout)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
md->ops->ee_handshake(md, timeout);
|
|
}
|
|
|
|
int ccci_md_send_ccb_tx_notify(unsigned char md_id, int core_id)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
return md->ops->send_ccb_tx_notify(md, core_id);
|
|
}
|
|
|
|
int ccci_md_force_assert(unsigned char md_id, enum MD_FORCE_ASSERT_TYPE type,
|
|
char *param, int len)
|
|
{
|
|
int ret = 0;
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
struct ccci_force_assert_shm_fmt *ccci_fa_smem_ptr = NULL;
|
|
struct ccci_smem_region *force_assert =
|
|
ccci_md_get_smem_by_user_id(md_id, SMEM_USER_RAW_FORCE_ASSERT);
|
|
|
|
if (md->is_force_asserted != 0)
|
|
return ret;
|
|
mdee_set_ex_time_str(md_id, type, param);
|
|
if (type == MD_FORCE_ASSERT_BY_AP_MPU) {
|
|
ret = md->ops->force_assert(md, CCIF_MPU_INTR);
|
|
} else {
|
|
ccci_fa_smem_ptr = (struct ccci_force_assert_shm_fmt *)
|
|
force_assert->base_ap_view_vir;
|
|
if (ccci_fa_smem_ptr) {
|
|
ccci_fa_smem_ptr->error_code = type;
|
|
if (param != NULL && len > 0) {
|
|
if (len > force_assert->size -
|
|
sizeof(struct ccci_force_assert_shm_fmt))
|
|
len = force_assert->size -
|
|
sizeof(
|
|
struct ccci_force_assert_shm_fmt);
|
|
memcpy_toio(ccci_fa_smem_ptr->param,
|
|
param, len);
|
|
}
|
|
}
|
|
ret = md->ops->force_assert(md, CCIF_INTERRUPT);
|
|
}
|
|
md->is_force_asserted = 1;
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(ccci_md_force_assert);
|
|
|
|
static void append_runtime_feature(char **p_rt_data,
|
|
struct ccci_runtime_feature *rt_feature, void *data)
|
|
{
|
|
CCCI_DEBUG_LOG(-1, TAG,
|
|
"append rt_data %p, feature %u len %u\n",
|
|
*p_rt_data, rt_feature->feature_id,
|
|
rt_feature->data_len);
|
|
memcpy_toio(*p_rt_data, rt_feature,
|
|
sizeof(struct ccci_runtime_feature));
|
|
*p_rt_data += sizeof(struct ccci_runtime_feature);
|
|
if (data != NULL) {
|
|
memcpy_toio(*p_rt_data, data, rt_feature->data_len);
|
|
*p_rt_data += rt_feature->data_len;
|
|
}
|
|
}
|
|
|
|
struct ccci_tag_bootmode {
|
|
u32 size;
|
|
u32 tag;
|
|
u32 bootmode;
|
|
u32 boottype;
|
|
};
|
|
|
|
static unsigned int get_boot_mode_from_dts(void)
|
|
{
|
|
struct device_node *np_chosen = NULL;
|
|
struct ccci_tag_bootmode *tag = NULL;
|
|
u32 bootmode = NORMAL_BOOT_ID;
|
|
|
|
np_chosen = of_find_node_by_path("/chosen");
|
|
if (!np_chosen) {
|
|
CCCI_ERROR_LOG(-1, TAG, "warning: not find node: '/chosen'\n");
|
|
|
|
np_chosen = of_find_node_by_path("/chosen@0");
|
|
if (!np_chosen) {
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"[%s] error: not find node: '/chosen@0'\n",
|
|
__func__);
|
|
return NORMAL_BOOT_ID;
|
|
}
|
|
}
|
|
|
|
tag = (struct ccci_tag_bootmode *)
|
|
of_get_property(np_chosen, "atag,boot", NULL);
|
|
if (!tag) {
|
|
CCCI_ERROR_LOG(-1, TAG,
|
|
"[%s] error: not find tag: 'atag,boot';\n", __func__);
|
|
return NORMAL_BOOT_ID;
|
|
}
|
|
|
|
if (tag->bootmode == META_BOOT || tag->bootmode == ADVMETA_BOOT)
|
|
bootmode = META_BOOT_ID;
|
|
|
|
else if (tag->bootmode == FACTORY_BOOT ||
|
|
tag->bootmode == ATE_FACTORY_BOOT)
|
|
bootmode = FACTORY_BOOT_ID;
|
|
|
|
CCCI_NORMAL_LOG(-1, TAG,
|
|
"[%s] bootmode: 0x%x boottype: 0x%x; return: 0x%x\n",
|
|
__func__, tag->bootmode, tag->boottype, bootmode);
|
|
|
|
return bootmode;
|
|
}
|
|
|
|
/*
|
|
*booting_start_id bit mapping:
|
|
* |31---------16|15-----------8|7---------0|
|
|
* | mdwait_time | logging_mode | boot_mode |
|
|
* mdwait_time: getting from property at user space
|
|
* logging_mode: usb/sd/idl mode, setting at user space
|
|
* boot_mode: factory/meta/normal mode
|
|
*/
|
|
static unsigned int get_booting_start_id(struct ccci_modem *md)
|
|
{
|
|
enum LOGGING_MODE mdlog_flag = MODE_IDLE;
|
|
u32 booting_start_id = 0;
|
|
|
|
mdlog_flag = (md->mdlg_mode & 0x0000ffff);
|
|
|
|
booting_start_id = (((char)mdlog_flag << 8)
|
|
| get_boot_mode_from_dts());
|
|
|
|
booting_start_id |= (md->mdlg_mode & 0xffff0000);
|
|
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"%s 0x%x\n", __func__, booting_start_id);
|
|
return booting_start_id;
|
|
}
|
|
|
|
static void config_ap_side_feature(struct ccci_modem *md,
|
|
struct md_query_ap_feature *md_feature)
|
|
{
|
|
unsigned int udc_noncache_size = 0, udc_cache_size = 0;
|
|
#if (MD_GENERATION >= 6297)
|
|
struct ccci_smem_region *region;
|
|
#endif
|
|
|
|
md->runtime_version = AP_MD_HS_V2;
|
|
md_feature->feature_set[BOOT_INFO].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[EXCEPTION_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
#if (MD_GENERATION >= 6293)
|
|
md_feature->feature_set[CCIF_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
#else
|
|
if (md->index == MD_SYS1)
|
|
md_feature->feature_set[CCIF_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
else
|
|
md_feature->feature_set[CCIF_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
#endif
|
|
|
|
#ifdef FEATURE_SCP_CCCI_SUPPORT
|
|
md_feature->feature_set[CCISM_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
#else
|
|
md_feature->feature_set[CCISM_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
|
|
#if (MD_GENERATION >= 6293)
|
|
md_feature->feature_set[CCISM_SHARE_MEMORY_EXP].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
if ((md->index == MD_SYS1) && ((get_md_resv_phy_cap_size(MD_SYS1) > 0)
|
|
|| (get_md_resv_sib_size(MD_SYS1) > 0)))
|
|
md_feature->feature_set[MD_PHY_CAPTURE].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
else
|
|
md_feature->feature_set[MD_PHY_CAPTURE].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[MD_CONSYS_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[MD1MD3_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
|
|
#if (MD_GENERATION >= 6297)
|
|
region =
|
|
ccci_md_get_smem_by_user_id(MD_SYS1, SMEM_USER_RAW_UDC_DESCTAB);
|
|
if (region)
|
|
udc_cache_size = region->size;
|
|
else
|
|
udc_cache_size = 0;
|
|
|
|
region = ccci_md_get_smem_by_user_id(MD_SYS1, SMEM_USER_RAW_UDC_DATA);
|
|
if (region)
|
|
udc_noncache_size = region->size;
|
|
else
|
|
udc_noncache_size = 0;
|
|
if (udc_noncache_size > 0 && udc_cache_size > 0)
|
|
md_feature->feature_set[UDC_RAW_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
else
|
|
md_feature->feature_set[UDC_RAW_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
#else
|
|
get_md_resv_udc_info(md->index, &udc_noncache_size, &udc_cache_size);
|
|
if (udc_noncache_size > 0 && udc_cache_size > 0)
|
|
md_feature->feature_set[UDC_RAW_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
else
|
|
md_feature->feature_set[UDC_RAW_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
if ((md->index == MD_SYS1) && (get_smem_amms_pos_size(MD_SYS1) > 0))
|
|
md_feature->feature_set[MD_POS_SHARE_MEMORY].support_mask =
|
|
CCCI_FEATURE_MUST_SUPPORT;
|
|
else
|
|
md_feature->feature_set[MD_POS_SHARE_MEMORY].support_mask =
|
|
CCCI_FEATURE_NOT_SUPPORT;
|
|
#else
|
|
md_feature->feature_set[CCISM_SHARE_MEMORY_EXP].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[MD_PHY_CAPTURE].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[MD_CONSYS_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
if (get_modem_is_enabled(MD_SYS3))
|
|
md_feature->feature_set[MD1MD3_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
else
|
|
md_feature->feature_set[MD1MD3_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
|
|
#endif
|
|
|
|
#ifdef CUST_FT_BIGDATA
|
|
/* only support for mt6853 */
|
|
md_feature->feature_set[CCCI_MD_BIGDATA_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[CCCI_MD_IPCA_BIGDATA_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
#else
|
|
md_feature->feature_set[CCCI_MD_BIGDATA_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[CCCI_MD_IPCA_BIGDATA_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
|
|
#if (MD_GENERATION >= 6293)
|
|
/* notice: CCB_SHARE_MEMORY should be set to support
|
|
* when at least one CCB region exists
|
|
*/
|
|
md_feature->feature_set[CCB_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[DHL_RAW_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[LWA_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[DT_NETD_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[DT_USB_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[AUDIO_RAW_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
#elif (MD_GENERATION == 6292)
|
|
/* notice: CCB_SHARE_MEMORY should be set to support
|
|
* when at least one CCB region exists
|
|
*/
|
|
md_feature->feature_set[CCB_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[DHL_RAW_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[LWA_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[DT_NETD_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[DT_USB_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[AUDIO_RAW_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
#else
|
|
md_feature->feature_set[CCB_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[DHL_RAW_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[LWA_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[DT_NETD_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[DT_USB_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
md_feature->feature_set[AUDIO_RAW_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
md_feature->feature_set[MISC_INFO_HIF_DMA_REMAP].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[MULTI_MD_MPU].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
|
|
#ifdef ENABLE_32K_CLK_LESS
|
|
if (mtk_crystal_exist_status()) {
|
|
CCCI_DEBUG_LOG(md->index, TAG,
|
|
"MISC_32K_LESS no support, mtk_crystal_exist_status 1\n");
|
|
md_feature->feature_set[MISC_INFO_RTC_32K_LESS].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
} else {
|
|
CCCI_DEBUG_LOG(md->index, TAG, "MISC_32K_LESS support\n");
|
|
md_feature->feature_set[MISC_INFO_RTC_32K_LESS].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
}
|
|
#else
|
|
CCCI_DEBUG_LOG(md->index, TAG, "ENABLE_32K_CLK_LESS disabled\n");
|
|
md_feature->feature_set[MISC_INFO_RTC_32K_LESS].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
md_feature->feature_set[MISC_INFO_RANDOM_SEED_NUM].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[MISC_INFO_GPS_COCLOCK].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[MISC_INFO_SBP_ID].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[MISC_INFO_CCCI].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[MISC_INFO_CLIB_TIME].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[MISC_INFO_C2K].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[MD_IMAGE_START_MEMORY].support_mask
|
|
= CCCI_FEATURE_OPTIONAL_SUPPORT;
|
|
md_feature->feature_set[EE_AFTER_EPOF].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
md_feature->feature_set[AP_CCMNI_MTU].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
|
|
#ifdef ENABLE_FAST_HEADER
|
|
md_feature->feature_set[CCCI_FAST_HEADER].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
#endif
|
|
|
|
/* tire1 features */
|
|
#ifdef FEATURE_TC1_CUSTOMER_VAL
|
|
md_feature->feature_set[MISC_INFO_CUSTOMER_VAL].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
#else
|
|
md_feature->feature_set[MISC_INFO_CUSTOMER_VAL].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
#ifdef FEATURE_SYNC_C2K_MEID
|
|
md_feature->feature_set[MISC_INFO_C2K_MEID].support_mask
|
|
= CCCI_FEATURE_MUST_SUPPORT;
|
|
#else
|
|
md_feature->feature_set[MISC_INFO_C2K_MEID].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
md_feature->feature_set[SMART_LOGGING_SHARE_MEMORY].support_mask
|
|
= CCCI_FEATURE_NOT_SUPPORT;
|
|
|
|
#if (MD_GENERATION >= 6295)
|
|
md_feature->feature_set[MD_USIP_SHARE_MEMORY].support_mask =
|
|
CCCI_FEATURE_OPTIONAL_SUPPORT;
|
|
#else
|
|
md_feature->feature_set[MD_USIP_SHARE_MEMORY].support_mask =
|
|
CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
|
|
md_feature->feature_set[MD_MTEE_SHARE_MEMORY_ENABLE].support_mask
|
|
= CCCI_FEATURE_OPTIONAL_SUPPORT;
|
|
md_feature->feature_set[AP_DEBUG_LEVEL].support_mask =
|
|
CCCI_FEATURE_MUST_SUPPORT;
|
|
#if (MD_GENERATION >= 6297)
|
|
md_feature->feature_set[MD_WIFI_PROXY_SHARE_MEMORY].support_mask =
|
|
CCCI_FEATURE_OPTIONAL_SUPPORT;
|
|
#else
|
|
md_feature->feature_set[MD_WIFI_PROXY_SHARE_MEMORY].support_mask =
|
|
CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
|
|
|
|
#if (MD_GENERATION >= 6297)
|
|
md_feature->feature_set[NVRAM_CACHE_SHARE_MEMORY].support_mask =
|
|
CCCI_FEATURE_MUST_SUPPORT;
|
|
#else
|
|
md_feature->feature_set[NVRAM_CACHE_SHARE_MEMORY].support_mask =
|
|
CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
|
|
/* This item is reserved,only SP use */
|
|
#ifdef ENABLE_SECURITY_SHARE_MEMORY
|
|
md_feature->feature_set[SECURITY_SHARE_MEMORY].support_mask =
|
|
CCCI_FEATURE_MUST_SUPPORT;
|
|
#else
|
|
md_feature->feature_set[SECURITY_SHARE_MEMORY].support_mask =
|
|
CCCI_FEATURE_NOT_SUPPORT;
|
|
#endif
|
|
|
|
#if (MD_GENERATION >= 6297)
|
|
md_feature->feature_set[MD_MEM_AP_VIEW_INF].support_mask =
|
|
CCCI_FEATURE_OPTIONAL_SUPPORT;
|
|
#endif
|
|
|
|
#ifdef CUST_FT_EE_TRIGGER_REBOOT
|
|
md_feature->feature_set[AP_DEBUG_LEVEL].support_mask =
|
|
CCCI_FEATURE_MUST_SUPPORT;
|
|
#endif
|
|
}
|
|
|
|
unsigned int align_to_2_power(unsigned int n)
|
|
{
|
|
n--;
|
|
n |= n >> 1;
|
|
n |= n >> 2;
|
|
n |= n >> 4;
|
|
n |= n >> 8;
|
|
n |= n >> 16;
|
|
n++;
|
|
|
|
return n;
|
|
}
|
|
|
|
#if (MD_GENERATION >= 6297)
|
|
static void ccci_sib_region_set_runtime(struct ccci_runtime_feature *rt_feature,
|
|
struct ccci_runtime_share_memory *rt_shm)
|
|
{
|
|
phys_addr_t md_sib_mem_addr;
|
|
unsigned int md_sib_mem_size;
|
|
|
|
get_md_sib_mem_info(&md_sib_mem_addr, &md_sib_mem_size);
|
|
rt_feature->data_len =
|
|
sizeof(struct ccci_runtime_share_memory);
|
|
rt_shm->addr = 0;
|
|
if (md_sib_mem_addr)
|
|
rt_shm->size = md_sib_mem_size;
|
|
else
|
|
rt_shm->size = 0;
|
|
}
|
|
|
|
static void ccci_md_mem_inf_prepare(int md_id,
|
|
struct ccci_runtime_feature *rt_ft,
|
|
struct ccci_runtime_md_mem_ap_addr tbl[], unsigned int num)
|
|
{
|
|
unsigned int add_num = 0;
|
|
phys_addr_t ro_rw_base, ncrw_base, crw_base;
|
|
u32 ro_rw_size, ncrw_size, crw_size;
|
|
int ret;
|
|
|
|
ret = get_md_resv_mem_info(md_id, &ro_rw_base, &ro_rw_size,
|
|
&ncrw_base, &ncrw_size);
|
|
if (ret < 0) {
|
|
CCCI_REPEAT_LOG(md_id, TAG, "%s get mdrorw and srw fail\n",
|
|
__func__);
|
|
return;
|
|
}
|
|
ret = get_md_resv_csmem_info(md_id, &crw_base, &crw_size);
|
|
if (ret < 0) {
|
|
CCCI_REPEAT_LOG(md_id, TAG, "%s get cache smem info fail\n",
|
|
__func__);
|
|
return;
|
|
}
|
|
|
|
/* Add bank 0 and bank 1 */
|
|
if (add_num < num) {
|
|
tbl[add_num].md_view_phy = 0;
|
|
tbl[add_num].size = ro_rw_size;
|
|
tbl[add_num].ap_view_phy_lo32 = (u32)ro_rw_base;
|
|
tbl[add_num].ap_view_phy_hi32 = (u32)((unsigned long long)ro_rw_base >> 32);
|
|
add_num++;
|
|
} else
|
|
CCCI_REPEAT_LOG(md_id, TAG, "%s add bank0/1 fail(%d)\n",
|
|
__func__, add_num);
|
|
|
|
if (add_num < num) {
|
|
tbl[add_num].md_view_phy = 0x40000000;
|
|
tbl[add_num].size = ncrw_size;
|
|
tbl[add_num].ap_view_phy_lo32 = (u32)ncrw_base;
|
|
tbl[add_num].ap_view_phy_hi32 = (u32)((unsigned long long)ncrw_base >> 32);
|
|
add_num++;
|
|
} else
|
|
CCCI_REPEAT_LOG(md_id, TAG, "%s add bank4 nc fail(%d)\n",
|
|
__func__, add_num);
|
|
|
|
if (add_num < num) {
|
|
tbl[add_num].md_view_phy = 0x40000000 +
|
|
get_md_smem_cachable_offset(md_id);
|
|
tbl[add_num].size = crw_size;
|
|
tbl[add_num].ap_view_phy_lo32 = (u32)crw_base;
|
|
tbl[add_num].ap_view_phy_hi32 = (u32)((unsigned long long)crw_base >> 32);
|
|
add_num++;
|
|
} else
|
|
CCCI_REPEAT_LOG(md_id, TAG, "%s add bank4 c fail(%d)\n",
|
|
__func__, add_num);
|
|
rt_ft->feature_id = MD_MEM_AP_VIEW_INF;
|
|
rt_ft->data_len = sizeof(struct ccci_runtime_md_mem_ap_addr) * add_num;
|
|
}
|
|
#endif
|
|
|
|
static void ccci_smem_region_set_runtime(unsigned char md_id, unsigned int id,
|
|
struct ccci_runtime_feature *rt_feature,
|
|
struct ccci_runtime_share_memory *rt_shm)
|
|
{
|
|
struct ccci_smem_region *region = ccci_md_get_smem_by_user_id(md_id,
|
|
id);
|
|
|
|
if (region) {
|
|
rt_feature->data_len =
|
|
sizeof(struct ccci_runtime_share_memory);
|
|
rt_shm->addr = region->base_md_view_phy;
|
|
rt_shm->size = region->size;
|
|
} else {
|
|
rt_feature->data_len =
|
|
sizeof(struct ccci_runtime_share_memory);
|
|
rt_shm->addr = 0;
|
|
rt_shm->size = 0;
|
|
}
|
|
}
|
|
|
|
int ccci_md_prepare_runtime_data(unsigned char md_id, unsigned char *data,
|
|
int length)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
u8 i = 0;
|
|
u32 total_len;
|
|
int j;
|
|
/*runtime data buffer */
|
|
struct ccci_smem_region *region = NULL;
|
|
struct ccci_smem_region *rt_data_region =
|
|
ccci_md_get_smem_by_user_id(md_id, SMEM_USER_RAW_RUNTIME_DATA);
|
|
char *rt_data = (char *)rt_data_region->base_ap_view_vir;
|
|
|
|
struct ccci_runtime_feature rt_feature;
|
|
/*runtime feature type */
|
|
struct ccci_runtime_share_memory rt_shm;
|
|
struct ccci_misc_info_element rt_f_element;
|
|
#if (MD_GENERATION >= 6297)
|
|
struct ccci_runtime_md_mem_ap_addr rt_mem_view[4];
|
|
#endif
|
|
struct md_query_ap_feature *md_feature = NULL;
|
|
struct md_query_ap_feature md_feature_ap;
|
|
struct ccci_runtime_boot_info boot_info;
|
|
unsigned int random_seed = 0;
|
|
struct timeval t;
|
|
unsigned int c2k_flags = 0;
|
|
#ifdef CUST_FT_EE_TRIGGER_REBOOT
|
|
int debug_level;
|
|
#endif
|
|
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"prepare_runtime_data AP total %u features\n",
|
|
MD_RUNTIME_FEATURE_ID_MAX);
|
|
|
|
memset(&md_feature_ap, 0, sizeof(struct md_query_ap_feature));
|
|
config_ap_side_feature(md, &md_feature_ap);
|
|
|
|
md_feature = (struct md_query_ap_feature *)(data +
|
|
sizeof(struct ccci_header));
|
|
|
|
if (md_feature->head_pattern != MD_FEATURE_QUERY_PATTERN ||
|
|
md_feature->tail_pattern != MD_FEATURE_QUERY_PATTERN) {
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"md_feature pattern is wrong: head 0x%x, tail 0x%x\n",
|
|
md_feature->head_pattern, md_feature->tail_pattern);
|
|
if (md->index == MD_SYS3)
|
|
md->ops->dump_info(md, DUMP_FLAG_CCIF, NULL, 0);
|
|
return -1;
|
|
}
|
|
|
|
for (i = BOOT_INFO; i < FEATURE_COUNT; i++) {
|
|
memset(&rt_feature, 0, sizeof(struct ccci_runtime_feature));
|
|
memset(&rt_shm, 0, sizeof(struct ccci_runtime_share_memory));
|
|
memset(&rt_f_element, 0, sizeof(struct ccci_misc_info_element));
|
|
rt_feature.feature_id = i;
|
|
if (md_feature->feature_set[i].support_mask ==
|
|
CCCI_FEATURE_MUST_SUPPORT &&
|
|
md_feature_ap.feature_set[i].support_mask <
|
|
CCCI_FEATURE_MUST_SUPPORT) {
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"feature %u not support for AP\n",
|
|
rt_feature.feature_id);
|
|
return -1;
|
|
}
|
|
|
|
CCCI_DEBUG_LOG(md->index, TAG,
|
|
"ftr %u mask %u, ver %u\n",
|
|
rt_feature.feature_id,
|
|
md_feature->feature_set[i].support_mask,
|
|
md_feature->feature_set[i].version);
|
|
|
|
if (md_feature->feature_set[i].support_mask ==
|
|
CCCI_FEATURE_NOT_EXIST) {
|
|
rt_feature.support_info =
|
|
md_feature->feature_set[i];
|
|
} else if (md_feature->feature_set[i].support_mask ==
|
|
CCCI_FEATURE_MUST_SUPPORT) {
|
|
rt_feature.support_info =
|
|
md_feature->feature_set[i];
|
|
} else if (md_feature->feature_set[i].support_mask ==
|
|
CCCI_FEATURE_OPTIONAL_SUPPORT) {
|
|
if (md_feature->feature_set[i].version ==
|
|
md_feature_ap.feature_set[i].version &&
|
|
md_feature_ap.feature_set[i].support_mask >=
|
|
CCCI_FEATURE_MUST_SUPPORT) {
|
|
rt_feature.support_info.support_mask =
|
|
CCCI_FEATURE_MUST_SUPPORT;
|
|
rt_feature.support_info.version =
|
|
md_feature_ap.feature_set[i].version;
|
|
} else {
|
|
rt_feature.support_info.support_mask =
|
|
CCCI_FEATURE_NOT_SUPPORT;
|
|
rt_feature.support_info.version =
|
|
md_feature_ap.feature_set[i].version;
|
|
}
|
|
} else if (md_feature->feature_set[i].support_mask ==
|
|
CCCI_FEATURE_SUPPORT_BACKWARD_COMPAT) {
|
|
if (md_feature->feature_set[i].version >=
|
|
md_feature_ap.feature_set[i].version) {
|
|
rt_feature.support_info.support_mask =
|
|
CCCI_FEATURE_MUST_SUPPORT;
|
|
rt_feature.support_info.version =
|
|
md_feature_ap.feature_set[i].version;
|
|
} else {
|
|
rt_feature.support_info.support_mask =
|
|
CCCI_FEATURE_NOT_SUPPORT;
|
|
rt_feature.support_info.version =
|
|
md_feature_ap.feature_set[i].version;
|
|
}
|
|
}
|
|
|
|
if (rt_feature.support_info.support_mask ==
|
|
CCCI_FEATURE_MUST_SUPPORT) {
|
|
switch (rt_feature.feature_id) {
|
|
case BOOT_INFO:
|
|
memset(&boot_info, 0, sizeof(boot_info));
|
|
rt_feature.data_len = sizeof(boot_info);
|
|
boot_info.boot_channel = CCCI_CONTROL_RX;
|
|
boot_info.booting_start_id =
|
|
get_booting_start_id(md);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &boot_info);
|
|
break;
|
|
case EXCEPTION_SHARE_MEMORY:
|
|
region = ccci_md_get_smem_by_user_id(md_id,
|
|
SMEM_USER_RAW_MDCCCI_DBG);
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_runtime_share_memory);
|
|
rt_shm.addr = region->base_md_view_phy;
|
|
rt_shm.size = CCCI_EE_SMEM_TOTAL_SIZE;
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
case CCIF_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_CCISM_MCU,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
case CCISM_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_CCISM_SCP,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
case CCB_SHARE_MEMORY:
|
|
/* notice: we should add up
|
|
* all CCB region size here
|
|
*/
|
|
/* ctrl control first */
|
|
region = ccci_md_get_smem_by_user_id(md_id,
|
|
SMEM_USER_RAW_CCB_CTRL);
|
|
if (region) {
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_misc_info_element);
|
|
rt_f_element.feature[0] =
|
|
region->base_md_view_phy;
|
|
rt_f_element.feature[1] =
|
|
region->size;
|
|
}
|
|
/* ccb data second */
|
|
for (j = SMEM_USER_CCB_START;
|
|
j <= SMEM_USER_CCB_END; j++) {
|
|
region = ccci_md_get_smem_by_user_id(
|
|
md_id, j);
|
|
if (j == SMEM_USER_CCB_START
|
|
&& region) {
|
|
rt_f_element.feature[2] =
|
|
region->base_md_view_phy;
|
|
rt_f_element.feature[3] = 0;
|
|
} else if (j == SMEM_USER_CCB_START
|
|
&& region == NULL)
|
|
break;
|
|
if (region)
|
|
rt_f_element.feature[3] +=
|
|
region->size;
|
|
}
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"ccb data size (include dsp raw): %X\n",
|
|
rt_f_element.feature[3]);
|
|
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case DHL_RAW_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_RAW_DHL,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
case LWA_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_RAW_LWA,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
case MULTI_MD_MPU:
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"new version md use multi-MPU.\n");
|
|
md->multi_md_mpu_support = 1;
|
|
rt_feature.data_len = 0;
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, NULL);
|
|
break;
|
|
case DT_NETD_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_RAW_NETD,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
case DT_USB_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_RAW_USB,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
case SMART_LOGGING_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_SMART_LOGGING,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
case MD1MD3_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_RAW_MD2MD,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
|
|
case MISC_INFO_HIF_DMA_REMAP:
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_misc_info_element);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case MISC_INFO_RTC_32K_LESS:
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_misc_info_element);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case MISC_INFO_RANDOM_SEED_NUM:
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_misc_info_element);
|
|
get_random_bytes(&random_seed, sizeof(int));
|
|
rt_f_element.feature[0] = random_seed;
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case MISC_INFO_GPS_COCLOCK:
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_misc_info_element);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case MISC_INFO_SBP_ID:
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_misc_info_element);
|
|
rt_f_element.feature[0] = md->sbp_code;
|
|
rt_f_element.feature[1] =
|
|
get_soc_md_rt_rat(MD_SYS1);
|
|
CCCI_BOOTUP_LOG(md->index, TAG,
|
|
"sbp=0x%x,wmid[0x%x]\n",
|
|
rt_f_element.feature[0],
|
|
rt_f_element.feature[1]);
|
|
CCCI_NORMAL_LOG(md->index, TAG,
|
|
"sbp=0x%x,wmid[0x%x]\n",
|
|
rt_f_element.feature[0],
|
|
rt_f_element.feature[1]);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case MISC_INFO_CCCI:
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_misc_info_element);
|
|
/* sequence check */
|
|
rt_f_element.feature[0] |= (1 << 0);
|
|
/* polling MD status */
|
|
rt_f_element.feature[0] |= (1 << 1);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case MISC_INFO_CLIB_TIME:
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_misc_info_element);
|
|
do_gettimeofday(&t);
|
|
|
|
/*set seconds information */
|
|
rt_f_element.feature[0] =
|
|
((unsigned int *)&t.tv_sec)[0];
|
|
rt_f_element.feature[1] =
|
|
((unsigned int *)&t.tv_sec)[1];
|
|
/*sys_tz.tz_minuteswest; */
|
|
rt_f_element.feature[2] = current_time_zone;
|
|
/*not used for now */
|
|
rt_f_element.feature[3] = sys_tz.tz_dsttime;
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case MISC_INFO_C2K:
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_misc_info_element);
|
|
c2k_flags = 0;
|
|
|
|
if (check_rat_at_rt_setting(MD_SYS1, "C"))
|
|
c2k_flags |= (1 << 2);
|
|
CCCI_NORMAL_LOG(md_id, TAG,
|
|
"c2k_flags 0x%X; MD_GENERATION: %d\n",
|
|
c2k_flags, MD_GENERATION);
|
|
|
|
rt_f_element.feature[0] = c2k_flags;
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case MD_IMAGE_START_MEMORY:
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_runtime_share_memory);
|
|
rt_shm.addr =
|
|
md->per_md_data.img_info[IMG_MD].address;
|
|
rt_shm.size =
|
|
md->per_md_data.img_info[IMG_MD].size;
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
case EE_AFTER_EPOF:
|
|
rt_feature.data_len =
|
|
sizeof(struct ccci_misc_info_element);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case AP_CCMNI_MTU:
|
|
rt_feature.data_len =
|
|
sizeof(unsigned int);
|
|
random_seed =
|
|
NET_RX_BUF - sizeof(struct ccci_header);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &random_seed);
|
|
break;
|
|
case CCCI_FAST_HEADER:
|
|
rt_feature.data_len = sizeof(unsigned int);
|
|
random_seed = 1;
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &random_seed);
|
|
break;
|
|
case AUDIO_RAW_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_RAW_AUDIO,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_shm);
|
|
break;
|
|
case CCISM_SHARE_MEMORY_EXP:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_CCISM_MCU_EXP,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&rt_shm);
|
|
break;
|
|
#ifdef CUST_FT_BIGDATA
|
|
case CCCI_MD_BIGDATA_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_MD_BIGDATA,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&rt_shm);
|
|
break;
|
|
case CCCI_MD_IPCA_BIGDATA_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_MD_IPCA_BIGDATA,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&rt_shm);
|
|
break;
|
|
#endif
|
|
case MD_PHY_CAPTURE:
|
|
#if (MD_GENERATION >= 6297)
|
|
ccci_sib_region_set_runtime(&rt_feature,
|
|
&rt_shm);
|
|
#else
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_RAW_PHY_CAP,
|
|
&rt_feature, &rt_shm);
|
|
#endif
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&rt_shm);
|
|
break;
|
|
case UDC_RAW_SHARE_MEMORY:
|
|
region = ccci_md_get_smem_by_user_id(md_id,
|
|
SMEM_USER_RAW_UDC_DATA);
|
|
if (region) {
|
|
rt_feature.data_len = sizeof(
|
|
struct ccci_misc_info_element);
|
|
rt_f_element.feature[0] =
|
|
region->base_md_view_phy;
|
|
rt_f_element.feature[1] =
|
|
region->size;
|
|
} else {
|
|
rt_feature.data_len = sizeof(
|
|
struct ccci_misc_info_element);
|
|
rt_f_element.feature[0] = 0;
|
|
rt_f_element.feature[1] = 0;
|
|
}
|
|
region = ccci_md_get_smem_by_user_id(md_id,
|
|
SMEM_USER_RAW_UDC_DESCTAB);
|
|
if (region) {
|
|
rt_feature.data_len = sizeof(
|
|
struct ccci_misc_info_element);
|
|
rt_f_element.feature[2] =
|
|
region->base_md_view_phy;
|
|
rt_f_element.feature[3] =
|
|
region->size;
|
|
} else {
|
|
rt_feature.data_len = sizeof(
|
|
struct ccci_misc_info_element);
|
|
rt_f_element.feature[2] = 0;
|
|
rt_f_element.feature[3] = 0;
|
|
}
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &rt_f_element);
|
|
break;
|
|
case MD_CONSYS_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_RAW_MD_CONSYS,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&rt_shm);
|
|
break;
|
|
case MD_USIP_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_RAW_USIP,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&rt_shm);
|
|
break;
|
|
case MD_MTEE_SHARE_MEMORY_ENABLE:
|
|
rt_feature.data_len = sizeof(unsigned int);
|
|
/* use the random_seed as temp_u32 value */
|
|
random_seed = get_mtee_is_enabled();
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&random_seed);
|
|
break;
|
|
case MD_POS_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_RAW_AMMS_POS,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&rt_shm);
|
|
break;
|
|
#if (MD_GENERATION >= 6297)
|
|
case MD_WIFI_PROXY_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_MD_WIFI_PROXY,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&rt_shm);
|
|
break;
|
|
case NVRAM_CACHE_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_MD_NVRAM_CACHE,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&rt_shm);
|
|
break;
|
|
case MD_MEM_AP_VIEW_INF:
|
|
ccci_md_mem_inf_prepare(md_id, &rt_feature,
|
|
rt_mem_view, 4);
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
rt_mem_view);
|
|
break;
|
|
#endif
|
|
#ifdef CUST_FT_EE_TRIGGER_REBOOT
|
|
case AP_DEBUG_LEVEL:
|
|
rt_feature.data_len = sizeof(int);
|
|
debug_level = ccci_get_ap_debug_level();
|
|
CCCI_ERROR_LOG(-1, TAG, "AP_DEBUG_LEVEL:%d\n", debug_level);
|
|
append_runtime_feature(&rt_data,
|
|
&rt_feature, &debug_level);
|
|
break;
|
|
#endif
|
|
#ifdef ENABLE_SECURITY_SHARE_MEMORY
|
|
case SECURITY_SHARE_MEMORY:
|
|
ccci_smem_region_set_runtime(md_id,
|
|
SMEM_USER_SECURITY_SMEM,
|
|
&rt_feature, &rt_shm);
|
|
append_runtime_feature(&rt_data, &rt_feature,
|
|
&rt_shm);
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
};
|
|
} else {
|
|
rt_feature.data_len = 0;
|
|
append_runtime_feature(&rt_data, &rt_feature, NULL);
|
|
}
|
|
|
|
}
|
|
|
|
total_len = rt_data - (char *)rt_data_region->base_ap_view_vir;
|
|
CCCI_BOOTUP_DUMP_LOG(md->index, TAG, "AP runtime data\n");
|
|
ccci_util_mem_dump(md->index, CCCI_DUMP_BOOTUP,
|
|
rt_data_region->base_ap_view_vir, total_len);
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct ccci_runtime_feature *ccci_md_get_rt_feature_by_id(unsigned char md_id,
|
|
u8 feature_id, u8 ap_query_md)
|
|
{
|
|
struct ccci_runtime_feature *rt_feature = NULL;
|
|
u8 i = 0;
|
|
u8 max_id = 0;
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
struct ccci_smem_region *rt_data_region =
|
|
ccci_md_get_smem_by_user_id(md_id, SMEM_USER_RAW_RUNTIME_DATA);
|
|
|
|
if (ap_query_md) {
|
|
rt_feature = (struct ccci_runtime_feature *)
|
|
(rt_data_region->base_ap_view_vir +
|
|
CCCI_SMEM_SIZE_RUNTIME_AP);
|
|
max_id = AP_RUNTIME_FEATURE_ID_MAX;
|
|
} else {
|
|
rt_feature = (struct ccci_runtime_feature *)
|
|
(rt_data_region->base_ap_view_vir);
|
|
max_id = MD_RUNTIME_FEATURE_ID_MAX;
|
|
}
|
|
while (i < max_id) {
|
|
if (feature_id == rt_feature->feature_id)
|
|
return rt_feature;
|
|
if (rt_feature->data_len >
|
|
sizeof(struct ccci_misc_info_element)) {
|
|
CCCI_ERROR_LOG(md->index, TAG,
|
|
"get invalid feature, id %u\n", i);
|
|
return NULL;
|
|
}
|
|
rt_feature = (struct ccci_runtime_feature *)
|
|
((char *)rt_feature->data + rt_feature->data_len);
|
|
i++;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int ccci_md_parse_rt_feature(unsigned char md_id,
|
|
struct ccci_runtime_feature *rt_feature, void *data, u32 data_len)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
if (unlikely(!rt_feature)) {
|
|
CCCI_ERROR_LOG(md->index, TAG,
|
|
"parse_md_rt_feature: rt_feature == NULL\n");
|
|
return -EFAULT;
|
|
}
|
|
if (unlikely(rt_feature->data_len > data_len ||
|
|
rt_feature->data_len == 0)) {
|
|
CCCI_ERROR_LOG(md->index, TAG,
|
|
"rt_feature %u data_len = %u, expected data_len %u\n",
|
|
rt_feature->feature_id, rt_feature->data_len, data_len);
|
|
return -EFAULT;
|
|
}
|
|
|
|
memcpy(data, (const void *)((char *)rt_feature->data),
|
|
rt_feature->data_len);
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct ccci_per_md *ccci_get_per_md_data(unsigned char md_id)
|
|
{
|
|
struct ccci_modem *md = ccci_md_get_modem_by_id(md_id);
|
|
|
|
if (md)
|
|
return &md->per_md_data;
|
|
else
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(ccci_get_per_md_data);
|
|
|
|
static void receive_wakeup_src_notify(int md_id, char *buf, unsigned int len)
|
|
{
|
|
int tmp_data = 0;
|
|
|
|
if (len == 0) {
|
|
/* before spm add MD_WAKEUP_SOURCE parameter. */
|
|
if (md_id == MD_SYS1) {
|
|
ccci_hif_set_wakeup_src(MD1_NET_HIF, 1);
|
|
ccci_hif_set_wakeup_src(CCIF_HIF_ID, 1);
|
|
}
|
|
if (md_id == MD_SYS3)
|
|
ccci_hif_set_wakeup_src(CCIF_HIF_ID, 1);
|
|
return;
|
|
}
|
|
|
|
/* after spm add MD_WAKEUP_SOURCE parameter. */
|
|
if (len > sizeof(tmp_data))
|
|
len = sizeof(tmp_data);
|
|
memcpy((void *)&tmp_data, buf, len);
|
|
switch (tmp_data) {
|
|
case WAKE_SRC_HIF_CCIF0:
|
|
ccci_hif_set_wakeup_src(CCIF_HIF_ID, 1);
|
|
break;
|
|
case WAKE_SRC_HIF_CLDMA:
|
|
case WAKE_SRC_HIF_DPMAIF:
|
|
ccci_hif_set_wakeup_src(MD1_NET_HIF, 1);
|
|
break;
|
|
default:
|
|
break;
|
|
};
|
|
}
|
|
|
|
int exec_ccci_kern_func_by_md_id(int md_id, unsigned int id, char *buf,
|
|
unsigned int len)
|
|
{
|
|
int ret = 0;
|
|
int tmp_data;
|
|
|
|
if (!get_modem_is_enabled(md_id)) {
|
|
CCCI_ERROR_LOG(md_id, CORE,
|
|
"wrong MD ID from %ps for %d\n",
|
|
__builtin_return_address(0), id);
|
|
return -CCCI_ERR_MD_INDEX_NOT_FOUND;
|
|
}
|
|
|
|
CCCI_DEBUG_LOG(md_id, CORE, "%ps execute function %d\n",
|
|
__builtin_return_address(0), id);
|
|
switch (id) {
|
|
case ID_GET_MD_WAKEUP_SRC:
|
|
receive_wakeup_src_notify(md_id, buf, len);
|
|
break;
|
|
case ID_GET_TXPOWER:
|
|
if (buf[0] == 0)
|
|
ret = ccci_port_send_msg_to_md(md_id, CCCI_SYSTEM_TX,
|
|
MD_TX_POWER, 0, 0);
|
|
else if (buf[0] == 1)
|
|
ret = ccci_port_send_msg_to_md(md_id, CCCI_SYSTEM_TX,
|
|
MD_RF_TEMPERATURE, 0, 0);
|
|
else if (buf[0] == 2)
|
|
ret = ccci_port_send_msg_to_md(md_id, CCCI_SYSTEM_TX,
|
|
MD_RF_TEMPERATURE_3G, 0, 0);
|
|
break;
|
|
case ID_FORCE_MD_ASSERT:
|
|
CCCI_NORMAL_LOG(md_id, CORE, "Force MD assert called by %s\n",
|
|
current->comm);
|
|
ret = ccci_md_force_assert(md_id,
|
|
MD_FORCE_ASSERT_BY_USER_TRIGGER,
|
|
NULL, 0);
|
|
break;
|
|
case ID_MD_MPU_ASSERT:
|
|
if (md_id == MD_SYS1) {
|
|
if (buf != NULL && strlen(buf)) {
|
|
CCCI_NORMAL_LOG(md_id, CORE,
|
|
"Force MD assert(MPU) called by %s\n",
|
|
current->comm);
|
|
ret = ccci_md_force_assert(md_id,
|
|
MD_FORCE_ASSERT_BY_AP_MPU,
|
|
buf, len);
|
|
} else {
|
|
CCCI_NORMAL_LOG(md_id, CORE,
|
|
"ACK (MPU violation) called by %s\n",
|
|
current->comm);
|
|
ret = ccci_port_send_msg_to_md(md_id,
|
|
CCCI_SYSTEM_TX,
|
|
MD_AP_MPU_ACK_MD, 0, 0);
|
|
}
|
|
} else
|
|
CCCI_NORMAL_LOG(md_id, CORE,
|
|
"MD%d MPU API called by %s\n",
|
|
md_id, current->comm);
|
|
break;
|
|
case ID_PAUSE_LTE:
|
|
/*
|
|
* MD booting/flight mode/exception mode: return >0 to DVFS.
|
|
* MD ready: return 0 if message delivered,
|
|
* return <0 if get error.
|
|
* DVFS will call this API with IRQ disabled.
|
|
*/
|
|
if (ccci_fsm_get_md_state(md_id) != READY)
|
|
ret = 1;
|
|
else {
|
|
ret = ccci_port_send_msg_to_md(md_id, CCCI_SYSTEM_TX,
|
|
MD_PAUSE_LTE, *((int *)buf), 1);
|
|
if (ret == -CCCI_ERR_MD_NOT_READY ||
|
|
ret == -CCCI_ERR_HIF_NOT_POWER_ON)
|
|
ret = 1;
|
|
}
|
|
break;
|
|
case ID_GET_MD_STATE:
|
|
ret = ccci_fsm_get_md_state_for_user(md_id);
|
|
break;
|
|
/* used for throttling feature - start */
|
|
case ID_THROTTLING_CFG:
|
|
ret = ccci_port_send_msg_to_md(md_id, CCCI_SYSTEM_TX,
|
|
MD_THROTTLING,
|
|
*((int *)buf), 1);
|
|
break;
|
|
/* used for throttling feature - end */
|
|
case ID_UPDATE_TX_POWER:
|
|
{
|
|
unsigned int msg_id = (md_id == 0) ?
|
|
MD_SW_MD1_TX_POWER :
|
|
MD_SW_MD2_TX_POWER;
|
|
unsigned int mode = *((unsigned int *)buf);
|
|
|
|
/*send tx power status for swtp and carkit*/
|
|
ret = ccci_port_send_msg_to_md(md_id, CCCI_SYSTEM_TX,
|
|
msg_id, mode, 0);
|
|
#ifdef CUST_FT_SEND_TX_POWER
|
|
ret = ccci_port_send_msg_to_md(md_id, CCCI_SYSTEM_TX,
|
|
MD_CARKIT_STATUS, mode, 0);
|
|
#endif
|
|
}
|
|
break;
|
|
case ID_DUMP_MD_SLEEP_MODE:
|
|
ccci_md_dump_info(md_id, DUMP_FLAG_SMEM_MDSLP, NULL, 0);
|
|
break;
|
|
case ID_PMIC_INTR:
|
|
ret = ccci_port_send_msg_to_md(md_id,
|
|
CCCI_SYSTEM_TX, PMIC_INTR_MODEM_BUCK_OC,
|
|
*((int *)buf), 1);
|
|
break;
|
|
case ID_LWA_CONTROL_MSG:
|
|
ret = ccci_port_send_msg_to_md(md_id, CCCI_SYSTEM_TX,
|
|
LWA_CONTROL_MSG, *((int *)buf), 1);
|
|
break;
|
|
case MD_DISPLAY_DYNAMIC_MIPI:
|
|
tmp_data = 0;
|
|
len = (len < sizeof(tmp_data)) ? len : sizeof(tmp_data);
|
|
memcpy((void *)&tmp_data, buf, len);
|
|
ret = ccci_port_send_msg_to_md(md_id, CCCI_SYSTEM_TX,
|
|
id, tmp_data, 0);
|
|
break;
|
|
default:
|
|
ret = -CCCI_ERR_FUNC_ID_ERROR;
|
|
break;
|
|
};
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(exec_ccci_kern_func_by_md_id);
|
|
|