mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 21:59:12 -04:00
msm: camera: isp: Maintain clock rate relation between CSIHPY, CSID and TFE
Added checks to confirm CSID frequency greater than CSIPHY frequency, TFE frequency greater than CSID frequency. Also TFE frequency should be such that it can accommodate PHY data rate. CRs-Fixed: 2847155 Change-Id: I5d3dcc53a6f27129f4b82cba1254445f58f6d0cf Signed-off-by: Shravya Samala <shravyas@codeaurora.org>
This commit is contained in:
parent
38b96be690
commit
c15edd4c3d
13 changed files with 429 additions and 7 deletions
|
|
@ -311,6 +311,31 @@ int cam_context_dump_pf_info(struct cam_context *ctx,
|
|||
return rc;
|
||||
}
|
||||
|
||||
int cam_context_handle_message(struct cam_context *ctx,
|
||||
uint32_t msg_type, uint32_t *data)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!ctx->state_machine) {
|
||||
CAM_ERR(CAM_CORE, "Context is not ready");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ctx->state > CAM_CTX_AVAILABLE) &&
|
||||
(ctx->state < CAM_CTX_STATE_MAX)) {
|
||||
if (ctx->state_machine[ctx->state].msg_cb_ops) {
|
||||
rc = ctx->state_machine[ctx->state].msg_cb_ops(
|
||||
ctx, msg_type, data);
|
||||
} else {
|
||||
CAM_WARN(CAM_CORE,
|
||||
"No message handler for ctx %d, state %d msg_type :%d",
|
||||
ctx->dev_hdl, ctx->state, msg_type);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_context_handle_acquire_dev(struct cam_context *ctx,
|
||||
struct cam_acquire_dev_cmd *cmd)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -158,14 +158,17 @@ struct cam_ctx_crm_ops {
|
|||
* @pagefault_ops: Function to be called on page fault
|
||||
* @dumpinfo_ops: Function to be invoked for dumping any
|
||||
* context info
|
||||
* @msg_cb_ops: Function to be called on any message from
|
||||
* other subdev notifications
|
||||
*
|
||||
*/
|
||||
struct cam_ctx_ops {
|
||||
struct cam_ctx_ioctl_ops ioctl_ops;
|
||||
struct cam_ctx_crm_ops crm_ops;
|
||||
cam_hw_event_cb_func irq_ops;
|
||||
cam_hw_pagefault_cb_func pagefault_ops;
|
||||
cam_ctx_info_dump_cb_func dumpinfo_ops;
|
||||
struct cam_ctx_ioctl_ops ioctl_ops;
|
||||
struct cam_ctx_crm_ops crm_ops;
|
||||
cam_hw_event_cb_func irq_ops;
|
||||
cam_hw_pagefault_cb_func pagefault_ops;
|
||||
cam_ctx_info_dump_cb_func dumpinfo_ops;
|
||||
cam_ctx_message_cb_func msg_cb_ops;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -367,6 +370,19 @@ int cam_context_handle_crm_dump_req(struct cam_context *ctx,
|
|||
int cam_context_dump_pf_info(struct cam_context *ctx,
|
||||
struct cam_smmu_pf_info *pf_info);
|
||||
|
||||
/**
|
||||
* cam_context_handle_message()
|
||||
*
|
||||
* @brief: Handle message callback command
|
||||
*
|
||||
* @ctx: Object pointer for cam_context
|
||||
* @msg_type: message type sent from other subdev
|
||||
* @data: data from other subdev
|
||||
*
|
||||
*/
|
||||
int cam_context_handle_message(struct cam_context *ctx,
|
||||
uint32_t msg_type, uint32_t *data);
|
||||
|
||||
/**
|
||||
* cam_context_handle_acquire_dev()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ typedef int (*cam_hw_pagefault_cb_func)(void *context,
|
|||
typedef int (*cam_ctx_info_dump_cb_func)(void *context,
|
||||
enum cam_context_dump_id dump_id);
|
||||
|
||||
/* message callback function type */
|
||||
typedef int (*cam_ctx_message_cb_func)(void *context,
|
||||
uint32_t message_type, uint32_t *data);
|
||||
/**
|
||||
* struct cam_hw_update_entry - Entry for hardware config
|
||||
*
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "cam_common_util.h"
|
||||
#include "cam_req_mgr_debug.h"
|
||||
#include "cam_cpas_api.h"
|
||||
#include "cam_subdev.h"
|
||||
|
||||
static const char isp_dev_name[] = "cam-isp";
|
||||
|
||||
|
|
@ -33,6 +34,9 @@ static struct cam_isp_ctx_debug isp_ctx_debug;
|
|||
static int cam_isp_context_dump_requests(void *data,
|
||||
struct cam_smmu_pf_info *pf_info);
|
||||
|
||||
static int cam_isp_context_handle_message(void *context,
|
||||
uint32_t msg_type, uint32_t *data);
|
||||
|
||||
static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
|
||||
struct cam_start_stop_dev_cmd *cmd);
|
||||
|
||||
|
|
@ -5772,6 +5776,7 @@ static struct cam_ctx_ops
|
|||
.irq_ops = NULL,
|
||||
.pagefault_ops = cam_isp_context_dump_requests,
|
||||
.dumpinfo_ops = cam_isp_context_info_dump,
|
||||
.msg_cb_ops = cam_isp_context_handle_message,
|
||||
},
|
||||
/* Activated */
|
||||
{
|
||||
|
|
@ -5791,6 +5796,7 @@ static struct cam_ctx_ops
|
|||
.irq_ops = __cam_isp_ctx_handle_irq_in_activated,
|
||||
.pagefault_ops = cam_isp_context_dump_requests,
|
||||
.dumpinfo_ops = cam_isp_context_info_dump,
|
||||
.msg_cb_ops = cam_isp_context_handle_message,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -5933,6 +5939,34 @@ static int cam_isp_context_dump_requests(void *data,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_context_handle_message(void *context,
|
||||
uint32_t msg_type, uint32_t *data)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_hw_cmd_args hw_cmd_args;
|
||||
struct cam_isp_hw_cmd_args isp_hw_cmd_args;
|
||||
struct cam_context *ctx = (struct cam_context *)context;
|
||||
|
||||
memset(&hw_cmd_args, 0, sizeof(hw_cmd_args));
|
||||
hw_cmd_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
|
||||
|
||||
switch (msg_type) {
|
||||
case CAM_SUBDEV_MESSAGE_CLOCK_UPDATE:
|
||||
hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
|
||||
isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_UPDATE_CLOCK;
|
||||
isp_hw_cmd_args.cmd_data = (void *)data;
|
||||
hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
|
||||
rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
|
||||
&hw_cmd_args);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "Update clock rate failed rc: %d", rc);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ISP, "Invalid message type %d", msg_type);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_context_debug_register(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,22 @@ static void cam_isp_dev_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
|
|||
cam_context_dump_pf_info(&(node->ctx_list[i]), pf_info);
|
||||
}
|
||||
|
||||
static void cam_isp_subdev_handle_message(
|
||||
struct v4l2_subdev *sd,
|
||||
enum cam_subdev_message_type_t message_type,
|
||||
uint32_t data)
|
||||
{
|
||||
int i, rc = 0;
|
||||
struct cam_node *node = v4l2_get_subdevdata(sd);
|
||||
|
||||
CAM_DBG(CAM_ISP, "node name %s", node->name, data);
|
||||
for (i = 0; i < node->ctx_size; i++) {
|
||||
rc = cam_context_handle_message(&(node->ctx_list[i]), message_type, &data);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "Failed to handle message for %s", node->name);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct of_device_id cam_isp_dt_match[] = {
|
||||
{
|
||||
.compatible = "qcom,cam-isp"
|
||||
|
|
@ -113,6 +129,7 @@ static int cam_isp_dev_component_bind(struct device *dev,
|
|||
} else if (strnstr(compat_str, "tfe", strlen(compat_str))) {
|
||||
rc = cam_subdev_probe(&g_isp_dev.sd, pdev, CAM_ISP_DEV_NAME,
|
||||
CAM_TFE_DEVICE_TYPE);
|
||||
g_isp_dev.sd.msg_cb = cam_isp_subdev_handle_message;
|
||||
g_isp_dev.isp_device_type = CAM_TFE_DEVICE_TYPE;
|
||||
g_isp_dev.max_context = CAM_TFE_CTX_MAX;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -306,6 +306,82 @@ err:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_tfe_hw_mgr_get_clock_rate(
|
||||
struct cam_isp_hw_mgr_res *isp_hw_res,
|
||||
uint32_t *get_clock_rate)
|
||||
{
|
||||
int i;
|
||||
int rc = -EINVAL;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
if (!isp_hw_res->hw_res[i])
|
||||
continue;
|
||||
|
||||
hw_intf = isp_hw_res->hw_res[i]->hw_intf;
|
||||
CAM_DBG(CAM_ISP, "hw type %d hw index:%d",
|
||||
hw_intf->hw_type, hw_intf->hw_idx);
|
||||
if (hw_intf && hw_intf->hw_ops.process_cmd) {
|
||||
rc = hw_intf->hw_ops.process_cmd(
|
||||
hw_intf->hw_priv,
|
||||
CAM_ISP_HW_CMD_GET_CLOCK_RATE,
|
||||
get_clock_rate,
|
||||
sizeof(uint32_t));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Failed to get Clock rate");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_tfe_hw_mgr_update_clock_rate(
|
||||
struct cam_isp_hw_mgr_res *isp_hw_res,
|
||||
uint32_t *set_clock_rate,
|
||||
uint32_t *updated_clock_rate)
|
||||
{
|
||||
int i;
|
||||
int rc = 0;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
if (!isp_hw_res->hw_res[i])
|
||||
continue;
|
||||
|
||||
hw_intf = isp_hw_res->hw_res[i]->hw_intf;
|
||||
CAM_DBG(CAM_ISP, "hw type %d hw index:%d",
|
||||
hw_intf->hw_type, hw_intf->hw_idx);
|
||||
|
||||
if (hw_intf && hw_intf->hw_ops.process_cmd) {
|
||||
rc = hw_intf->hw_ops.process_cmd(
|
||||
hw_intf->hw_priv,
|
||||
CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE,
|
||||
set_clock_rate,
|
||||
sizeof(uint32_t));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Failed to get Clock rate");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (hw_intf && hw_intf->hw_ops.process_cmd) {
|
||||
rc = hw_intf->hw_ops.process_cmd(
|
||||
hw_intf->hw_priv,
|
||||
CAM_ISP_HW_CMD_GET_CLOCK_RATE,
|
||||
updated_clock_rate,
|
||||
sizeof(uint32_t));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Failed to get Clock rate");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_tfe_hw_mgr_start_hw_res(
|
||||
struct cam_isp_hw_mgr_res *isp_hw_res,
|
||||
struct cam_tfe_hw_mgr_ctx *ctx)
|
||||
|
|
@ -1824,6 +1900,105 @@ void cam_tfe_cam_cdm_callback(uint32_t handle, void *userdata,
|
|||
}
|
||||
}
|
||||
|
||||
int cam_tfe_cshiphy_callback(
|
||||
struct cam_tfe_hw_mgr_ctx *ctx, void *cmd_args)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
uint32_t *phy_clock_rate;
|
||||
uint32_t clock_rate = 0;
|
||||
uint32_t csid_clock_rate = 0, tfe_clock_rate = 0;
|
||||
uint32_t updated_tfe_clk = 0, updated_csid_clk = 0;
|
||||
|
||||
if (!ctx || !cmd_args) {
|
||||
CAM_ERR(CAM_ISP, "Invalid arguments");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
phy_clock_rate = (uint32_t *)cmd_args;
|
||||
CAM_DBG(CAM_ISP, "clk rate csid ... in ctx id:%d",
|
||||
ctx->ctx_index);
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_csid, list) {
|
||||
rc = cam_tfe_hw_mgr_get_clock_rate(hw_mgr_res,
|
||||
&clock_rate);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Can not get CSID clock rate(id :%d)",
|
||||
hw_mgr_res->res_id);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!csid_clock_rate)
|
||||
csid_clock_rate = clock_rate;
|
||||
|
||||
if (clock_rate < csid_clock_rate)
|
||||
csid_clock_rate = clock_rate;
|
||||
|
||||
CAM_DBG(CAM_ISP, "clk rate csid: %lld %lld",
|
||||
clock_rate, csid_clock_rate);
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "clk rate TFE in resource ctx id:%d",
|
||||
ctx->ctx_index);
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_in, list) {
|
||||
rc = cam_tfe_hw_mgr_get_clock_rate(hw_mgr_res,
|
||||
&clock_rate);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Can not get TFE clock rate (%d)",
|
||||
hw_mgr_res->res_id);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!tfe_clock_rate)
|
||||
tfe_clock_rate = clock_rate;
|
||||
|
||||
if (clock_rate < tfe_clock_rate)
|
||||
tfe_clock_rate = clock_rate;
|
||||
|
||||
CAM_DBG(CAM_ISP, "clk rate tfe: %lld %lld",
|
||||
clock_rate, tfe_clock_rate);
|
||||
}
|
||||
|
||||
if (*phy_clock_rate > csid_clock_rate) {
|
||||
list_for_each_entry(hw_mgr_res,
|
||||
&ctx->res_list_tfe_csid, list) {
|
||||
rc = cam_tfe_hw_mgr_update_clock_rate(hw_mgr_res,
|
||||
phy_clock_rate, &updated_csid_clk);
|
||||
}
|
||||
|
||||
if (updated_csid_clk > tfe_clock_rate) {
|
||||
list_for_each_entry(hw_mgr_res,
|
||||
&ctx->res_list_tfe_in, list) {
|
||||
rc = cam_tfe_hw_mgr_update_clock_rate(hw_mgr_res,
|
||||
&updated_csid_clk, &updated_tfe_clk);
|
||||
}
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (csid_clock_rate > tfe_clock_rate) {
|
||||
list_for_each_entry(hw_mgr_res,
|
||||
&ctx->res_list_tfe_in, list) {
|
||||
rc = cam_tfe_hw_mgr_update_clock_rate(hw_mgr_res,
|
||||
&csid_clock_rate, &updated_tfe_clk);
|
||||
}
|
||||
}
|
||||
end:
|
||||
/* final check */
|
||||
if ((*phy_clock_rate > updated_csid_clk) ||
|
||||
(updated_csid_clk > updated_tfe_clk) ||
|
||||
(*phy_clock_rate > updated_tfe_clk)) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"improper clock rates, phy:%lld csid:%lld tfe:%lld",
|
||||
*phy_clock_rate, updated_csid_clk, updated_tfe_clk);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* entry function: acquire_hw */
|
||||
static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
||||
{
|
||||
|
|
@ -4761,6 +4936,9 @@ static int cam_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
|
|||
isp_hw_cmd_args->u.last_cdm_done =
|
||||
ctx->last_cdm_done_req;
|
||||
break;
|
||||
case CAM_ISP_HW_MGR_CMD_UPDATE_CLOCK:
|
||||
rc = cam_tfe_cshiphy_callback(ctx, isp_hw_cmd_args->cmd_data);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x",
|
||||
hw_cmd_args->cmd_type);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ enum cam_isp_hw_event_type {
|
|||
CAM_ISP_HW_EVENT_MAX
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* enum cam_isp_hw_err_type - Collection of the ISP error types for
|
||||
* ISP hardware event CAM_ISP_HW_EVENT_ERROR
|
||||
|
|
@ -241,6 +240,7 @@ enum cam_isp_hw_mgr_command {
|
|||
CAM_ISP_HW_MGR_CMD_CTX_TYPE,
|
||||
CAM_ISP_HW_MGR_GET_PACKET_OPCODE,
|
||||
CAM_ISP_HW_MGR_GET_LAST_CDM_DONE,
|
||||
CAM_ISP_HW_MGR_CMD_UPDATE_CLOCK,
|
||||
CAM_ISP_HW_MGR_CMD_MAX,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ enum cam_isp_hw_cmd_type {
|
|||
CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE,
|
||||
CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG,
|
||||
CAM_ISP_HW_CMD_QUERY_BUS_CAP,
|
||||
CAM_ISP_HW_CMD_GET_CLOCK_RATE,
|
||||
CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE,
|
||||
CAM_ISP_HW_CMD_MAX,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2404,6 +2404,52 @@ static int cam_tfe_csid_set_csid_clock(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_tfe_csid_get_csid_clock(
|
||||
struct cam_tfe_csid_hw *csid_hw, void *cmd_args)
|
||||
{
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
uint32_t *curr_clk_rate;
|
||||
int src_clk_idx;
|
||||
int rc = 0;
|
||||
|
||||
if (!csid_hw)
|
||||
return -EINVAL;
|
||||
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
src_clk_idx = soc_info->src_clk_idx;
|
||||
|
||||
curr_clk_rate = (uint32_t *)cmd_args;
|
||||
|
||||
rc = cam_soc_util_get_clk_rate(soc_info->clk[src_clk_idx],
|
||||
soc_info->clk_name[src_clk_idx], curr_clk_rate);
|
||||
|
||||
CAM_DBG(CAM_ISP, "CSID clock rate %llu", *curr_clk_rate);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_tfe_csid_set_csid_clock_dynamically(
|
||||
struct cam_tfe_csid_hw *csid_hw, void *cmd_args)
|
||||
{
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
uint32_t *clk_rate;
|
||||
int rc = 0;
|
||||
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
clk_rate = (uint32_t *)cmd_args;
|
||||
|
||||
CAM_DBG(CAM_ISP, "CSID clock rate %lld", *clk_rate);
|
||||
|
||||
rc = cam_soc_util_set_src_clk_rate(soc_info, *clk_rate);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"unable to set clock dynamically rate:%lld", *clk_rate);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_tfe_csid_get_regdump(struct cam_tfe_csid_hw *csid_hw,
|
||||
void *cmd_args)
|
||||
{
|
||||
|
|
@ -2676,6 +2722,12 @@ static int cam_tfe_csid_process_cmd(void *hw_priv,
|
|||
case CAM_TFE_CSID_LOG_ACQUIRE_DATA:
|
||||
rc = cam_tfe_csid_log_acquire_data(csid_hw, cmd_args);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_GET_CLOCK_RATE:
|
||||
rc = cam_tfe_csid_get_csid_clock(csid_hw, cmd_args);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE:
|
||||
rc = cam_tfe_csid_set_csid_clock_dynamically(csid_hw, cmd_args);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
|
||||
csid_hw->hw_intf->hw_idx, cmd_type);
|
||||
|
|
|
|||
|
|
@ -969,6 +969,62 @@ static int cam_tfe_top_set_hw_clk_rate(
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int cam_tfe_top_get_hw_clk_rate(
|
||||
struct cam_tfe_top_priv *top_priv,
|
||||
void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
uint32_t *curr_clk_rate;
|
||||
int src_clk_idx;
|
||||
int rc = 0;
|
||||
|
||||
if (!top_priv) {
|
||||
CAM_ERR(CAM_ISP, "Error top_private NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
soc_info = top_priv->common_data.soc_info;
|
||||
src_clk_idx = soc_info->src_clk_idx;
|
||||
|
||||
curr_clk_rate = (uint32_t *)cmd_args;
|
||||
|
||||
rc = cam_soc_util_get_clk_rate(soc_info->clk[src_clk_idx],
|
||||
soc_info->clk_name[src_clk_idx], curr_clk_rate);
|
||||
|
||||
CAM_DBG(CAM_ISP, "TFE clock rate %llu", *curr_clk_rate);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_tfe_top_dynamic_clock_update(
|
||||
struct cam_tfe_top_priv *top_priv,
|
||||
void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
int src_clk_idx;
|
||||
uint32_t *clk_rate;
|
||||
int rc = 0;
|
||||
|
||||
soc_info = top_priv->common_data.soc_info;
|
||||
src_clk_idx = soc_info->src_clk_idx;
|
||||
|
||||
clk_rate = (uint32_t *)cmd_args;
|
||||
|
||||
CAM_DBG(CAM_ISP, "TFE clock rate %lld", *clk_rate);
|
||||
|
||||
rc = cam_soc_util_set_src_clk_rate(soc_info, *clk_rate);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"unable to set clock dynamically rate:%lld",
|
||||
*clk_rate);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct cam_axi_vote *cam_tfe_top_delay_bw_reduction(
|
||||
struct cam_tfe_top_priv *top_priv,
|
||||
uint64_t *to_be_applied_bw)
|
||||
|
|
@ -2881,6 +2937,14 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
|||
rc = cam_tfe_set_top_debug(core_info, cmd_args,
|
||||
arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_GET_CLOCK_RATE:
|
||||
rc = cam_tfe_top_get_hw_clk_rate(core_info->top_priv, cmd_args,
|
||||
arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE:
|
||||
rc = cam_tfe_top_dynamic_clock_update(core_info->top_priv, cmd_args,
|
||||
arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_GET_BUF_UPDATE:
|
||||
case CAM_ISP_HW_CMD_GET_HFR_UPDATE:
|
||||
case CAM_ISP_HW_CMD_STRIPE_UPDATE:
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
#define CAM_SUBDEVICE_EVENT_MAX 30
|
||||
|
||||
enum cam_subdev_message_type_t {
|
||||
CAM_SUBDEV_MESSAGE_IRQ_ERR = 0x1
|
||||
CAM_SUBDEV_MESSAGE_IRQ_ERR = 0x1,
|
||||
CAM_SUBDEV_MESSAGE_CLOCK_UPDATE
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -346,6 +346,23 @@ int cam_soc_util_irq_disable(struct cam_hw_soc_info *soc_info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int cam_soc_util_get_clk_rate(struct clk *clk, const char *clk_name,
|
||||
uint32_t *clk_rate)
|
||||
{
|
||||
uint32_t clk_rate_round;
|
||||
|
||||
clk_rate_round = clk_get_rate(clk);
|
||||
if (clk_rate_round < 0) {
|
||||
CAM_ERR(CAM_UTIL, "get_rate failed on %s", clk_name);
|
||||
return clk_rate_round;
|
||||
}
|
||||
|
||||
*clk_rate = clk_rate_round;
|
||||
CAM_DBG(CAM_UTIL, "get rate %lld on %s", *clk_rate, clk_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long cam_soc_util_get_clk_round_rate(struct cam_hw_soc_info *soc_info,
|
||||
uint32_t clk_index, unsigned long clk_rate)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -405,6 +405,19 @@ int cam_soc_util_disable_platform_resource(struct cam_hw_soc_info *soc_info,
|
|||
long cam_soc_util_get_clk_round_rate(struct cam_hw_soc_info *soc_info,
|
||||
uint32_t clk_index, unsigned long clk_rate);
|
||||
|
||||
/**
|
||||
* cam_soc_util_get_clk_rate()
|
||||
*
|
||||
* @brief: Get the rate on the source clock.
|
||||
* @clk: Src clock reference pointer to get clock rate
|
||||
* @clk_name: Name of src clock
|
||||
* @clk_rate: Clock rate associated with the src clk
|
||||
*
|
||||
* @return: success or failure
|
||||
*/
|
||||
int cam_soc_util_get_clk_rate(struct clk *clk, const char *clk_name,
|
||||
uint32_t *clk_rate);
|
||||
|
||||
/**
|
||||
* cam_soc_util_set_src_clk_rate()
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue