Selaa lähdekoodia

msm: camera: cdm: Add support for CDM 2.1

This change adds CDM 2.1 support.

CRs-Fixed: 2682747
Change-Id: I9e0782a5e7d8e22706048469669772c21d883d89
Signed-off-by: Trishansh Bhardwaj <[email protected]>
Trishansh Bhardwaj 5 vuotta sitten
vanhempi
sitoutus
159ea8087f

+ 3 - 0
drivers/cam_cdm/cam_cdm.h

@@ -276,6 +276,7 @@ struct cam_cdm_common_reg_data {
  *                       wait, etc.
  * @core_en:             offset to pause/enable CDM
  * @fe_cfg:              offset to configure CDM fetch engine
+ * @irq_context_status   offset to read back irq context status
  * @bl_fifo_rb:          offset to set BL_FIFO read back
  * @bl_fifo_base_rb:     offset to read back base address on offset set by
  *                       bl_fifo_rb
@@ -319,6 +320,7 @@ struct cam_cdm_common_regs {
 	uint32_t core_cfg;
 	uint32_t core_en;
 	uint32_t fe_cfg;
+	uint32_t irq_context_status;
 	uint32_t bl_fifo_rb;
 	uint32_t bl_fifo_base_rb;
 	uint32_t bl_fifo_len_rb;
@@ -415,6 +417,7 @@ enum cam_cdm_hw_version {
 	CAM_CDM_VERSION_1_1 = 0x10010000,
 	CAM_CDM_VERSION_1_2 = 0x10020000,
 	CAM_CDM_VERSION_2_0 = 0x20000000,
+	CAM_CDM_VERSION_2_1 = 0x20010000,
 	CAM_CDM_VERSION_MAX,
 };
 

+ 2 - 0
drivers/cam_cdm/cam_cdm_core_common.c

@@ -49,6 +49,7 @@ bool cam_cdm_set_cam_hw_version(
 	case CAM_CDM110_VERSION:
 	case CAM_CDM120_VERSION:
 	case CAM_CDM200_VERSION:
+	case CAM_CDM210_VERSION:
 		cam_version->major    = (ver & 0xF0000000);
 		cam_version->minor    = (ver & 0xFFF0000);
 		cam_version->incr     = (ver & 0xFFFF);
@@ -81,6 +82,7 @@ struct cam_cdm_utils_ops *cam_cdm_get_ops(
 		case CAM_CDM110_VERSION:
 		case CAM_CDM120_VERSION:
 		case CAM_CDM200_VERSION:
+		case CAM_CDM210_VERSION:
 			return &CDM170_ops;
 		default:
 			CAM_ERR(CAM_CDM, "CDM Version=%x not supported in util",

+ 1 - 0
drivers/cam_cdm/cam_cdm_core_common.h

@@ -12,6 +12,7 @@
 #define CAM_CDM110_VERSION 0x10010000
 #define CAM_CDM120_VERSION 0x10020000
 #define CAM_CDM200_VERSION 0x20000000
+#define CAM_CDM210_VERSION 0x20010000
 
 #define CAM_CDM_AHB_BURST_LEN_1  (BIT(1) - 1)
 #define CAM_CDM_AHB_BURST_LEN_4  (BIT(2) - 1)

+ 36 - 3
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -22,6 +22,7 @@
 #include "cam_cdm_hw_reg_1_1.h"
 #include "cam_cdm_hw_reg_1_2.h"
 #include "cam_cdm_hw_reg_2_0.h"
+#include "cam_cdm_hw_reg_2_1.h"
 #include "camera_main.h"
 #include "cam_trace.h"
 
@@ -60,6 +61,18 @@ static const struct of_device_id msm_cam_hw_cdm_dt_match[] = {
 		.compatible = CAM_HW_CDM_OPE_NAME_2_0,
 		.data = &cam_cdm_2_0_reg_offset,
 	},
+	{
+		.compatible = CAM_HW_CDM_CPAS_NAME_2_1,
+		.data = &cam_cdm_2_1_reg_offset,
+	},
+	{
+		.compatible = CAM_HW_CDM_OPE_NAME_2_1,
+		.data = &cam_cdm_2_1_reg_offset,
+	},
+	{
+		.compatible = CAM_HW_CDM_IFE_NAME_2_1,
+		.data = &cam_cdm_2_1_reg_offset,
+	},
 };
 
 static enum cam_cdm_id cam_hw_cdm_get_id_by_name(char *name)
@@ -77,14 +90,23 @@ static enum cam_cdm_id cam_hw_cdm_get_id_by_name(char *name)
 			strlen(CAM_HW_CDM_CPAS_NAME_1_2)))
 		return CAM_CDM_CPAS;
 	if (strnstr(name, CAM_HW_CDM_IFE_NAME_1_2,
-			strlen(CAM_HW_CDM_CPAS_NAME_1_2)))
+			strlen(CAM_HW_CDM_IFE_NAME_1_2)))
 		return CAM_CDM_IFE;
 	if (strnstr(name, CAM_HW_CDM_CPAS_NAME_2_0,
 			strlen(CAM_HW_CDM_CPAS_NAME_2_0)))
 		return CAM_CDM_CPAS;
 	if (strnstr(name, CAM_HW_CDM_OPE_NAME_2_0,
-			strlen(CAM_HW_CDM_CPAS_NAME_2_0)))
+			strlen(CAM_HW_CDM_OPE_NAME_2_0)))
 		return CAM_CDM_OPE;
+	if (strnstr(name, CAM_HW_CDM_CPAS_NAME_2_1,
+			strlen(CAM_HW_CDM_CPAS_NAME_2_1)))
+		return CAM_CDM_CPAS;
+	if (strnstr(name, CAM_HW_CDM_OPE_NAME_2_1,
+			strlen(CAM_HW_CDM_OPE_NAME_2_1)))
+		return CAM_CDM_OPE;
+	if (strnstr(name, CAM_HW_CDM_IFE_NAME_2_1,
+			strlen(CAM_HW_CDM_IFE_NAME_2_1)))
+		return CAM_CDM_IFE;
 
 	return CAM_CDM_MAX;
 }
@@ -1248,17 +1270,28 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
 	struct cam_cdm_work_payload *payload[CAM_CDM_BL_FIFO_MAX] = {0};
 	uint32_t user_data = 0;
 	uint32_t irq_status[CAM_CDM_BL_FIFO_MAX] = {0};
+	uint32_t irq_context_summary = 0xF;
 	bool work_status;
 	int i;
 
-	CAM_DBG(CAM_CDM, "Got irq");
+	CAM_DBG(CAM_CDM, "Got irq hw_version 0x%x", cdm_core->hw_version);
 	spin_lock(&cdm_hw->hw_lock);
 	if (cdm_hw->hw_state == CAM_HW_STATE_POWER_DOWN) {
 		CAM_DBG(CAM_CDM, "CDM is in power down state");
 		spin_unlock(&cdm_hw->hw_lock);
 		return IRQ_HANDLED;
 	}
+	if (cdm_core->hw_version >= CAM_CDM_VERSION_2_1) {
+		if (cam_cdm_read_hw_reg(cdm_hw,
+			cdm_core->offsets->cmn_reg->irq_context_status,
+			&irq_context_summary)) {
+			CAM_ERR(CAM_CDM, "Failed to read CDM HW IRQ status");
+		}
+	}
 	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo_irq; i++) {
+		if (!(BIT(i) & irq_context_summary)) {
+			continue;
+		}
 		if (cam_cdm_read_hw_reg(cdm_hw,
 			cdm_core->offsets->irq_reg[i]->irq_status,
 			&irq_status[i])) {

+ 252 - 0
drivers/cam_cdm/cam_cdm_hw_reg_2_1.h

@@ -0,0 +1,252 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#include "cam_cdm.h"
+
+struct cam_cdm_bl_pending_req_reg_params cdm_hw_2_1_bl_pending_req0 = {
+	.rb_offset = 0x6c,
+	.rb_mask = 0x1ff,
+	.rb_num_fifo = 0x2,
+	.rb_next_fifo_shift = 0x10,
+};
+
+struct cam_cdm_bl_pending_req_reg_params cdm_hw_2_1_bl_pending_req1 = {
+	.rb_offset = 0x70,
+	.rb_mask = 0x1ff,
+	.rb_num_fifo = 0x2,
+	.rb_next_fifo_shift = 0x10,
+};
+
+static struct cam_cdm_irq_regs cdm_hw_2_1_irq0 = {
+	.irq_mask = 0x30,
+	.irq_clear = 0x34,
+	.irq_clear_cmd = 0x38,
+	.irq_set = 0x3c,
+	.irq_set_cmd = 0x40,
+	.irq_status = 0x44,
+};
+
+static struct cam_cdm_irq_regs cdm_hw_2_1_irq1 = {
+	.irq_mask = 0x130,
+	.irq_clear = 0x134,
+	.irq_clear_cmd = 0x138,
+	.irq_set = 0x13c,
+	.irq_set_cmd = 0x140,
+	.irq_status = 0x144,
+};
+
+static struct cam_cdm_irq_regs cdm_hw_2_1_irq2 = {
+	.irq_mask = 0x230,
+	.irq_clear = 0x234,
+	.irq_clear_cmd = 0x238,
+	.irq_set = 0x23c,
+	.irq_set_cmd = 0x240,
+	.irq_status = 0x244,
+};
+
+static struct cam_cdm_irq_regs cdm_hw_2_1_irq3 = {
+	.irq_mask = 0x330,
+	.irq_clear = 0x334,
+	.irq_clear_cmd = 0x338,
+	.irq_set = 0x33c,
+	.irq_set_cmd = 0x340,
+	.irq_status = 0x344,
+};
+
+static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo0 = {
+	.bl_fifo_base = 0x50,
+	.bl_fifo_len = 0x54,
+	.bl_fifo_store = 0x58,
+	.bl_fifo_cfg = 0x5c,
+};
+
+static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo1 = {
+	.bl_fifo_base = 0x150,
+	.bl_fifo_len = 0x154,
+	.bl_fifo_store = 0x158,
+	.bl_fifo_cfg = 0x15c,
+};
+
+static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo2 = {
+	.bl_fifo_base = 0x250,
+	.bl_fifo_len = 0x254,
+	.bl_fifo_store = 0x258,
+	.bl_fifo_cfg = 0x25c,
+};
+
+static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo3 = {
+	.bl_fifo_base = 0x350,
+	.bl_fifo_len = 0x354,
+	.bl_fifo_store = 0x358,
+	.bl_fifo_cfg = 0x35c,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg0 = {
+	.scratch_reg = 0x90,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg1 = {
+	.scratch_reg = 0x94,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg2 = {
+	.scratch_reg = 0x98,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg3 = {
+	.scratch_reg = 0x9c,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg4 = {
+	.scratch_reg = 0xa0,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg5 = {
+	.scratch_reg = 0xa4,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg6 = {
+	.scratch_reg = 0xa8,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg7 = {
+	.scratch_reg = 0xac,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg8 = {
+	.scratch_reg = 0xb0,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg9 = {
+	.scratch_reg = 0xb4,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg10  = {
+	.scratch_reg = 0xb8,
+};
+
+static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg11  = {
+	.scratch_reg = 0xbc,
+};
+
+static struct cam_cdm_perf_mon_regs cdm_2_1_perf_mon0 = {
+	.perf_mon_ctrl = 0x110,
+	.perf_mon_0 = 0x114,
+	.perf_mon_1 = 0x118,
+	.perf_mon_2 = 0x11c,
+};
+
+static struct cam_cdm_perf_mon_regs cdm_2_1_perf_mon1 = {
+	.perf_mon_ctrl = 0x120,
+	.perf_mon_0 = 0x124,
+	.perf_mon_1 = 0x128,
+	.perf_mon_2 = 0x12c,
+};
+
+static struct cam_cdm_comp_wait_status cdm_2_1_comp_wait_status0 = {
+	.comp_wait_status = 0x88,
+};
+
+static struct cam_cdm_comp_wait_status cdm_2_1_comp_wait_status1 = {
+	.comp_wait_status = 0x8c,
+};
+
+static struct cam_cdm_icl_data_regs cdm_2_1_icl_data = {
+	.icl_last_data_0 = 0x1c0,
+	.icl_last_data_1 = 0x1c4,
+	.icl_last_data_2 = 0x1c8,
+	.icl_inv_data = 0x1cc,
+};
+
+static struct cam_cdm_icl_misc_regs cdm_2_1_icl_misc = {
+	.icl_inv_bl_addr = 0x1d0,
+	.icl_status = 0x1d8,
+};
+
+static struct cam_cdm_icl_regs cdm_2_1_icl = {
+	.data_regs = &cdm_2_1_icl_data,
+	.misc_regs = &cdm_2_1_icl_misc,
+};
+
+static struct cam_cdm_common_regs cdm_hw_2_1_cmn_reg_offset = {
+	.cdm_hw_version = 0x0,
+	.cam_version = NULL,
+	.rst_cmd = 0x10,
+	.cgc_cfg = 0x14,
+	.core_cfg = 0x18,
+	.core_en = 0x1c,
+	.fe_cfg = 0x20,
+	.irq_context_status = 0x2c,
+	.bl_fifo_rb = 0x60,
+	.bl_fifo_base_rb = 0x64,
+	.bl_fifo_len_rb = 0x68,
+	.usr_data = 0x80,
+	.wait_status = 0x84,
+	.last_ahb_addr = 0xd0,
+	.last_ahb_data = 0xd4,
+	.core_debug = 0xd8,
+	.last_ahb_err_addr = 0xe0,
+	.last_ahb_err_data = 0xe4,
+	.current_bl_base = 0xe8,
+	.current_bl_len = 0xec,
+	.current_used_ahb_base = 0xf0,
+	.debug_status = 0xf4,
+	.bus_misr_cfg0 = 0x100,
+	.bus_misr_cfg1 = 0x104,
+	.bus_misr_rd_val = 0x108,
+	.pending_req = {
+			&cdm_hw_2_1_bl_pending_req0,
+			&cdm_hw_2_1_bl_pending_req1,
+		},
+	.comp_wait = {
+			&cdm_2_1_comp_wait_status0,
+			&cdm_2_1_comp_wait_status1,
+		},
+	.perf_mon = {
+			&cdm_2_1_perf_mon0,
+			&cdm_2_1_perf_mon1,
+		},
+	.scratch = {
+			&cdm_2_1_scratch_reg0,
+			&cdm_2_1_scratch_reg1,
+			&cdm_2_1_scratch_reg2,
+			&cdm_2_1_scratch_reg3,
+			&cdm_2_1_scratch_reg4,
+			&cdm_2_1_scratch_reg5,
+			&cdm_2_1_scratch_reg6,
+			&cdm_2_1_scratch_reg7,
+			&cdm_2_1_scratch_reg8,
+			&cdm_2_1_scratch_reg9,
+			&cdm_2_1_scratch_reg10,
+			&cdm_2_1_scratch_reg11,
+		},
+	.perf_reg = NULL,
+	.icl_reg = &cdm_2_1_icl,
+	.spare = 0x3fc,
+};
+
+static struct cam_cdm_common_reg_data cdm_hw_2_1_cmn_reg_data = {
+	.num_bl_fifo = 0x4,
+	.num_bl_fifo_irq = 0x4,
+	.num_bl_pending_req_reg = 0x2,
+	.num_scratch_reg = 0xc,
+};
+
+struct cam_cdm_hw_reg_offset cam_cdm_2_1_reg_offset = {
+	.cmn_reg = &cdm_hw_2_1_cmn_reg_offset,
+	.bl_fifo_reg = {
+			&cdm_hw_2_1_bl_fifo0,
+			&cdm_hw_2_1_bl_fifo1,
+			&cdm_hw_2_1_bl_fifo2,
+			&cdm_hw_2_1_bl_fifo3,
+		},
+	.irq_reg = {
+			&cdm_hw_2_1_irq0,
+			&cdm_hw_2_1_irq1,
+			&cdm_hw_2_1_irq2,
+			&cdm_hw_2_1_irq3,
+		},
+	.reg_data = &cdm_hw_2_1_cmn_reg_data,
+};

+ 3 - 0
drivers/cam_cdm/cam_cdm_soc.h

@@ -13,6 +13,9 @@
 #define CAM_HW_CDM_IFE_NAME_1_2  "qcom,cam-ife-cdm1_2"
 #define CAM_HW_CDM_CPAS_NAME_2_0 "qcom,cam-cpas-cdm2_0"
 #define CAM_HW_CDM_OPE_NAME_2_0  "qcom,cam-ope-cdm2_0"
+#define CAM_HW_CDM_CPAS_NAME_2_1 "qcom,cam-cpas-cdm2_1"
+#define CAM_HW_CDM_OPE_NAME_2_1  "qcom,cam-ope-cdm2_1"
+#define CAM_HW_CDM_IFE_NAME_2_1  "qcom,cam-ife-cdm2_1"
 
 int cam_hw_cdm_soc_get_dt_properties(struct cam_hw_info *cdm_hw,
 	const struct of_device_id *table);