Skip to content

Commit 4bd36ea

Browse files
Camera Software IntegrationGerrit - the friendly Code Review server
authored andcommitted
Merge "msm: camera: icp: PIL loading changes for kvm" into camera-kernel.qclinux.1.0
2 parents 827e229 + bbcee56 commit 4bd36ea

7 files changed

Lines changed: 154 additions & 12 deletions

File tree

camera/drivers/cam_cpas/cam_cpas_soc.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,10 +1468,14 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
14681468

14691469
soc_private->enable_smart_qos = of_property_read_bool(of_node,
14701470
"enable-smart-qos");
1471-
soc_private->enable_secure_qos_update = of_property_read_bool(of_node,
1472-
"enable-secure-qos-update");
1473-
CAM_DBG(CAM_CPAS, "Enable secure qos update: %s",
1474-
CAM_BOOL_TO_YESNO(soc_private->enable_secure_qos_update));
1471+
rc = of_property_read_u32(of_node, "enable-secure-qos-update",
1472+
&soc_private->enable_secure_qos_update);
1473+
if (rc) {
1474+
soc_private->enable_secure_qos_update = 0;
1475+
rc = 0;
1476+
}
1477+
CAM_DBG(CAM_CPAS, "Enable secure qos update: %d",
1478+
soc_private->enable_secure_qos_update);
14751479

14761480
if (soc_private->enable_smart_qos) {
14771481
uint32_t value;

camera/drivers/cam_cpas/cam_cpas_soc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ struct cam_cpas_private_soc {
304304
uint32_t num_caches;
305305
uint32_t part_info;
306306
struct cam_sys_cache_info *llcc_info;
307-
bool enable_secure_qos_update;
307+
uint32_t enable_secure_qos_update;
308308
bool enable_smart_qos;
309309
bool enable_cam_ddr_drv;
310310
bool enable_cam_clk_drv;

camera/drivers/cam_icp/cam_icp_subdev.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "cam_icp_context.h"
2929
#include "cam_hw_mgr_intf.h"
3030
#include "cam_icp_hw_mgr_intf.h"
31+
#include "cam_icp_hw_intf.h"
3132
#include "cam_debug_util.h"
3233
#include "cam_smmu_api.h"
3334
#include "camera_main.h"
@@ -50,6 +51,7 @@ struct cam_icp_subdev {
5051
int32_t reserved;
5152
};
5253

54+
struct camera_firmware cam_fw;
5355
static DEFINE_MUTEX(g_dev_lock);
5456
static struct cam_icp_subdev *g_icp_dev[CAM_ICP_SUBDEV_MAX];
5557

@@ -257,6 +259,89 @@ static inline int cam_icp_subdev_clean_up(uint32_t device_idx)
257259
return 0;
258260
}
259261

262+
void cam_put_domain_for_fw(struct camera_firmware *fw)
263+
{
264+
if (!fw)
265+
return;
266+
267+
if (fw->iommu_domain) {
268+
/*
269+
* No explicit release function for iommu_get_domain_for_dev,
270+
* but if you attached a domain, detach it here.
271+
*/
272+
iommu_detach_device(fw->iommu_domain, fw->dev);
273+
fw->iommu_domain = NULL;
274+
}
275+
276+
if (fw->dev) {
277+
of_node_put(fw->dev->of_node);
278+
platform_device_unregister(to_platform_device(fw->dev));
279+
fw->dev = NULL;
280+
}
281+
282+
fw->has_el2_iommu = false;
283+
}
284+
285+
static int cam_get_domain_for_fw(struct device *dev, struct camera_firmware *fw)
286+
{
287+
struct platform_device *pdev_fw = NULL;
288+
struct platform_device_info info;
289+
struct device_node *np = NULL;
290+
int rc = 0;
291+
292+
np = of_get_child_by_name(dev->of_node, "camera-firmware");
293+
if (!np) {
294+
CAM_INFO(CAM_ICP, "camera-firmware, not overlayed. no KVM");
295+
fw->has_el2_iommu = false;
296+
return 0;
297+
}
298+
299+
fw->has_el2_iommu = true;
300+
memset(&info, 0, sizeof(info));
301+
info.fwnode = &np->fwnode;
302+
info.parent = dev;
303+
info.name = np->name;
304+
info.dma_mask = DMA_BIT_MASK(32);
305+
306+
pdev_fw = platform_device_register_full(&info);
307+
if (IS_ERR(pdev_fw)) {
308+
rc = PTR_ERR(pdev_fw);
309+
CAM_ERR(CAM_ICP, "platform_device_register_full failed: %d", rc);
310+
goto cleanup_np;
311+
}
312+
313+
pdev_fw->dev.of_node = np;
314+
315+
rc = of_dma_configure(&pdev_fw->dev, np, true);
316+
if (rc) {
317+
CAM_ERR(CAM_ICP, "DMA configuration failed: %d", rc);
318+
pdev_fw->dev.of_node = NULL;
319+
goto unregister_pdev;
320+
}
321+
322+
fw->dev = &pdev_fw->dev;
323+
324+
fw->iommu_domain = iommu_get_domain_for_dev(fw->dev);
325+
if (!fw->iommu_domain) {
326+
CAM_ERR(CAM_ICP, "Failed to get IOMMU domain");
327+
rc = -ENOMEM;
328+
goto unregister_pdev;
329+
}
330+
331+
CAM_INFO(CAM_ICP, "KVM Enabled - fw.dev: %p, fw.iommu_domain: %p", fw->dev,
332+
fw->iommu_domain);
333+
return 0;
334+
335+
unregister_pdev:
336+
platform_device_unregister(pdev_fw);
337+
fw->dev = NULL;
338+
339+
cleanup_np:
340+
of_node_put(np);
341+
fw->has_el2_iommu = false;
342+
return rc;
343+
}
344+
260345
static int cam_icp_component_bind(struct device *dev,
261346
struct device *master_dev, void *data)
262347
{
@@ -356,6 +441,12 @@ static int cam_icp_component_bind(struct device *dev,
356441
goto ctx_fail;
357442
}
358443

444+
rc = cam_get_domain_for_fw(dev, &cam_fw);
445+
if (rc) {
446+
CAM_ERR(CAM_ICP, "device[%s] get domain for fw failed: %d", subdev_name, rc);
447+
goto ctx_fail;
448+
}
449+
359450
cam_common_register_evt_inject_cb(cam_icp_dev_evt_inject_cb,
360451
CAM_COMMON_EVT_INJECT_HW_ICP);
361452

@@ -364,12 +455,18 @@ static int cam_icp_component_bind(struct device *dev,
364455

365456
icp_dev->open_cnt = 0;
366457
rc = cam_subdev_register(&icp_dev->sd, pdev);
458+
if (rc) {
459+
CAM_ERR(CAM_ICP, "device[%s] subdev register failed: %d", subdev_name, rc);
460+
goto fw_cleanup;
461+
}
367462

368463
CAM_DBG(CAM_ICP, "device[%s] id: %u component bound successfully",
369464
subdev_name, device_idx);
370465

371466
return rc;
372467

468+
fw_cleanup:
469+
cam_put_domain_for_fw(&cam_fw);
373470
ctx_fail:
374471
for (--i; i >= 0; i--)
375472
cam_icp_context_deinit(&icp_dev->ctx_icp[i]);

camera/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_icp_hw_intf.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,13 @@ struct cam_icp_ubwc_cfg_cmd {
133133
bool disable_ubwc_comp;
134134
};
135135

136+
struct camera_firmware {
137+
struct device *dev;
138+
struct iommu_domain *iommu_domain;
139+
struct qcom_scm_pas_context *ctx;
140+
phys_addr_t mem_phys;
141+
size_t mem_size;
142+
bool has_el2_iommu;
143+
};
144+
136145
#endif

camera/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ static int cam_icp_v2_non_sec_boot(
595595

596596
#if IS_REACHABLE(CONFIG_QCOM_MDT_LOADER)
597597
static int __load_firmware(struct platform_device *pdev,
598-
uint32_t fw_pas_id)
598+
uint32_t fw_pas_id, struct camera_firmware *fw)
599599
{
600600
const char *fw_name;
601601
const struct firmware *firmware = NULL;
@@ -670,13 +670,26 @@ static int __load_firmware(struct platform_device *pdev,
670670
goto out;
671671
}
672672

673-
rc = qcom_mdt_load(&pdev->dev, firmware, firmware_name, fw_pas_id,
674-
vaddr, res_start, res_size, NULL);
673+
fw->ctx = qcom_scm_pas_context_init(&pdev->dev, fw_pas_id, res_start,
674+
res_size);
675+
if (IS_ERR_OR_NULL(fw->ctx)) {
676+
rc = fw->ctx ? PTR_ERR(fw->ctx) : -ENOMEM;
677+
fw->ctx = NULL;
678+
goto out;
679+
}
680+
fw->ctx->has_iommu = fw->has_el2_iommu;
681+
682+
rc = qcom_mdt_pas_load(fw->ctx, firmware, firmware_name, vaddr, NULL);
675683
if (rc) {
676684
CAM_ERR(CAM_ICP, "failed to load firmware rc=%d", rc);
685+
fw->ctx = NULL;
677686
goto out;
678687
}
679688

689+
fw->mem_phys = res_start;
690+
fw->mem_size = res_size;
691+
692+
CAM_DBG(CAM_ICP, "res_start=0x%x, res_size=%zu", res_start, res_size);
680693
out:
681694
if (vaddr)
682695
iounmap(vaddr);
@@ -714,14 +727,28 @@ static int cam_icp_v2_boot(struct cam_hw_info *icp_v2_info,
714727
prepare_boot(icp_v2_info, args);
715728

716729
#if IS_REACHABLE(CONFIG_QCOM_MDT_LOADER)
717-
rc = __load_firmware(icp_v2_info->soc_info.pdev, soc_priv->fw_pas_id);
730+
rc = __load_firmware(icp_v2_info->soc_info.pdev,
731+
soc_priv->fw_pas_id, core_info->fw);
718732
if (rc) {
719733
CAM_ERR(CAM_ICP, "firmware loading failed rc=%d", rc);
720734
goto err;
721735
}
722736
#endif
723737

724-
rc = qcom_scm_pas_auth_and_reset(soc_priv->fw_pas_id);
738+
if (core_info->fw->has_el2_iommu) {
739+
rc = iommu_map(core_info->fw->iommu_domain, 0, core_info->fw->mem_phys,
740+
core_info->fw->mem_size, IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV,
741+
GFP_KERNEL);
742+
if (rc) {
743+
CAM_ERR(CAM_ICP, "FW Region mapping failed for KVM rc=%d", rc);
744+
goto err;
745+
}
746+
} else {
747+
core_info->fw->mem_phys = 0;
748+
core_info->fw->mem_size = 0;
749+
}
750+
751+
rc = qcom_scm_pas_prepare_and_auth_reset(core_info->fw->ctx);
725752
if (rc) {
726753
CAM_ERR(CAM_ICP, "auth and reset failed rc=%d", rc);
727754
goto err;
@@ -746,8 +773,10 @@ static int cam_icp_v2_shutdown(struct cam_hw_info *icp_v2_info)
746773

747774
if (core_info->use_sec_pil) {
748775
rc = qcom_scm_pas_shutdown(soc_priv->fw_pas_id);
749-
}
750-
else {
776+
if (core_info->fw->has_el2_iommu)
777+
iommu_unmap(core_info->fw->iommu_domain, 0,
778+
core_info->fw->mem_size);
779+
} else {
751780
int32_t sys_base_idx = core_info->reg_base_idx[ICP_V2_SYS_BASE];
752781
void __iomem *base;
753782

camera/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct cam_icp_v2_core_info {
3939
uintptr_t fw_kva_addr;
4040
uint64_t fw_buf_len;
4141
} fw_params;
42+
struct camera_firmware *fw;
4243
bool cpas_start;
4344
bool use_sec_pil;
4445
bool is_irq_test;

camera/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_dev.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "cam_icp_soc_common.h"
1818

1919
static int max_icp_v2_hw_idx = -1;
20+
extern struct camera_firmware cam_fw;
2021

2122
struct cam_icp_v2_hw_info cam_icp_v2_hw_info[] = {
2223
{
@@ -171,6 +172,7 @@ static int cam_icp_v2_component_bind(struct device *dev,
171172

172173
platform_set_drvdata(pdev, icp_v2_intf);
173174

175+
core_info->fw = &cam_fw;
174176
return 0;
175177

176178
res_deinit:

0 commit comments

Comments
 (0)