Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b7522cd authored by Jing Zhou's avatar Jing Zhou Committed by Harsh Shah
Browse files

msm: camera: ife: add ISP HW Manager



Add the implementation of ISP HW Manager and ISP packet parser
utility. ISP HW manager is a common framework with one of the
adaptations being IFE HW Manager. HW Manager controls the CSID
and VFE HW through the HW interface. HW manager services calls
from ISP Context through the HW Manager interface. Packet parser
utlity parses the packet sent from UMD and prepares it for
submission to HW CDM.

Change-Id: Ia98c92b4606a61e8b0db0eae0cde71dda5c279ff
Signed-off-by: default avatarAlok Pandey <akumarpa@codeaurora.org>
Signed-off-by: default avatarRavikishore Pampana <rpampana@codeaurora.org>
Signed-off-by: default avatarHarsh Shah <harshs@codeaurora.org>
Signed-off-by: default avatarJing Zhou <jzhou70@codeaurora.org>
parent a1af882b
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@
 * GNU General Public License for more details.
 */


#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
@@ -24,6 +23,7 @@
#include "cam_isp_dev.h"
#include "cam_isp_log.h"
#include "cam_hw_mgr_intf.h"
#include "cam_isp_hw_mgr_intf.h"
#include "cam_node.h"

static struct cam_isp_dev g_isp_dev;
@@ -72,7 +72,12 @@ static int cam_isp_dev_probe(struct platform_device *pdev)
	}
	node = (struct cam_node *) g_isp_dev.sd.token;

	/* Initialize the context list */
	rc = cam_isp_hw_mgr_init(pdev->dev.of_node, &hw_mgr_intf);
	if (rc != 0) {
		pr_err("%s: Can not initialized ISP HW manager!\n", __func__);
		goto unregister;
	}

	for (i = 0; i < CAM_CTX_MAX; i++) {
		rc = cam_isp_context_init(&g_isp_dev.ctx_isp[i],
			&g_isp_dev.ctx[i],
@@ -84,7 +89,6 @@ static int cam_isp_dev_probe(struct platform_device *pdev)
		}
	}

	/* Initialize the cam node */
	rc = cam_node_init(node, &hw_mgr_intf, g_isp_dev.ctx, CAM_CTX_MAX,
		CAM_ISP_DEV_NAME);
	if (rc) {
@@ -126,4 +130,3 @@ module_init(cam_isp_dev_init_module);
module_exit(cam_isp_dev_exit_module);
MODULE_DESCRIPTION("MSM ISP driver");
MODULE_LICENSE("GPL v2");
+11 −0
Original line number Diff line number Diff line
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
ccflags-y += -Idrivers/media/platform/msm/camera/cam_core
ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu
ccflags-y += -Idrivers/media/platform/msm/camera/cam_cdm
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller
ccflags-y += -Idrivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include

obj-$(CONFIG_SPECTRA_CAMERA) += hw_utils/ isp_hw/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_isp_hw_mgr.o cam_ife_hw_mgr.o
+3046 −0

File added.

Preview size limit exceeded, changes collapsed.

+210 −0
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef _CAM_IFE_HW_MGR_H_
#define _CAM_IFE_HW_MGR_H_

#include "cam_isp_hw_mgr.h"
#include "cam_vfe_hw_intf.h"
#include "cam_ife_csid_hw_intf.h"
#include "cam_tasklet_util.h"

/* MAX IFE instance */
#define CAM_IFE_HW_NUM_MAX                       4

/* enum cam_ife_hw_mgr_res_type - manager resource node type */
enum cam_ife_hw_mgr_res_type {
	CAM_IFE_HW_MGR_RES_UNINIT,
	CAM_IFE_HW_MGR_RES_ROOT,
	CAM_IFE_HW_MGR_RES_CID,
	CAM_IFE_HW_MGR_RES_CSID,
	CAM_IFE_HW_MGR_RES_IFE_SRC,
	CAM_IFE_HW_MGR_RES_IFE_OUT,
};

/* IFE resource constants */
#define CAM_IFE_HW_IN_RES_MAX            (CAM_ISP_IFE_IN_RES_MAX & 0xFF)
#define CAM_IFE_HW_OUT_RES_MAX           (CAM_ISP_IFE_OUT_RES_MAX & 0xFF)
#define CAM_IFE_HW_RES_POOL_MAX          64

/**
 * struct cam_vfe_hw_mgr_res- HW resources for the VFE manager
 *
 * @list:                used by the resource list
 * @res_type:            IFE manager resource type
 * @res_id:              resource id based on the resource type for root or
 *                       leaf resource, it matches the KMD interface port id.
 *                       For branch resrouce, it is defined by the ISP HW
 *                       layer
 * @hw_res:              hw layer resource array. For single VFE, only one VFE
 *                       hw resrouce will be acquired. For dual VFE, two hw
 *                       resources from different VFE HW device will be
 *                       acquired
 * @parent:              point to the parent resource node.
 * @children:            point to the children resource nodes
 * @child_num:           numbe of the child resource node.
 *
 */
struct cam_ife_hw_mgr_res {
	struct list_head                 list;
	enum cam_ife_hw_mgr_res_type     res_type;
	uint32_t                         res_id;
	uint32_t                         is_dual_vfe;
	struct cam_isp_resource_node    *hw_res[CAM_ISP_HW_SPLIT_MAX];

	/* graph */
	struct cam_ife_hw_mgr_res       *parent;
	struct cam_ife_hw_mgr_res       *child[CAM_IFE_HW_OUT_RES_MAX];
	uint32_t                         num_children;
};


/**
 * struct ctx_base_info - base hardware information for the context
 *
 * @idx:                 Base resource index
 * @split_id:            split info for the base resource
 *
 */
struct ctx_base_info {
	uint32_t                       idx;
	enum cam_isp_hw_split_id       split_id;
};

/**
 * struct cam_vfe_hw_mgr_ctx - IFE HW manager Context object
 *
 * @list:                   used by the ctx list.
 * @common:                 common acquired context data
 * @ctx_index:              acquired context id.
 * @hw_mgr:                 IFE hw mgr which owns this context
 * @ctx_in_use:             flag to tell whether context is active
 * @res_list_ife_in:        Starting resource(TPG,PHY0, PHY1...) Can only be
 *                          one.
 * @res_list_csid:          CSID resource list
 * @res_list_ife_src:       IFE input resource list
 * @res_list_ife_out:       IFE output resoruces array
 * @free_res_list:          Free resources list for the branch node
 * @res_pool:               memory storage for the free resource list
 * @irq_status0_mask:       irq_status0_mask for the context
 * @irq_status1_mask:       irq_status1_mask for the context
 * @base                    device base index array contain the all IFE HW
 *                          instance associated with this context.
 * @num_base                number of valid base data in the base array
 * @cdm_handle              cdm hw acquire handle
 * @cdm_ops                 cdm util operation pointer for building
 *                          cdm commands
 * @cdm_cmd                 cdm base and length request pointer
 * @sof_cnt                 sof count value per core, used for dual VFE
 * @epoch_cnt               epoch count value per core, used for dual VFE
 * @overflow_pending        flat to specify the overflow is pending for the
 *                          context
 */
struct cam_ife_hw_mgr_ctx {
	struct list_head                list;
	struct cam_isp_hw_mgr_ctx       common;

	uint32_t                        ctx_index;
	struct cam_ife_hw_mgr          *hw_mgr;
	uint32_t                        ctx_in_use;

	struct cam_ife_hw_mgr_res       res_list_ife_in;
	struct list_head                res_list_ife_cid;
	struct list_head                res_list_ife_csid;
	struct list_head                res_list_ife_src;
	struct cam_ife_hw_mgr_res       res_list_ife_out[
						CAM_IFE_HW_OUT_RES_MAX];

	struct list_head                free_res_list;
	struct cam_ife_hw_mgr_res       res_pool[CAM_IFE_HW_RES_POOL_MAX];

	uint32_t                        irq_status0_mask[CAM_IFE_HW_NUM_MAX];
	uint32_t                        irq_status1_mask[CAM_IFE_HW_NUM_MAX];
	struct ctx_base_info            base[CAM_IFE_HW_NUM_MAX];
	uint32_t                        num_base;
	uint32_t                        cdm_handle;
	struct cam_cdm_utils_ops       *cdm_ops;
	struct cam_cdm_bl_request      *cdm_cmd;

	uint32_t                        sof_cnt[CAM_IFE_HW_NUM_MAX];
	uint32_t                        epoch_cnt[CAM_IFE_HW_NUM_MAX];
	atomic_t                        overflow_pending;

};

/**
 * struct cam_ife_hw_mgr - IFE HW Manager
 *
 * @mgr_common:            common data for all HW managers
 * @csid_devices;          csid device instances array. This will be filled by
 *                         HW manager during the initialization.
 * @ife_devices:           IFE device instances array. This will be filled by
 *                         HW layer during initialization
 * @ctx_mutex:             mutex for the hw context pool
 * @free_ctx_list:         free hw context list
 * @used_ctx_list:         used hw context list
 * @ctx_pool:              context storage
 * @ife_csid_dev_caps      csid device capability stored per core
 * @ife_dev_caps           ife device capability per core
 * @work q                 work queue for IFE hw manager
 */
struct cam_ife_hw_mgr {
	struct cam_isp_hw_mgr          mgr_common;
	struct cam_hw_intf            *csid_devices[CAM_IFE_CSID_HW_NUM_MAX];
	struct cam_hw_intf            *ife_devices[CAM_IFE_HW_NUM_MAX];
	struct cam_soc_reg_map        *cdm_reg_map[CAM_IFE_HW_NUM_MAX];

	struct mutex                   ctx_mutex;
	struct list_head               free_ctx_list;
	struct list_head               used_ctx_list;
	struct cam_ife_hw_mgr_ctx      ctx_pool[CAM_CTX_MAX];

	struct cam_ife_csid_hw_caps    ife_csid_dev_caps[
						CAM_IFE_CSID_HW_NUM_MAX];
	struct cam_vfe_hw_get_hw_cap   ife_dev_caps[CAM_IFE_HW_NUM_MAX];
	struct cam_req_mgr_core_workq  *workq;
};

/**
 * cam_ife_hw_mgr_init()
 *
 * @brief:              Initialize the IFE hardware manger. This is the
 *                      etnry functinon for the IFE HW manager.
 *
 * @hw_mgr_intf:        IFE hardware manager object returned
 *
 */
int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf);

/**
 * cam_ife_mgr_do_tasklet_buf_done()
 *
 * @brief:              Main tasklet handle function for the buf done event
 *
 * @handler_priv:       Tasklet information handle
 * @evt_payload_priv:   Event payload for the handler funciton
 *
 */
int cam_ife_mgr_do_tasklet_buf_done(void *handler_priv, void *evt_payload_priv);

/**
 * cam_ife_mgr_do_tasklet()
 *
 * @brief:              Main tasklet handle function for mux resource events
 *
 * @handler_priv:       Tasklet information handle
 * @evt_payload_priv:   Event payload for the handler funciton
 *
 */
int cam_ife_mgr_do_tasklet(void *handler_priv, void *evt_payload_priv);

#endif /* _CAM_IFE_HW_MGR_H_ */
+35 −0
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include "cam_isp_hw_mgr_intf.h"
#include "cam_ife_hw_mgr.h"


int cam_isp_hw_mgr_init(struct device_node *of_node,
	struct cam_hw_mgr_intf *hw_mgr)
{
	int rc = 0;
	const char *compat_str = NULL;

	rc = of_property_read_string_index(of_node, "arch-compat", 0,
		(const char **)&compat_str);

	if (strnstr(compat_str, "ife", strlen(compat_str)))
		rc = cam_ife_hw_mgr_init(hw_mgr);
	else {
		pr_err("%s: Invalid ISP hw type\n", __func__);
		rc = -EINVAL;
	}

	return rc;
}
Loading