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

Commit 6272ed41 authored by Camera Software Integration's avatar Camera Software Integration Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: icp: Adapt HFI to processor specific irq management" into camera-kernel.lnx.4.0

parents 2638d4f3 f42f7b1e
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -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
+4 −15
Original line number Diff line number Diff line
@@ -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_ */
+27 −8
Original line number Diff line number Diff line
@@ -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);
+28 −0
Original line number Diff line number Diff line
@@ -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)
{
+4 −1
Original line number Diff line number Diff line
/* 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.
Loading