blob: bf2f37084cd10e26caba8a1c88e7a11d04ae8cff [file] [log] [blame]
/* 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_LRME_HW_CORE_H_
#define _CAM_LRME_HW_CORE_H_
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <media/cam_defs.h>
#include <media/cam_lrme.h>
#include "cam_common_util.h"
#include "cam_debug_util.h"
#include "cam_io_util.h"
#include "cam_cpas_api.h"
#include "cam_cdm_intf_api.h"
#include "cam_lrme_hw_intf.h"
#include "cam_lrme_hw_soc.h"
#include "cam_req_mgr_workq.h"
#define CAM_LRME_HW_RESET_TIMEOUT 3000
#define CAM_LRME_BUS_RD_MAX_CLIENTS 2
#define CAM_LRME_BUS_WR_MAX_CLIENTS 2
#define CAM_LRME_HW_WORKQ_NUM_TASK 30
#define CAM_LRME_TOP_IRQ_MASK 0x19
#define CAM_LRME_WE_IRQ_MASK_0 0x2
#define CAM_LRME_WE_IRQ_MASK_1 0x0
#define CAM_LRME_FE_IRQ_MASK 0x0
#define CAM_LRME_MAX_REG_PAIR_NUM 60
/**
* enum cam_lrme_irq_set
*
* @CAM_LRME_IRQ_ENABLE : Enable irqs
* @CAM_LRME_IRQ_DISABLE : Disable irqs
*/
enum cam_lrme_irq_set {
CAM_LRME_IRQ_ENABLE,
CAM_LRME_IRQ_DISABLE,
};
/**
* struct cam_lrme_cdm_info : information used to submit cdm command
*
* @cdm_handle : CDM handle for this device
* @cdm_ops : CDM ops
* @cdm_cmd : CDM command pointer
*/
struct cam_lrme_cdm_info {
uint32_t cdm_handle;
struct cam_cdm_utils_ops *cdm_ops;
struct cam_cdm_bl_request *cdm_cmd;
};
/**
* struct cam_lrme_hw_work_data : Work data for HW work queue
*
* @top_irq_status : Top registers irq status
* @fe_irq_status : FE engine irq status
* @we_irq_status : WE engine irq status
*/
struct cam_lrme_hw_work_data {
uint32_t top_irq_status;
uint32_t fe_irq_status;
uint32_t we_irq_status[2];
};
/**
* enum cam_lrme_core_state : LRME core states
*
* @CAM_LRME_CORE_STATE_UNINIT : LRME is in uninit state
* @CAM_LRME_CORE_STATE_INIT : LRME is in init state after probe
* @ CAM_LRME_CORE_STATE_IDLE : LRME is in idle state. Hardware is in
* this state when no frame is processing
* or waiting for this core.
* @CAM_LRME_CORE_STATE_REQ_PENDING : LRME is in pending state. One frame is
* waiting for processing
* @CAM_LRME_CORE_STATE_PROCESSING : LRME is in processing state. HW manager
* can submit one more frame to HW
* @CAM_LRME_CORE_STATE_REQ_PROC_PEND : Indicate two frames are inside HW.
* @CAM_LRME_CORE_STATE_RECOVERY : Indicate core is in the process of reset
* @CAM_LRME_CORE_STATE_MAX : upper limit of states
*/
enum cam_lrme_core_state {
CAM_LRME_CORE_STATE_UNINIT,
CAM_LRME_CORE_STATE_INIT,
CAM_LRME_CORE_STATE_IDLE,
CAM_LRME_CORE_STATE_REQ_PENDING,
CAM_LRME_CORE_STATE_PROCESSING,
CAM_LRME_CORE_STATE_REQ_PROC_PEND,
CAM_LRME_CORE_STATE_RECOVERY,
CAM_LRME_CORE_STATE_MAX,
};
/**
* struct cam_lrme_core : LRME HW core information
*
* @hw_info : Pointer to base HW information structure
* @device_iommu : Device iommu handle
* @cdm_iommu : CDM iommu handle
* @hw_caps : Hardware capabilities
* @state : Hardware state
* @reset_complete : Reset completion
* @work : Hardware workqueue to handle irq events
* @work_data : Work data used by hardware workqueue
* @hw_mgr_cb : Hw manager callback
* @req_proc : Pointer to the processing frame request
* @req_submit : Pointer to the frame request waiting for processing
* @hw_cdm_info : CDM information used by this device
* @hw_idx : Hardware index
*/
struct cam_lrme_core {
struct cam_lrme_hw_info *hw_info;
struct cam_iommu_handle device_iommu;
struct cam_iommu_handle cdm_iommu;
struct cam_lrme_dev_cap hw_caps;
enum cam_lrme_core_state state;
struct completion reset_complete;
struct cam_req_mgr_core_workq *work;
struct cam_lrme_hw_work_data work_data[CAM_LRME_HW_WORKQ_NUM_TASK];
struct cam_lrme_hw_cmd_set_cb hw_mgr_cb;
struct cam_lrme_frame_request *req_proc;
struct cam_lrme_frame_request *req_submit;
struct cam_lrme_cdm_info *hw_cdm_info;
uint32_t hw_idx;
};
/**
* struct cam_lrme_bus_rd_reg_common : Offsets of FE common registers
*
* @hw_version : Offset of hw_version register
* @hw_capability : Offset of hw_capability register
* @sw_reset : Offset of sw_reset register
* @cgc_override : Offset of cgc_override register
* @irq_mask : Offset of irq_mask register
* @irq_clear : Offset of irq_clear register
* @irq_cmd : Offset of irq_cmd register
* @irq_status : Offset of irq_status register
* @cmd : Offset of cmd register
* @irq_set : Offset of irq_set register
* @misr_reset : Offset of misr_reset register
* @security_cfg : Offset of security_cfg register
* @pwr_iso_cfg : Offset of pwr_iso_cfg register
* @pwr_iso_seed : Offset of pwr_iso_seed register
* @test_bus_ctrl : Offset of test_bus_ctrl register
* @spare : Offset of spare register
*/
struct cam_lrme_bus_rd_reg_common {
uint32_t hw_version;
uint32_t hw_capability;
uint32_t sw_reset;
uint32_t cgc_override;
uint32_t irq_mask;
uint32_t irq_clear;
uint32_t irq_cmd;
uint32_t irq_status;
uint32_t cmd;
uint32_t irq_set;
uint32_t misr_reset;
uint32_t security_cfg;
uint32_t pwr_iso_cfg;
uint32_t pwr_iso_seed;
uint32_t test_bus_ctrl;
uint32_t spare;
};
/**
* struct cam_lrme_bus_wr_reg_common : Offset of WE common registers
* @hw_version : Offset of hw_version register
* @hw_capability : Offset of hw_capability register
* @sw_reset : Offset of sw_reset register
* @cgc_override : Offset of cgc_override register
* @misr_reset : Offset of misr_reset register
* @pwr_iso_cfg : Offset of pwr_iso_cfg register
* @test_bus_ctrl : Offset of test_bus_ctrl register
* @composite_mask_0 : Offset of composite_mask_0 register
* @irq_mask_0 : Offset of irq_mask_0 register
* @irq_mask_1 : Offset of irq_mask_1 register
* @irq_clear_0 : Offset of irq_clear_0 register
* @irq_clear_1 : Offset of irq_clear_1 register
* @irq_status_0 : Offset of irq_status_0 register
* @irq_status_1 : Offset of irq_status_1 register
* @irq_cmd : Offset of irq_cmd register
* @irq_set_0 : Offset of irq_set_0 register
* @irq_set_1 : Offset of irq_set_1 register
* @addr_fifo_status : Offset of addr_fifo_status register
* @frame_header_cfg0 : Offset of frame_header_cfg0 register
* @frame_header_cfg1 : Offset of frame_header_cfg1 register
* @spare : Offset of spare register
*/
struct cam_lrme_bus_wr_reg_common {
uint32_t hw_version;
uint32_t hw_capability;
uint32_t sw_reset;
uint32_t cgc_override;
uint32_t misr_reset;
uint32_t pwr_iso_cfg;
uint32_t test_bus_ctrl;
uint32_t composite_mask_0;
uint32_t irq_mask_0;
uint32_t irq_mask_1;
uint32_t irq_clear_0;
uint32_t irq_clear_1;
uint32_t irq_status_0;
uint32_t irq_status_1;
uint32_t irq_cmd;
uint32_t irq_set_0;
uint32_t irq_set_1;
uint32_t addr_fifo_status;
uint32_t frame_header_cfg0;
uint32_t frame_header_cfg1;
uint32_t spare;
};
/**
* struct cam_lrme_bus_rd_bus_client : Offset of FE registers
*
* @core_cfg : Offset of core_cfg register
* @ccif_meta_data : Offset of ccif_meta_data register
* @addr_image : Offset of addr_image register
* @rd_buffer_size : Offset of rd_buffer_size register
* @rd_stride : Offset of rd_stride register
* @unpack_cfg_0 : Offset of unpack_cfg_0 register
* @latency_buff_allocation : Offset of latency_buff_allocation register
* @burst_limit_cfg : Offset of burst_limit_cfg register
* @misr_cfg_0 : Offset of misr_cfg_0 register
* @misr_cfg_1 : Offset of misr_cfg_1 register
* @misr_rd_val : Offset of misr_rd_val register
* @debug_status_cfg : Offset of debug_status_cfg register
* @debug_status_0 : Offset of debug_status_0 register
* @debug_status_1 : Offset of debug_status_1 register
*/
struct cam_lrme_bus_rd_bus_client {
uint32_t core_cfg;
uint32_t ccif_meta_data;
uint32_t addr_image;
uint32_t rd_buffer_size;
uint32_t rd_stride;
uint32_t unpack_cfg_0;
uint32_t latency_buff_allocation;
uint32_t burst_limit_cfg;
uint32_t misr_cfg_0;
uint32_t misr_cfg_1;
uint32_t misr_rd_val;
uint32_t debug_status_cfg;
uint32_t debug_status_0;
uint32_t debug_status_1;
};
/**
* struct cam_lrme_bus_wr_bus_client : Offset of WE registers
*
* @status_0 : Offset of status_0 register
* @status_1 : Offset of status_1 register
* @cfg : Offset of cfg register
* @addr_frame_header : Offset of addr_frame_header register
* @frame_header_cfg : Offset of frame_header_cfg register
* @addr_image : Offset of addr_image register
* @addr_image_offset : Offset of addr_image_offset register
* @buffer_width_cfg : Offset of buffer_width_cfg register
* @buffer_height_cfg : Offset of buffer_height_cfg register
* @packer_cfg : Offset of packer_cfg register
* @wr_stride : Offset of wr_stride register
* @irq_subsample_cfg_period : Offset of irq_subsample_cfg_period register
* @irq_subsample_cfg_pattern : Offset of irq_subsample_cfg_pattern register
* @burst_limit_cfg : Offset of burst_limit_cfg register
* @misr_cfg : Offset of misr_cfg register
* @misr_rd_word_sel : Offset of misr_rd_word_sel register
* @misr_val : Offset of misr_val register
* @debug_status_cfg : Offset of debug_status_cfg register
* @debug_status_0 : Offset of debug_status_0 register
* @debug_status_1 : Offset of debug_status_1 register
*/
struct cam_lrme_bus_wr_bus_client {
uint32_t status_0;
uint32_t status_1;
uint32_t cfg;
uint32_t addr_frame_header;
uint32_t frame_header_cfg;
uint32_t addr_image;
uint32_t addr_image_offset;
uint32_t buffer_width_cfg;
uint32_t buffer_height_cfg;
uint32_t packer_cfg;
uint32_t wr_stride;
uint32_t irq_subsample_cfg_period;
uint32_t irq_subsample_cfg_pattern;
uint32_t burst_limit_cfg;
uint32_t misr_cfg;
uint32_t misr_rd_word_sel;
uint32_t misr_val;
uint32_t debug_status_cfg;
uint32_t debug_status_0;
uint32_t debug_status_1;
};
/**
* struct cam_lrme_bus_rd_hw_info : FE registers information
*
* @common_reg : FE common register
* @bus_client_reg : List of FE bus registers information
*/
struct cam_lrme_bus_rd_hw_info {
struct cam_lrme_bus_rd_reg_common common_reg;
struct cam_lrme_bus_rd_bus_client
bus_client_reg[CAM_LRME_BUS_RD_MAX_CLIENTS];
};
/**
* struct cam_lrme_bus_wr_hw_info : WE engine registers information
*
* @common_reg : WE common register
* @bus_client_reg : List of WE bus registers information
*/
struct cam_lrme_bus_wr_hw_info {
struct cam_lrme_bus_wr_reg_common common_reg;
struct cam_lrme_bus_wr_bus_client
bus_client_reg[CAM_LRME_BUS_WR_MAX_CLIENTS];
};
/**
* struct cam_lrme_clc_reg : Offset of clc registers
*
* @clc_hw_version : Offset of clc_hw_version register
* @clc_hw_status : Offset of clc_hw_status register
* @clc_hw_status_dbg : Offset of clc_hw_status_dbg register
* @clc_module_cfg : Offset of clc_module_cfg register
* @clc_moduleformat : Offset of clc_moduleformat register
* @clc_rangestep : Offset of clc_rangestep register
* @clc_offset : Offset of clc_offset register
* @clc_maxallowedsad : Offset of clc_maxallowedsad register
* @clc_minallowedtarmad : Offset of clc_minallowedtarmad register
* @clc_meaningfulsaddiff : Offset of clc_meaningfulsaddiff register
* @clc_minsaddiffdenom : Offset of clc_minsaddiffdenom register
* @clc_robustnessmeasuredistmap_0 : Offset of measuredistmap_0 register
* @clc_robustnessmeasuredistmap_1 : Offset of measuredistmap_1 register
* @clc_robustnessmeasuredistmap_2 : Offset of measuredistmap_2 register
* @clc_robustnessmeasuredistmap_3 : Offset of measuredistmap_3 register
* @clc_robustnessmeasuredistmap_4 : Offset of measuredistmap_4 register
* @clc_robustnessmeasuredistmap_5 : Offset of measuredistmap_5 register
* @clc_robustnessmeasuredistmap_6 : Offset of measuredistmap_6 register
* @clc_robustnessmeasuredistmap_7 : Offset of measuredistmap_7 register
* @clc_ds_crop_horizontal : Offset of clc_ds_crop_horizontal register
* @clc_ds_crop_vertical : Offset of clc_ds_crop_vertical register
* @clc_tar_pd_unpacker : Offset of clc_tar_pd_unpacker register
* @clc_ref_pd_unpacker : Offset of clc_ref_pd_unpacker register
* @clc_sw_override : Offset of clc_sw_override register
* @clc_tar_height : Offset of clc_tar_height register
* @clc_test_bus_ctrl : Offset of clc_test_bus_ctrl register
* @clc_spare : Offset of clc_spare register
*/
struct cam_lrme_clc_reg {
uint32_t clc_hw_version;
uint32_t clc_hw_status;
uint32_t clc_hw_status_dbg;
uint32_t clc_module_cfg;
uint32_t clc_moduleformat;
uint32_t clc_rangestep;
uint32_t clc_offset;
uint32_t clc_maxallowedsad;
uint32_t clc_minallowedtarmad;
uint32_t clc_meaningfulsaddiff;
uint32_t clc_minsaddiffdenom;
uint32_t clc_robustnessmeasuredistmap_0;
uint32_t clc_robustnessmeasuredistmap_1;
uint32_t clc_robustnessmeasuredistmap_2;
uint32_t clc_robustnessmeasuredistmap_3;
uint32_t clc_robustnessmeasuredistmap_4;
uint32_t clc_robustnessmeasuredistmap_5;
uint32_t clc_robustnessmeasuredistmap_6;
uint32_t clc_robustnessmeasuredistmap_7;
uint32_t clc_ds_crop_horizontal;
uint32_t clc_ds_crop_vertical;
uint32_t clc_tar_pd_unpacker;
uint32_t clc_ref_pd_unpacker;
uint32_t clc_sw_override;
uint32_t clc_tar_height;
uint32_t clc_ref_height;
uint32_t clc_test_bus_ctrl;
uint32_t clc_spare;
};
/**
* struct cam_lrme_titan_reg : Offset of LRME top registers
*
* @top_hw_version : Offset of top_hw_version register
* @top_titan_version : Offset of top_titan_version register
* @top_rst_cmd : Offset of top_rst_cmd register
* @top_core_clk_cfg : Offset of top_core_clk_cfg register
* @top_irq_status : Offset of top_irq_status register
* @top_irq_mask : Offset of top_irq_mask register
* @top_irq_clear : Offset of top_irq_clear register
* @top_irq_set : Offset of top_irq_set register
* @top_irq_cmd : Offset of top_irq_cmd register
* @top_violation_status : Offset of top_violation_status register
* @top_spare : Offset of top_spare register
*/
struct cam_lrme_titan_reg {
uint32_t top_hw_version;
uint32_t top_titan_version;
uint32_t top_rst_cmd;
uint32_t top_core_clk_cfg;
uint32_t top_irq_status;
uint32_t top_irq_mask;
uint32_t top_irq_clear;
uint32_t top_irq_set;
uint32_t top_irq_cmd;
uint32_t top_violation_status;
uint32_t top_spare;
};
/**
* struct cam_lrme_hw_info : LRME registers information
*
* @clc_reg : LRME CLC registers
* @bus_rd_reg : LRME FE registers
* @bus_wr_reg : LRME WE registers
* @titan_reg : LRME top reisters
*/
struct cam_lrme_hw_info {
struct cam_lrme_clc_reg clc_reg;
struct cam_lrme_bus_rd_hw_info bus_rd_reg;
struct cam_lrme_bus_wr_hw_info bus_wr_reg;
struct cam_lrme_titan_reg titan_reg;
};
int cam_lrme_hw_process_irq(void *priv, void *data);
int cam_lrme_hw_submit_req(void *hw_priv, void *hw_submit_args,
uint32_t arg_size);
int cam_lrme_hw_reset(void *hw_priv, void *reset_core_args, uint32_t arg_size);
int cam_lrme_hw_stop(void *hw_priv, void *stop_args, uint32_t arg_size);
int cam_lrme_hw_get_caps(void *hw_priv, void *get_hw_cap_args,
uint32_t arg_size);
irqreturn_t cam_lrme_hw_irq(int irq_num, void *data);
int cam_lrme_hw_process_cmd(void *hw_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size);
int cam_lrme_hw_util_get_caps(struct cam_hw_info *lrme_hw,
struct cam_lrme_dev_cap *hw_caps);
int cam_lrme_hw_start(void *hw_priv, void *hw_init_args, uint32_t arg_size);
int cam_lrme_hw_flush(void *hw_priv, void *hw_flush_args, uint32_t arg_size);
void cam_lrme_set_irq(struct cam_hw_info *lrme_hw, enum cam_lrme_irq_set set);
#endif /* _CAM_LRME_HW_CORE_H_ */