mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 23:24:22 -04:00
Merge "msm: camera: icp: Adapt HFI to processor specific irq management" into camera-kernel.lnx.4.0
This commit is contained in:
commit
6272ed41ba
7 changed files with 92 additions and 29 deletions
|
|
@ -49,6 +49,16 @@ struct hfi_mem_info {
|
|||
void __iomem *icp_base;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hfi_ops
|
||||
* @irq_raise: called to raise H2ICP interrupt
|
||||
* @irq_enable: called to enable interrupts from ICP
|
||||
*/
|
||||
struct hfi_ops {
|
||||
void (*irq_raise)(void *data);
|
||||
void (*irq_enable)(void *data);
|
||||
};
|
||||
|
||||
/**
|
||||
* hfi_write_cmd() - function for hfi write
|
||||
* @cmd_ptr: pointer to command data for hfi write
|
||||
|
|
@ -70,14 +80,16 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id, uint32_t *words_read);
|
|||
|
||||
/**
|
||||
* hfi_init() - function initialize hfi after firmware download
|
||||
* @event_driven_mode: event mode
|
||||
* @hfi_mem: hfi memory info
|
||||
* @hfi_ops: processor-specific hfi ops
|
||||
* @priv: device private data
|
||||
* @event_driven_mode: event mode
|
||||
* @icp_base: icp base address
|
||||
*
|
||||
* Returns success(zero)/failure(non zero)
|
||||
*/
|
||||
int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
|
||||
void *__iomem icp_base);
|
||||
int cam_hfi_init(struct hfi_mem_info *hfi_mem, struct hfi_ops *hfi_ops,
|
||||
void *priv, uint8_t event_driven_mode, void *__iomem icp_base);
|
||||
|
||||
/**
|
||||
* hfi_get_hw_caps() - hardware capabilities from firmware
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@
|
|||
|
||||
/* start of ICP CSR registers */
|
||||
#define HFI_REG_A5_HW_VERSION 0x0
|
||||
#define HFI_REG_A5_CSR_A2HOSTINTEN 0x10
|
||||
#define HFI_REG_A5_CSR_HOST2ICPINT 0x30
|
||||
|
||||
/* general purpose registers from */
|
||||
#define HFI_REG_FW_VERSION 0x44
|
||||
|
|
@ -97,19 +95,6 @@ enum reg_settings {
|
|||
SET_WM = 1024
|
||||
};
|
||||
|
||||
/**
|
||||
* @INTR_DISABLE: Disable interrupt
|
||||
* @INTR_ENABLE: Enable interrupt
|
||||
* @INTR_ENABLE_WD0: Enable WD0
|
||||
* @INTR_ENABLE_WD1: Enable WD1
|
||||
*/
|
||||
enum intr_status {
|
||||
INTR_DISABLE,
|
||||
INTR_ENABLE,
|
||||
INTR_ENABLE_WD0,
|
||||
INTR_ENABLE_WD1 = 0x4
|
||||
};
|
||||
|
||||
/**
|
||||
* @ICP_INIT_RESP_RESET: reset init state
|
||||
* @ICP_INIT_RESP_SUCCESS: init success
|
||||
|
|
@ -284,6 +269,7 @@ struct hfi_qtbl {
|
|||
/**
|
||||
* struct hfi_info
|
||||
* @map: Hfi shared memory info
|
||||
* @ops: processor-specific ops
|
||||
* @smem_size: Shared memory size
|
||||
* @uncachedheap_size: uncached heap size
|
||||
* @msgpacket_buf: message buffer
|
||||
|
|
@ -293,9 +279,11 @@ struct hfi_qtbl {
|
|||
* @mutex msg_q_lock: Lock for message queue
|
||||
* @msg_q_state: State of message queue
|
||||
* @csr_base: CSR base address
|
||||
* @priv: device private data
|
||||
*/
|
||||
struct hfi_info {
|
||||
struct hfi_mem_info map;
|
||||
struct hfi_ops ops;
|
||||
uint32_t smem_size;
|
||||
uint32_t uncachedheap_size;
|
||||
uint32_t msgpacket_buf[ICP_HFI_MAX_MSG_SIZE_IN_WORDS];
|
||||
|
|
@ -305,6 +293,7 @@ struct hfi_info {
|
|||
struct mutex msg_q_lock;
|
||||
bool msg_q_state;
|
||||
void __iomem *csr_base;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
#endif /* _CAM_HFI_REG_H_ */
|
||||
|
|
|
|||
|
|
@ -39,6 +39,18 @@ unsigned int g_icp_mmu_hdl;
|
|||
static DEFINE_MUTEX(hfi_cmd_q_mutex);
|
||||
static DEFINE_MUTEX(hfi_msg_q_mutex);
|
||||
|
||||
static void hfi_irq_raise(struct hfi_info *hfi)
|
||||
{
|
||||
if (hfi->ops.irq_raise)
|
||||
hfi->ops.irq_raise(hfi->priv);
|
||||
}
|
||||
|
||||
static void hfi_irq_enable(struct hfi_info *hfi)
|
||||
{
|
||||
if (hfi->ops.irq_enable)
|
||||
hfi->ops.irq_enable(hfi->priv);
|
||||
}
|
||||
|
||||
void cam_hfi_queue_dump(void)
|
||||
{
|
||||
struct hfi_qtbl *qtbl;
|
||||
|
|
@ -160,8 +172,7 @@ int hfi_write_cmd(void *cmd_ptr)
|
|||
* firmware to process
|
||||
*/
|
||||
wmb();
|
||||
cam_io_w_mb((uint32_t)INTR_ENABLE,
|
||||
g_hfi->csr_base + HFI_REG_A5_CSR_HOST2ICPINT);
|
||||
hfi_irq_raise(g_hfi);
|
||||
err:
|
||||
mutex_unlock(&hfi_cmd_q_mutex);
|
||||
return rc;
|
||||
|
|
@ -554,8 +565,7 @@ int cam_hfi_resume(struct hfi_mem_info *hfi_mem, void __iomem *icp_base)
|
|||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
cam_io_w_mb((uint32_t)(INTR_ENABLE|INTR_ENABLE_WD0),
|
||||
icp_base + HFI_REG_A5_CSR_A2HOSTINTEN);
|
||||
hfi_irq_enable(g_hfi);
|
||||
|
||||
fw_version = cam_io_r(icp_base + HFI_REG_FW_VERSION);
|
||||
CAM_DBG(CAM_HFI, "fw version : [%x]", fw_version);
|
||||
|
|
@ -592,8 +602,8 @@ int cam_hfi_resume(struct hfi_mem_info *hfi_mem, void __iomem *icp_base)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
|
||||
void __iomem *icp_base)
|
||||
int cam_hfi_init(struct hfi_mem_info *hfi_mem, struct hfi_ops *hfi_ops,
|
||||
void *priv, uint8_t event_driven_mode, void __iomem *icp_base)
|
||||
{
|
||||
int rc = 0;
|
||||
struct hfi_qtbl *qtbl;
|
||||
|
|
@ -602,6 +612,13 @@ int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
|
|||
uint32_t hw_version, fw_version, status = 0;
|
||||
struct sfr_buf *sfr_buffer;
|
||||
|
||||
if (!hfi_mem || !hfi_ops || !priv) {
|
||||
CAM_ERR(CAM_HFI,
|
||||
"invalid arg: hfi_mem=%pK hfi_ops=%pK priv=%pK",
|
||||
hfi_mem, hfi_ops, priv);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&hfi_cmd_q_mutex);
|
||||
mutex_lock(&hfi_msg_q_mutex);
|
||||
|
||||
|
|
@ -784,8 +801,10 @@ int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
|
|||
g_hfi->hfi_state = HFI_READY;
|
||||
g_hfi->cmd_q_state = true;
|
||||
g_hfi->msg_q_state = true;
|
||||
cam_io_w_mb((uint32_t)(INTR_ENABLE|INTR_ENABLE_WD0),
|
||||
icp_base + HFI_REG_A5_CSR_A2HOSTINTEN);
|
||||
g_hfi->ops = *hfi_ops;
|
||||
g_hfi->priv = priv;
|
||||
|
||||
hfi_irq_enable(g_hfi);
|
||||
|
||||
mutex_unlock(&hfi_cmd_q_mutex);
|
||||
mutex_unlock(&hfi_msg_q_mutex);
|
||||
|
|
|
|||
|
|
@ -485,6 +485,34 @@ irqreturn_t cam_a5_irq(int irq_num, void *data)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
void cam_a5_irq_raise(void *priv)
|
||||
{
|
||||
struct cam_hw_info *a5_info = priv;
|
||||
|
||||
if (!a5_info) {
|
||||
CAM_ERR(CAM_ICP, "invalid A5 device info");
|
||||
return;
|
||||
}
|
||||
|
||||
cam_io_w_mb(A5_HOSTINT,
|
||||
a5_info->soc_info.reg_map[A5_SIERRA_BASE].mem_base +
|
||||
ICP_SIERRA_A5_CSR_HOST2ICPINT);
|
||||
}
|
||||
|
||||
void cam_a5_irq_enable(void *priv)
|
||||
{
|
||||
struct cam_hw_info *a5_info = priv;
|
||||
|
||||
if (!a5_info) {
|
||||
CAM_ERR(CAM_ICP, "invalid A5 device info");
|
||||
return;
|
||||
}
|
||||
|
||||
cam_io_w_mb(A5_WDT_WS0EN | A5_A2HOSTINTEN,
|
||||
a5_info->soc_info.reg_map[A5_SIERRA_BASE].mem_base +
|
||||
ICP_SIERRA_A5_CSR_A2HOSTINTEN);
|
||||
}
|
||||
|
||||
int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
|
||||
void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef CAM_A5_CORE_H
|
||||
|
|
@ -81,6 +81,9 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
|
|||
|
||||
irqreturn_t cam_a5_irq(int irq_num, void *data);
|
||||
|
||||
void cam_a5_irq_raise(void *priv);
|
||||
void cam_a5_irq_enable(void *priv);
|
||||
|
||||
/**
|
||||
* @brief : API to register a5 hw to platform framework.
|
||||
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
|
||||
|
|
|
|||
|
|
@ -23,6 +23,14 @@
|
|||
A5_CSR_WAKE_UP_EN | \
|
||||
A5_CSR_EN_CLKGATE_WFI)
|
||||
|
||||
#define ICP_SIERRA_A5_CSR_A2HOSTINTEN 0x10
|
||||
#define A5_WDT_WS1EN (1 << 2)
|
||||
#define A5_WDT_WS0EN (1 << 1)
|
||||
#define A5_A2HOSTINTEN (1 << 0)
|
||||
|
||||
#define ICP_SIERRA_A5_CSR_HOST2ICPINT 0x30
|
||||
#define A5_HOSTINT (1 << 0)
|
||||
|
||||
#define ICP_SIERRA_A5_CSR_A5_STATUS 0x200
|
||||
#define A5_CSR_A5_STANDBYWFI (1 << 7)
|
||||
|
||||
|
|
|
|||
|
|
@ -3624,6 +3624,7 @@ static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr)
|
|||
struct cam_hw_intf *a5_dev_intf = NULL;
|
||||
struct cam_hw_info *a5_dev = NULL;
|
||||
struct hfi_mem_info hfi_mem;
|
||||
struct hfi_ops hfi_ops;
|
||||
|
||||
a5_dev_intf = hw_mgr->a5_dev_intf;
|
||||
if (!a5_dev_intf) {
|
||||
|
|
@ -3688,8 +3689,11 @@ static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr)
|
|||
hfi_mem.io_mem2.len = 0x0;
|
||||
}
|
||||
|
||||
return cam_hfi_init(0, &hfi_mem,
|
||||
a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
|
||||
hfi_ops.irq_raise = cam_a5_irq_raise;
|
||||
hfi_ops.irq_enable = cam_a5_irq_enable;
|
||||
|
||||
return cam_hfi_init(&hfi_mem, &hfi_ops, a5_dev, 0,
|
||||
a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
|
||||
}
|
||||
|
||||
static int cam_icp_mgr_send_fw_init(struct cam_icp_hw_mgr *hw_mgr)
|
||||
|
|
|
|||
Loading…
Reference in a new issue