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

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

Merge "msm: camera: icp: Support processor-specific HFI register offsets" into...

Merge "msm: camera: icp: Support processor-specific HFI register offsets" into camera-kernel.lnx.4.0
parents 6b144e04 528d44a3
Loading
Loading
Loading
Loading
+6 −8
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ struct hfi_mem {
 * @qdss: qdss mapped memory for fw
 * @io_mem: io memory info
 * @io_mem2: 2nd io memory info
 * @icp_base: icp base address
 */
struct hfi_mem_info {
	struct hfi_mem qtbl;
@@ -46,17 +45,18 @@ struct hfi_mem_info {
	struct hfi_mem qdss;
	struct hfi_mem io_mem;
	struct hfi_mem io_mem2;
	void __iomem *icp_base;
};

/**
 * struct hfi_ops
 * @irq_raise: called to raise H2ICP interrupt
 * @irq_enable: called to enable interrupts from ICP
 * @iface_addr: called to get interface registers base address
 */
struct hfi_ops {
	void (*irq_raise)(void *data);
	void (*irq_enable)(void *data);
	void __iomem *(*iface_addr)(void *data);
};

/**
@@ -84,12 +84,11 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id, uint32_t *words_read);
 * @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(struct hfi_mem_info *hfi_mem, struct hfi_ops *hfi_ops,
		void *priv, uint8_t event_driven_mode, void *__iomem icp_base);
int cam_hfi_init(struct hfi_mem_info *hfi_mem, const struct hfi_ops *hfi_ops,
		void *priv, uint8_t event_driven_mode);

/**
 * hfi_get_hw_caps() - hardware capabilities from firmware
@@ -110,7 +109,7 @@ void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size);
/**
 * cam_hfi_deinit() - cleanup HFI
 */
void cam_hfi_deinit(void __iomem *icp_base);
void cam_hfi_deinit(void);
/**
 * hfi_set_debug_level() - set debug level
 * @a5_dbg_type: 1 for debug_q & 2 for qdss
@@ -152,11 +151,10 @@ int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg);
/**
 * cam_hfi_resume() - function to resume
 * @hfi_mem: hfi memory info
 * @icp_base: icp base address
 *
 * Returns success(zero)/failure(non zero)
 */
int cam_hfi_resume(struct hfi_mem_info *hfi_mem, void __iomem *icp_base);
int cam_hfi_resume(struct hfi_mem_info *hfi_mem);

/**
 * cam_hfi_queue_dump() - utility function to dump hfi queues
+17 −22
Original line number Diff line number Diff line
@@ -9,27 +9,24 @@
#include <linux/types.h>
#include "hfi_intf.h"

/* start of ICP CSR registers */
#define HFI_REG_A5_HW_VERSION                   0x0
/* general purpose registers */
#define GEN_PURPOSE_REG(n)              (n * 4)

/* general purpose registers from */
#define HFI_REG_FW_VERSION                      0x44
#define HFI_REG_HOST_ICP_INIT_REQUEST           0x48
#define HFI_REG_ICP_HOST_INIT_RESPONSE          0x4C
#define HFI_REG_SHARED_MEM_PTR                  0x50
#define HFI_REG_SHARED_MEM_SIZE                 0x54
#define HFI_REG_QTBL_PTR                        0x58
#define HFI_REG_UNCACHED_HEAP_PTR               0x5C
#define HFI_REG_UNCACHED_HEAP_SIZE              0x60
#define HFI_REG_QDSS_IOVA                       0x6C
#define HFI_REG_SFR_PTR                         0x68
#define HFI_REG_QDSS_IOVA_SIZE                  0x70
#define HFI_REG_IO_REGION_IOVA                  0x74
#define HFI_REG_IO_REGION_SIZE                  0x78
#define HFI_REG_IO2_REGION_IOVA                 0x7C
#define HFI_REG_IO2_REGION_SIZE                 0x80

/* end of ICP CSR registers */
#define HFI_REG_FW_VERSION              GEN_PURPOSE_REG(1)
#define HFI_REG_HOST_ICP_INIT_REQUEST   GEN_PURPOSE_REG(2)
#define HFI_REG_ICP_HOST_INIT_RESPONSE  GEN_PURPOSE_REG(3)
#define HFI_REG_SHARED_MEM_PTR          GEN_PURPOSE_REG(4)
#define HFI_REG_SHARED_MEM_SIZE         GEN_PURPOSE_REG(5)
#define HFI_REG_QTBL_PTR                GEN_PURPOSE_REG(6)
#define HFI_REG_UNCACHED_HEAP_PTR       GEN_PURPOSE_REG(7)
#define HFI_REG_UNCACHED_HEAP_SIZE      GEN_PURPOSE_REG(8)
#define HFI_REG_SFR_PTR                 GEN_PURPOSE_REG(10)
#define HFI_REG_QDSS_IOVA               GEN_PURPOSE_REG(11)
#define HFI_REG_QDSS_IOVA_SIZE          GEN_PURPOSE_REG(12)
#define HFI_REG_IO_REGION_IOVA          GEN_PURPOSE_REG(13)
#define HFI_REG_IO_REGION_SIZE          GEN_PURPOSE_REG(14)
#define HFI_REG_IO2_REGION_IOVA         GEN_PURPOSE_REG(15)
#define HFI_REG_IO2_REGION_SIZE         GEN_PURPOSE_REG(16)

/* start of Queue table and queues */
#define MAX_ICP_HFI_QUEUES                      4
@@ -278,7 +275,6 @@ struct hfi_qtbl {
 * @cmd_q_state: State of command queue
 * @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 {
@@ -292,7 +288,6 @@ struct hfi_info {
	bool cmd_q_state;
	struct mutex msg_q_lock;
	bool msg_q_state;
	void __iomem *csr_base;
	void *priv;
};

+33 −13
Original line number Diff line number Diff line
@@ -51,6 +51,16 @@ static void hfi_irq_enable(struct hfi_info *hfi)
		hfi->ops.irq_enable(hfi->priv);
}

static void __iomem *hfi_iface_addr(struct hfi_info *hfi)
{
	void __iomem *ret = NULL;

	if (hfi->ops.iface_addr)
		ret = hfi->ops.iface_addr(hfi->priv);

	return IS_ERR_OR_NULL(ret) ? NULL : ret;
}

void cam_hfi_queue_dump(void)
{
	struct hfi_qtbl *qtbl;
@@ -550,12 +560,16 @@ int hfi_get_hw_caps(void *query_buf)
	return 0;
}

int cam_hfi_resume(struct hfi_mem_info *hfi_mem, void __iomem *icp_base)
int cam_hfi_resume(struct hfi_mem_info *hfi_mem)
{
	int rc = 0;
	uint32_t fw_version, status = 0;
	void __iomem *icp_base = hfi_iface_addr(g_hfi);

	g_hfi->csr_base = icp_base;
	if (!icp_base) {
		CAM_ERR(CAM_HFI, "invalid HFI interface address");
		return -EINVAL;
	}

	if (readl_poll_timeout(icp_base + HFI_REG_ICP_HOST_INIT_RESPONSE,
			       status, status == ICP_INIT_RESP_SUCCESS,
@@ -602,15 +616,16 @@ int cam_hfi_resume(struct hfi_mem_info *hfi_mem, void __iomem *icp_base)
	return rc;
}

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 cam_hfi_init(struct hfi_mem_info *hfi_mem, const struct hfi_ops *hfi_ops,
		void *priv, uint8_t event_driven_mode)
{
	int rc = 0;
	uint32_t status = 0;
	struct hfi_qtbl *qtbl;
	struct hfi_qtbl_hdr *qtbl_hdr;
	struct hfi_q_hdr *cmd_q_hdr, *msg_q_hdr, *dbg_q_hdr;
	uint32_t hw_version, fw_version, status = 0;
	struct sfr_buf *sfr_buffer;
	void __iomem *icp_base;

	if (!hfi_mem || !hfi_ops || !priv) {
		CAM_ERR(CAM_HFI,
@@ -752,6 +767,16 @@ int cam_hfi_init(struct hfi_mem_info *hfi_mem, struct hfi_ops *hfi_ops,
		break;
	}

	g_hfi->ops = *hfi_ops;
	g_hfi->priv = priv;

	icp_base = hfi_iface_addr(g_hfi);
	if (!icp_base) {
		CAM_ERR(CAM_HFI, "invalid HFI interface address");
		rc = -EINVAL;
		goto regions_fail;
	}

	cam_io_w_mb((uint32_t)hfi_mem->qtbl.iova,
		icp_base + HFI_REG_QTBL_PTR);
	cam_io_w_mb((uint32_t)hfi_mem->sfr_buf.iova,
@@ -792,17 +817,12 @@ int cam_hfi_init(struct hfi_mem_info *hfi_mem, struct hfi_ops *hfi_ops,
		goto regions_fail;
	}

	hw_version = cam_io_r(icp_base + HFI_REG_A5_HW_VERSION);
	fw_version = cam_io_r(icp_base + HFI_REG_FW_VERSION);
	CAM_DBG(CAM_HFI, "hw version : : [%x], fw version : [%x]",
		hw_version, fw_version);
	CAM_DBG(CAM_HFI, "ICP fw version: 0x%x",
		cam_io_r(icp_base + HFI_REG_FW_VERSION));

	g_hfi->csr_base = icp_base;
	g_hfi->hfi_state = HFI_READY;
	g_hfi->cmd_q_state = true;
	g_hfi->msg_q_state = true;
	g_hfi->ops = *hfi_ops;
	g_hfi->priv = priv;

	hfi_irq_enable(g_hfi);

@@ -819,7 +839,7 @@ int cam_hfi_init(struct hfi_mem_info *hfi_mem, struct hfi_ops *hfi_ops,
	return rc;
}

void cam_hfi_deinit(void __iomem *icp_base)
void cam_hfi_deinit(void)
{
	mutex_lock(&hfi_cmd_q_mutex);
	mutex_lock(&hfi_msg_q_mutex);
+17 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@
#define PC_POLL_DELAY_US 100
#define PC_POLL_TIMEOUT_US 10000

#define A5_GEN_PURPOSE_REG_OFFSET 0x40

static int cam_a5_cpas_vote(struct cam_a5_device_core_info *core_info,
	struct cam_icp_cpas_vote *cpas_vote)
{
@@ -513,6 +515,21 @@ void cam_a5_irq_enable(void *priv)
		ICP_SIERRA_A5_CSR_A2HOSTINTEN);
}

void __iomem *cam_a5_iface_addr(void *priv)
{
	struct cam_hw_info *a5_info = priv;
	void __iomem *base;

	if (!a5_info) {
		CAM_ERR(CAM_ICP, "invalid A5 device info");
		return ERR_PTR(-EINVAL);
	}

	base = a5_info->soc_info.reg_map[A5_SIERRA_BASE].mem_base;

	return base + A5_GEN_PURPOSE_REG_OFFSET;
}

int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
	void *cmd_args, uint32_t arg_size)
{
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ irqreturn_t cam_a5_irq(int irq_num, void *data);

void cam_a5_irq_raise(void *priv);
void cam_a5_irq_enable(void *priv);
void __iomem *cam_a5_iface_addr(void *priv);

/**
 * @brief : API to register a5 hw to platform framework.
Loading