camera: intel: ipu6: Pass NVM data into CMC

NVM data is needed when initialize CMC.

BUG=b:149068439, b:149068672
TEST=Full tested pass for camera functions.

Change-Id: I17e3c0522485f93ca90239d125acdf01715ab0b4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2594544
Tested-by: Zong Li <zong.li@intel.com>
Reviewed-by: Ren-Pei Zeng <kamesan@chromium.org>
Commit-Queue: Ren-Pei Zeng <kamesan@chromium.org>
diff --git a/camera/hal/intel/ipu6/modules/algowrapper/IntelCmc.cpp b/camera/hal/intel/ipu6/modules/algowrapper/IntelCmc.cpp
index fa86fb1..73fa450 100644
--- a/camera/hal/intel/ipu6/modules/algowrapper/IntelCmc.cpp
+++ b/camera/hal/intel/ipu6/modules/algowrapper/IntelCmc.cpp
@@ -33,7 +33,6 @@
 bool IntelCmc::init(const ia_binary_data* aiqbData, const ia_binary_data* nvmData) {
     LOG1("@%s, aiqbData:%p, nvmData:%p", __func__, aiqbData, nvmData);
     CheckError(!aiqbData, false, "aiqbData is nullptr");
-    CheckError(nvmData, false, "nvmData is not nullptr");  // it doesn't support nvmData currently.
 
     mHandle = ia_cmc_parser_init_v1(aiqbData, nvmData);
     LOG1("@%s, mHandle:%p", __func__, mHandle);
diff --git a/camera/hal/intel/ipu6/modules/sandboxing/IPCIntelCmc.cpp b/camera/hal/intel/ipu6/modules/sandboxing/IPCIntelCmc.cpp
index ed0995a..6555d79 100644
--- a/camera/hal/intel/ipu6/modules/sandboxing/IPCIntelCmc.cpp
+++ b/camera/hal/intel/ipu6/modules/sandboxing/IPCIntelCmc.cpp
@@ -30,8 +30,10 @@
     LOGIPC("@%s", __func__);
 }
 
-bool IPCIntelCmc::clientFlattenInit(const ia_binary_data& aiqb, cmc_init_params* params) {
-    LOGIPC("@%s, aiqb: data:%p, size:%d, params:%p", __func__, aiqb.data, aiqb.size, params);
+bool IPCIntelCmc::clientFlattenInit(const ia_binary_data& aiqb, const ia_binary_data* nvmData,
+                                    cmc_init_params* params) {
+    LOGIPC("@%s, aiqb: data:%p, size:%d, nvmData %p, params:%p", __func__, aiqb.data, aiqb.size,
+           nvmData, params);
 
     CheckError(!params, false, "@%s, params is nullptr", __func__);
     CheckError(!aiqb.data, false, "@%s, aiqb.data is nullptr", __func__);
@@ -40,8 +42,17 @@
                aiqb.size);
 
     ia_binary_data_mod* input = &params->input;
-    MEMCPY_S(input->data, sizeof(input->data), aiqb.data, aiqb.size);
-    input->size = aiqb.size;
+    char* ptr = input->data;
+
+    MEMCPY_S(ptr, sizeof(input->data), aiqb.data, aiqb.size);
+    params->aiqb_size = aiqb.size;
+
+    params->nvm_size = 0;
+    ptr += aiqb.size;
+    if (nvmData) {
+        MEMCPY_S(ptr, sizeof(input->data) - aiqb.size, nvmData->data, nvmData->size);
+        params->nvm_size = nvmData->size;
+    }
 
     return true;
 }
@@ -60,13 +71,20 @@
     return true;
 }
 
-bool IPCIntelCmc::serverUnflattenInit(const cmc_init_params& params, ia_binary_data* aiqb) {
-    LOGIPC("@%s, aiqb:%p", __func__, aiqb);
+bool IPCIntelCmc::serverUnflattenInit(const cmc_init_params& params, ia_binary_data* aiqb,
+                                     ia_binary_data* nvmData) {
+    LOGIPC("@%s, aiqb:%p, nvmData:%p", __func__, aiqb, nvmData);
     CheckError(aiqb == nullptr, false, "@%s, aiqb is nullptr", __func__);
+    CheckError(nvmData == nullptr, false, "@%s, nvmData is nullptr", __func__);
 
     ia_binary_data_mod* input = const_cast<ia_binary_data_mod*>(&params.input);
     aiqb->data = input->data;
-    aiqb->size = input->size;
+    aiqb->size = params.aiqb_size;
+
+    if (params.nvm_size > 0) {
+        nvmData->data = input->data + aiqb->size;
+        nvmData->size = params.nvm_size;
+    }
 
     return true;
 }
diff --git a/camera/hal/intel/ipu6/modules/sandboxing/IPCIntelCmc.h b/camera/hal/intel/ipu6/modules/sandboxing/IPCIntelCmc.h
index 4c29617..02f5d75 100644
--- a/camera/hal/intel/ipu6/modules/sandboxing/IPCIntelCmc.h
+++ b/camera/hal/intel/ipu6/modules/sandboxing/IPCIntelCmc.h
@@ -70,6 +70,8 @@
 
 struct cmc_init_params {
     ia_binary_data_mod input;
+    unsigned int aiqb_size;
+    unsigned int nvm_size;
     ia_cmc_data results;
 };
 
@@ -83,11 +85,13 @@
     virtual ~IPCIntelCmc();
 
     // for init
-    bool clientFlattenInit(const ia_binary_data& aiqb, cmc_init_params* params);
+    bool clientFlattenInit(const ia_binary_data& aiqb, const ia_binary_data* nvmData,
+                           cmc_init_params* params);
     bool clientUnflattenInit(const cmc_init_params& params, ia_cmc_t** cmc,
                              uintptr_t* cmcRemoteHandle);
     bool serverFlattenInit(const ia_cmc_t& cmc, cmc_init_params* params);
-    bool serverUnflattenInit(const cmc_init_params& pData, ia_binary_data* aiqb);
+    bool serverUnflattenInit(const cmc_init_params& pData, ia_binary_data* aiqb,
+                             ia_binary_data* nvmData);
 
     bool flattenCmcData(const ia_cmc_t* cmc, ia_cmc_data* results);
     bool unflattenCmcData(ia_cmc_data* results);
diff --git a/camera/hal/intel/ipu6/modules/sandboxing/client/IntelCmc.cpp b/camera/hal/intel/ipu6/modules/sandboxing/client/IntelCmc.cpp
index 9440653..c0c82db 100644
--- a/camera/hal/intel/ipu6/modules/sandboxing/client/IntelCmc.cpp
+++ b/camera/hal/intel/ipu6/modules/sandboxing/client/IntelCmc.cpp
@@ -54,7 +54,6 @@
 
 bool IntelCmc::init(const ia_binary_data* aiqbData, const ia_binary_data* nvmData) {
     LOGIPC("@%s, aiqbData:%p, nvmData:%p", __func__, aiqbData, nvmData);
-    CheckError(nvmData, false, "@%s, nvmData should be nullptr", __func__);
 
     CheckError(mInitialized == false, false, "@%s, mInitialized is false", __func__);
     CheckError(!aiqbData, false, "@%s, aiqbData is nullptr", __func__);
@@ -63,7 +62,7 @@
 
     cmc_init_params* params = static_cast<cmc_init_params*>(mMemInit.mAddr);
 
-    bool ret = mIpc.clientFlattenInit(*aiqbData, params);
+    bool ret = mIpc.clientFlattenInit(*aiqbData, nvmData, params);
     CheckError(ret == false, false, "@%s, clientFlattenInit fails", __func__);
 
     ret = mCommon.requestSync(IPC_CMC_INIT, mMemInit.mHandle);
diff --git a/camera/hal/intel/ipu6/modules/sandboxing/server/IntelCmcServer.cpp b/camera/hal/intel/ipu6/modules/sandboxing/server/IntelCmcServer.cpp
index c0d64aa..863627b 100644
--- a/camera/hal/intel/ipu6/modules/sandboxing/server/IntelCmcServer.cpp
+++ b/camera/hal/intel/ipu6/modules/sandboxing/server/IntelCmcServer.cpp
@@ -45,13 +45,14 @@
 
     cmc_init_params* params = static_cast<cmc_init_params*>(pData);
     ia_binary_data aiqbData = {nullptr, 0};
+    ia_binary_data nvmData = {nullptr, 0};
 
-    bool ret = mIpc.serverUnflattenInit(*params, &aiqbData);
+    bool ret = mIpc.serverUnflattenInit(*params, &aiqbData, &nvmData);
     CheckError(ret == false, UNKNOWN_ERROR, "@%s, serverUnflattenInit fails", __func__);
 
     std::unique_ptr<IntelCmc> intelCmc = std::make_unique<IntelCmc>();
 
-    ret = intelCmc->init(&aiqbData, nullptr);
+    ret = intelCmc->init(&aiqbData, nvmData.size > 0 ? &nvmData : nullptr);
     CheckError(ret == false, UNKNOWN_ERROR, "@%s, intelCmc->init fails", __func__);
 
     ia_cmc_t* cmc = intelCmc->getCmc();
diff --git a/camera/hal/intel/ipu6/src/platformdata/AiqInitData.cpp b/camera/hal/intel/ipu6/src/platformdata/AiqInitData.cpp
index 7c16bff..7f51579 100644
--- a/camera/hal/intel/ipu6/src/platformdata/AiqInitData.cpp
+++ b/camera/hal/intel/ipu6/src/platformdata/AiqInitData.cpp
@@ -125,7 +125,7 @@
     LOG1("%s, aiqd file %s, size %d", __func__, mAiqdFileName.c_str(), mBinaryData.size);
 }
 
-CpfConf::CpfConf()
+CpfConf::CpfConf(ia_binary_data* nvmData) : mNvmData(nvmData)
 {
     mLard = new IntelLard();
     mCmc = std::unique_ptr<IntelCmc>(new IntelCmc());
@@ -159,7 +159,7 @@
         ia_err iaErr = mLard->run(iaLard, &lardInputParams, &lardResults);
         if (lardResults != nullptr) {
             LOG1("ia_lard_run success, using lard to get cmc mode and tuning.");
-            cmcRet = mCmc->init(&lardResults->aiqb_cmc_data, nullptr);
+            cmcRet = mCmc->init(&lardResults->aiqb_cmc_data, mNvmData);
             mAiq = lardResults->aiqb_aiq_data;
             mIsp = lardResults->aiqb_isp_data;
             mOthers = lardResults->aiqb_other_data;
@@ -169,7 +169,7 @@
         mLard->deinit(iaLard);
     } else {
         LOG1("Lard not supported. The AIQB file may be in old CPF format");
-        cmcRet = mCmc->init(&cpfData, nullptr);
+        cmcRet = mCmc->init(&cpfData, mNvmData);
         mAiq = cpfData;
         mIsp = cpfData;
         mOthers = cpfData;
@@ -263,7 +263,8 @@
                    const std::vector<TuningConfig>& tuningCfg,
                    const std::vector<LardTagConfig>& lardTagCfg,
                    const std::string& nvmPath,
-                   std::unordered_map<std::string, std::string> camModuleToAiqbMap)
+                   std::unordered_map<std::string, std::string> camModuleToAiqbMap,
+                   ia_binary_data* nvmData)
 {
     LOG1("@%s:Sensor Name = %s", __func__, sensorName.c_str());
 
@@ -308,7 +309,7 @@
             }
         }
 
-        CpfConf* cpfConf = new CpfConf();
+        CpfConf* cpfConf = new CpfConf(nvmData);
 
         cpfConf->init(mCpfData[aiqbName], oneLardTagCfg);
         mCpfConfig[cfg.tuningMode] = cpfConf;
@@ -549,8 +550,9 @@
                               ia_cmc_t** cmcData)
 {
     if (!mCpfStore) {
+        ia_binary_data* nvmData = getNvm();
         mCpfStore = new CpfStore(mSensorName, mCamCfgDir, mTuningCfg, mLardTagCfg,
-                                 mNvmPath, mCameraModuleToAiqbMap);
+                                 mNvmPath, mCameraModuleToAiqbMap, nvmData);
     }
     return mCpfStore->getCpfAndCmc(ispData, aiqData, otherData, cmcHandle, mode, cmcData);
 }
diff --git a/camera/hal/intel/ipu6/src/platformdata/AiqInitData.h b/camera/hal/intel/ipu6/src/platformdata/AiqInitData.h
index 21de658..3265791 100644
--- a/camera/hal/intel/ipu6/src/platformdata/AiqInitData.h
+++ b/camera/hal/intel/ipu6/src/platformdata/AiqInitData.h
@@ -67,7 +67,7 @@
 class CpfConf
 {
 public:
-    CpfConf();
+    explicit CpfConf(ia_binary_data* nvmData);
     virtual ~CpfConf();
 
     /**
@@ -131,6 +131,7 @@
 
 private:
     IntelLard* mLard;
+    ia_binary_data* mNvmData;
     std::unique_ptr<IntelCmc> mCmc;
     ia_binary_data mAiq;
     ia_binary_data mIsp;
@@ -170,7 +171,8 @@
              const std::vector<TuningConfig>& tuningCfg,
              const std::vector<LardTagConfig>& lardTagCfg,
              const std::string& nvmPath,
-             std::unordered_map<std::string, std::string> camModuleToAiqbMap);
+             std::unordered_map<std::string, std::string> camModuleToAiqbMap,
+             ia_binary_data* nvmData);
     virtual ~CpfStore();
 
     /**