msm: camera: ope: Add dynamic clock support

Dynamic clock and bandwidth support is added to
OPE.

CRs-Fixed: 2594541
Change-Id: Ib53ec47c7074f01f1bb55e17c97e5dacc550a129
Signed-off-by: Suresh Vankadara <svankada@codeaurora.org>
Signed-off-by: Trishansh Bhardwaj <tbhardwa@codeaurora.org>
This commit is contained in:
Trishansh Bhardwaj
2019-12-20 14:52:45 +05:30
committed by Karthik Jayakumar
parent 12d9311463
commit a46b9bff7a
7 changed files with 1143 additions and 45 deletions

View File

@@ -40,7 +40,7 @@ static int cam_ope_context_dump_active_request(void *data, unsigned long iova,
mutex_lock(&ctx->ctx_mutex); mutex_lock(&ctx->ctx_mutex);
if (ctx->state < CAM_CTX_ACQUIRED || ctx->state > CAM_CTX_ACTIVATED) { if (ctx->state < CAM_CTX_ACQUIRED || ctx->state > CAM_CTX_ACTIVATED) {
CAM_ERR(CAM_ICP, "Invalid state icp ctx %d state %d", CAM_ERR(CAM_OPE, "Invalid state ope ctx %d state %d",
ctx->ctx_id, ctx->state); ctx->ctx_id, ctx->state);
goto end; goto end;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -52,6 +52,112 @@
#define OPE_MAX_CDM_BLS 16 #define OPE_MAX_CDM_BLS 16
#define CAM_OPE_MAX_PER_PATH_VOTES 6
#define CAM_OPE_BW_CONFIG_UNKNOWN 0
#define CAM_OPE_BW_CONFIG_V2 2
#define CLK_HW_OPE 0x0
#define CLK_HW_MAX 0x1
#define OPE_DEVICE_IDLE_TIMEOUT 400
/**
* struct cam_ope_clk_bw_request_v2
* @budget_ns: Time required to process frame
* @frame_cycles: Frame cycles needed to process the frame
* @rt_flag: Flag to indicate real time stream
* @num_paths: Number of paths for per path bw vote
* @axi_path: Per path vote info for OPE
*/
struct cam_ope_clk_bw_req_internal_v2 {
uint64_t budget_ns;
uint32_t frame_cycles;
uint32_t rt_flag;
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
};
/**
* struct cam_ope_clk_bw_request
* @budget_ns: Time required to process frame
* @frame_cycles: Frame cycles needed to process the frame
* @rt_flag: Flag to indicate real time stream
* @uncompressed_bw: Bandwidth required to process frame
* @compressed_bw: Compressed bandwidth to process frame
*/
struct cam_ope_clk_bw_request {
uint64_t budget_ns;
uint32_t frame_cycles;
uint32_t rt_flag;
uint64_t uncompressed_bw;
uint64_t compressed_bw;
};
/**
* struct cam_ctx_clk_info
* @curr_fc: Context latest request frame cycles
* @rt_flag: Flag to indicate real time request
* @base_clk: Base clock to process the request
* @reserved: Reserved field
* @uncompressed_bw: Current bandwidth voting
* @compressed_bw: Current compressed bandwidth voting
* @clk_rate: Supported clock rates for the context
* @num_paths: Number of valid AXI paths
* @axi_path: ctx based per path bw vote
*/
struct cam_ctx_clk_info {
uint32_t curr_fc;
uint32_t rt_flag;
uint32_t base_clk;
uint32_t reserved;
uint64_t uncompressed_bw;
uint64_t compressed_bw;
int32_t clk_rate[CAM_MAX_VOTE];
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
};
/**
* struct ope_cmd_generic_blob
* @ctx: Current context info
* @req_info_idx: Index used for request
* @io_buf_addr: pointer to io buffer address
*/
struct ope_cmd_generic_blob {
struct cam_ope_ctx *ctx;
uint32_t req_idx;
uint64_t *io_buf_addr;
};
/**
* struct cam_ope_clk_info
* @base_clk: Base clock to process request
* @curr_clk: Current clock of hadrware
* @threshold: Threshold for overclk count
* @over_clked: Over clock count
* @uncompressed_bw: Current bandwidth voting
* @compressed_bw: Current compressed bandwidth voting
* @num_paths: Number of AXI vote paths
* @axi_path: Current per path bw vote info
* @hw_type: IPE/BPS device type
* @watch_dog: watchdog timer handle
* @watch_dog_reset_counter: Counter for watch dog reset
*/
struct cam_ope_clk_info {
uint32_t base_clk;
uint32_t curr_clk;
uint32_t threshold;
uint32_t over_clked;
uint64_t uncompressed_bw;
uint64_t compressed_bw;
uint32_t num_paths;
struct cam_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
uint32_t hw_type;
struct cam_req_mgr_timer *watch_dog;
uint32_t watch_dog_reset_counter;
};
/** /**
* struct ope_cmd_work_data * struct ope_cmd_work_data
* *
@@ -273,6 +379,8 @@ struct ope_io_buf {
* @ope_debug_buf: Debug buffer * @ope_debug_buf: Debug buffer
* @io_buf: IO config info of a request * @io_buf: IO config info of a request
* @cdm_cmd: CDM command for OPE CDM * @cdm_cmd: CDM command for OPE CDM
* @clk_info: Clock Info V1
* @clk_info_v2: Clock Info V2
*/ */
struct cam_ope_request { struct cam_ope_request {
uint64_t request_id; uint64_t request_id;
@@ -290,6 +398,8 @@ struct cam_ope_request {
struct ope_debug_buffer ope_debug_buf; struct ope_debug_buffer ope_debug_buf;
struct ope_io_buf io_buf[OPE_MAX_BATCH_SIZE][OPE_MAX_IO_BUFS]; struct ope_io_buf io_buf[OPE_MAX_BATCH_SIZE][OPE_MAX_IO_BUFS];
struct cam_cdm_bl_request *cdm_cmd; struct cam_cdm_bl_request *cdm_cmd;
struct cam_ope_clk_bw_request clk_info;
struct cam_ope_clk_bw_req_internal_v2 clk_info_v2;
}; };
/** /**
@@ -320,6 +430,10 @@ struct cam_ope_cdm {
* @req_list: Request List * @req_list: Request List
* @ope_cdm: OPE CDM info * @ope_cdm: OPE CDM info
* @req_watch_dog: Watchdog for requests * @req_watch_dog: Watchdog for requests
* @req_watch_dog_reset_counter: Request reset counter
* @clk_info: OPE Ctx clock info
* @clk_watch_dog: Clock watchdog
* @clk_watch_dog_reset_counter: Reset counter
*/ */
struct cam_ope_ctx { struct cam_ope_ctx {
void *context_priv; void *context_priv;
@@ -336,6 +450,10 @@ struct cam_ope_ctx {
struct cam_ope_request *req_list[CAM_CTX_REQ_MAX]; struct cam_ope_request *req_list[CAM_CTX_REQ_MAX];
struct cam_ope_cdm ope_cdm; struct cam_ope_cdm ope_cdm;
struct cam_req_mgr_timer *req_watch_dog; struct cam_req_mgr_timer *req_watch_dog;
uint32_t req_watch_dog_reset_counter;
struct cam_ctx_clk_info clk_info;
struct cam_req_mgr_timer *clk_watch_dog;
uint32_t clk_watch_dog_reset_counter;
}; };
/** /**
@@ -366,6 +484,7 @@ struct cam_ope_ctx {
* @timer_work_data: Timer work data * @timer_work_data: Timer work data
* @ope_dev_intf: OPE device interface * @ope_dev_intf: OPE device interface
* @cdm_reg_map: OPE CDM register map * @cdm_reg_map: OPE CDM register map
* @clk_info: OPE clock Info for HW manager
*/ */
struct cam_ope_hw_mgr { struct cam_ope_hw_mgr {
int32_t open_cnt; int32_t open_cnt;
@@ -394,6 +513,7 @@ struct cam_ope_hw_mgr {
struct ope_clk_work_data *timer_work_data; struct ope_clk_work_data *timer_work_data;
struct cam_hw_intf *ope_dev_intf[OPE_DEV_MAX]; struct cam_hw_intf *ope_dev_intf[OPE_DEV_MAX];
struct cam_soc_reg_map *cdm_reg_map[OPE_DEV_MAX][OPE_BASE_MAX]; struct cam_soc_reg_map *cdm_reg_map[OPE_DEV_MAX][OPE_BASE_MAX];
struct cam_ope_clk_info clk_info;
}; };
#endif /* CAM_OPE_HW_MGR_H */ #endif /* CAM_OPE_HW_MGR_H */

View File

@@ -1711,11 +1711,28 @@ int cam_ope_process_cmd(void *device_priv, uint32_t cmd_type,
struct cam_ope_dev_clk_update *clk_upd_cmd = struct cam_ope_dev_clk_update *clk_upd_cmd =
(struct cam_ope_dev_clk_update *)cmd_args; (struct cam_ope_dev_clk_update *)cmd_args;
if (core_info->clk_enable == false) {
rc = cam_soc_util_clk_enable_default(soc_info,
CAM_SVS_VOTE);
if (rc) {
CAM_ERR(CAM_OPE, "Clock enable is failed");
return rc;
}
core_info->clk_enable = true;
}
rc = cam_ope_update_clk_rate(soc_info, clk_upd_cmd->clk_rate); rc = cam_ope_update_clk_rate(soc_info, clk_upd_cmd->clk_rate);
if (rc) if (rc)
CAM_ERR(CAM_OPE, "Failed to update clk: %d", rc); CAM_ERR(CAM_OPE, "Failed to update clk: %d", rc);
} }
break; break;
case OPE_HW_CLK_DISABLE: {
if (core_info->clk_enable == true)
cam_soc_util_clk_disable_default(soc_info);
core_info->clk_enable = false;
}
break;
case OPE_HW_BW_UPDATE: { case OPE_HW_BW_UPDATE: {
struct cam_ope_dev_bw_update *cpas_vote = cmd_args; struct cam_ope_dev_bw_update *cpas_vote = cmd_args;

View File

@@ -12,20 +12,22 @@
#include "cam_cpas_api.h" #include "cam_cpas_api.h"
#define OPE_HW_INIT 0x1 #define OPE_HW_INIT 0x1
#define OPE_HW_DEINIT 0x2 #define OPE_HW_DEINIT 0x2
#define OPE_HW_ACQUIRE 0x3 #define OPE_HW_ACQUIRE 0x3
#define OPE_HW_RELEASE 0x4 #define OPE_HW_RELEASE 0x4
#define OPE_HW_START 0x5 #define OPE_HW_START 0x5
#define OPE_HW_STOP 0x6 #define OPE_HW_STOP 0x6
#define OPE_HW_FLUSH 0x7 #define OPE_HW_FLUSH 0x7
#define OPE_HW_PREPARE 0x8 #define OPE_HW_PREPARE 0x8
#define OPE_HW_ISR 0x9 #define OPE_HW_ISR 0x9
#define OPE_HW_PROBE 0xA #define OPE_HW_PROBE 0xA
#define OPE_HW_CLK_UPDATE 0xB #define OPE_HW_CLK_UPDATE 0xB
#define OPE_HW_BW_UPDATE 0xC #define OPE_HW_BW_UPDATE 0xC
#define OPE_HW_RESET 0xD #define OPE_HW_RESET 0xD
#define OPE_HW_SET_IRQ_CB 0xE #define OPE_HW_SET_IRQ_CB 0xE
#define OPE_HW_CLK_DISABLE 0xF
#define OPE_HW_CLK_ENABLE 0x10
/** /**
* struct cam_ope_dev_probe * struct cam_ope_dev_probe

View File

@@ -8,7 +8,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/dma-buf.h> #include <linux/dma-buf.h>
#include <media/cam_defs.h> #include <media/cam_defs.h>
#include <media/cam_icp.h> #include <media/cam_ope.h>
#include "ope_soc.h" #include "ope_soc.h"
#include "cam_soc_util.h" #include "cam_soc_util.h"
#include "cam_debug_util.h" #include "cam_debug_util.h"

View File

@@ -52,6 +52,15 @@
#define CAM_AXI_PATH_DATA_OPE_MAX_OFFSET \ #define CAM_AXI_PATH_DATA_OPE_MAX_OFFSET \
(CAM_AXI_PATH_DATA_OPE_START_OFFSET + 31) (CAM_AXI_PATH_DATA_OPE_START_OFFSET + 31)
#define CAM_AXI_PATH_DATA_OPE_START_OFFSET 64
#define CAM_AXI_PATH_DATA_OPE_RD_IN (CAM_AXI_PATH_DATA_OPE_START_OFFSET + 0)
#define CAM_AXI_PATH_DATA_OPE_RD_REF (CAM_AXI_PATH_DATA_OPE_START_OFFSET + 1)
#define CAM_AXI_PATH_DATA_OPE_WR_VID (CAM_AXI_PATH_DATA_OPE_START_OFFSET + 2)
#define CAM_AXI_PATH_DATA_OPE_WR_DISP (CAM_AXI_PATH_DATA_OPE_START_OFFSET + 3)
#define CAM_AXI_PATH_DATA_OPE_WR_REF (CAM_AXI_PATH_DATA_OPE_START_OFFSET + 4)
#define CAM_AXI_PATH_DATA_OPE_MAX_OFFSET \
(CAM_AXI_PATH_DATA_OPE_START_OFFSET + 31)
#define CAM_AXI_PATH_DATA_ALL 256 #define CAM_AXI_PATH_DATA_ALL 256
/** /**