Jelajahi Sumber

video: driver: Add diwali SKU's

Add support for diwali AA/AB(v1) & AC(v2) SKU.

Change-Id: I8afdf0529016e9cdbe72da8e57d7f35194cf9026
Signed-off-by: Priyanka Gujjula <[email protected]>
Priyanka Gujjula 3 tahun lalu
induk
melakukan
f352311f44

+ 112 - 6
driver/platform/diwali/src/msm_vidc_diwali.c

@@ -5,6 +5,7 @@
  */
 
 #include <linux/of.h>
+#include <linux/io.h>
 
 #include "msm_vidc_diwali.h"
 #include "msm_vidc_platform.h"
@@ -45,6 +46,15 @@
 	.bank_spreading = bsp,	\
 }
 
+#define EFUSE_ENTRY(sa, s, m, sh, p) \
+{	\
+	.start_address = sa,		\
+	.size = s,	\
+	.mask = m,	\
+	.shift = sh,	\
+	.purpose = p	\
+}
+
 #define DDR_TYPE_LPDDR4 0x6
 #define DDR_TYPE_LPDDR4X 0x7
 #define DDR_TYPE_LPDDR5 0x8
@@ -58,7 +68,7 @@
 #define HEIC    MSM_VIDC_HEIC
 #define CODECS_ALL     (H264 | HEVC | VP9 | HEIC)
 
-static struct msm_platform_core_capability core_data_diwali[] = {
+static struct msm_platform_core_capability core_data_diwali_v0[] = {
 	/* {type, value} */
 	{ENC_CODECS, H264|HEVC|HEIC},
 	{DEC_CODECS, H264|HEVC|VP9|HEIC},
@@ -108,7 +118,13 @@ static struct msm_platform_core_capability core_data_diwali[] = {
 	{ENC_AUTO_FRAMERATE, 1},
 };
 
-static struct msm_platform_inst_capability instance_data_diwali[] = {
+static struct msm_platform_core_capability core_data_diwali_v1[] = {
+};
+
+static struct msm_platform_core_capability core_data_diwali_v2[] = {
+};
+
+static struct msm_platform_inst_capability instance_data_diwali_v0[] = {
 	/* {cap, domain, codec,
 	 *      min, max, step_or_mask, value,
 	 *      v4l2_id,
@@ -1601,6 +1617,12 @@ static struct msm_platform_inst_capability instance_data_diwali[] = {
 		V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY},
 };
 
+static struct msm_platform_inst_capability instance_data_diwali_v1[] = {
+};
+
+static struct msm_platform_inst_capability instance_data_diwali_v2[] = {
+};
+
 /*
  * Custom conversion coefficients for resolution: 176x144 negative
  * coeffs are converted to s4.9 format
@@ -1632,18 +1654,77 @@ static u32 bus_bw_nrt[] = {
 	11000000,
 };
 
+static struct msm_vidc_efuse_data efuse_data_diwali[] = {
+	/* IRIS_4K60_FMAX_LIMIT_EFUSE - max 4K@60 */
+	EFUSE_ENTRY(0x221C0274, 4, 0x8000000000, 0x27, SKU_VERSION),
+	/* IRIS_MULTIPIPE_DISABLE - max 4K@30 */
+	EFUSE_ENTRY(0x221C0270, 4, 0x0000000080, 0x06, SKU_VERSION),
+};
+
 static struct msm_vidc_platform_data diwali_data = {
-	.core_data = core_data_diwali,
-	.core_data_size = ARRAY_SIZE(core_data_diwali),
-	.instance_data = instance_data_diwali,
-	.instance_data_size = ARRAY_SIZE(instance_data_diwali),
+	.core_data = core_data_diwali_v0,
+	.core_data_size = ARRAY_SIZE(core_data_diwali_v0),
+	.instance_data = instance_data_diwali_v0,
+	.instance_data_size = ARRAY_SIZE(instance_data_diwali_v0),
 	.csc_data.vpe_csc_custom_bias_coeff = vpe_csc_custom_bias_coeff,
 	.csc_data.vpe_csc_custom_matrix_coeff = vpe_csc_custom_matrix_coeff,
 	.csc_data.vpe_csc_custom_limit_coeff = vpe_csc_custom_limit_coeff,
 	.ubwc_config = ubwc_config_diwali,
 	.bus_bw_nrt = bus_bw_nrt,
+	.efuse_data = efuse_data_diwali,
+	.efuse_data_size = ARRAY_SIZE(efuse_data_diwali),
+	.sku_version = 0,
 };
 
+static int msm_vidc_read_efuse(struct msm_vidc_core *core)
+{
+	int rc = 0;
+	void __iomem *base;
+	u32 i = 0, efuse = 0, efuse_data_count = 0;
+	struct msm_vidc_efuse_data *efuse_data = NULL;
+	struct msm_vidc_platform_data *platform_data;
+
+	if (!core || !core->platform || !core->pdev) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	platform_data = &core->platform->data;
+	efuse_data = platform_data->efuse_data;
+	efuse_data_count = platform_data->efuse_data_size;
+
+	if (!efuse_data)
+		return 0;
+
+	for (i = 0; i < efuse_data_count; i++) {
+		switch ((efuse_data[i]).purpose) {
+		case SKU_VERSION:
+			base = devm_ioremap(&core->pdev->dev, (efuse_data[i]).start_address,
+					(efuse_data[i]).size);
+			if (!base) {
+				d_vpr_e("failed efuse: start %#x, size %d\n",
+					(efuse_data[i]).start_address,
+					(efuse_data[i]).size);
+				return -EINVAL;
+			} else {
+				efuse = readl_relaxed(base);
+				platform_data->sku_version =
+						(efuse & (efuse_data[i]).mask) >>
+						(efuse_data[i]).shift;
+			}
+			break;
+		default:
+			break;
+		}
+		if (platform_data->sku_version) {
+			d_vpr_h("efuse 0x%x, platform version 0x%x\n",
+				efuse, platform_data->sku_version);
+			break;
+		}
+	}
+	return rc;
+}
+
 static void msm_vidc_ddr_ubwc_config(
 	struct msm_vidc_platform_data *platform_data, u32 hbb_override_val)
 {
@@ -1667,6 +1748,7 @@ static void msm_vidc_ddr_ubwc_config(
 static int msm_vidc_init_data(struct msm_vidc_core *core)
 {
 	int rc = 0;
+	struct msm_vidc_platform_data *platform_data = NULL;
 
 	if (!core || !core->platform) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -1675,6 +1757,30 @@ static int msm_vidc_init_data(struct msm_vidc_core *core)
 	d_vpr_h("%s: initialize diwali data\n", __func__);
 
 	core->platform->data = diwali_data;
+	platform_data = &core->platform->data;
+
+	/* Check for sku version */
+	rc = msm_vidc_read_efuse(core);
+	if (rc) {
+		d_vpr_e("%s: Failed to read efuse\n", __func__);
+		return rc;
+	}
+
+	if (platform_data->sku_version == SKU_VERSION_1) {
+		platform_data->core_data = core_data_diwali_v1;
+		platform_data->core_data_size =
+				ARRAY_SIZE(core_data_diwali_v1);
+		platform_data->instance_data = instance_data_diwali_v1;
+		platform_data->instance_data_size =
+				ARRAY_SIZE(instance_data_diwali_v1);
+	} else if (platform_data->sku_version == SKU_VERSION_2) {
+		platform_data->core_data = core_data_diwali_v2;
+		platform_data->core_data_size =
+				ARRAY_SIZE(core_data_diwali_v2);
+		platform_data->instance_data = instance_data_diwali_v2;
+		platform_data->instance_data_size =
+				ARRAY_SIZE(instance_data_diwali_v2);
+	}
 
 	/* Check for DDR variant */
 	msm_vidc_ddr_ubwc_config(&core->platform->data, 0xe);

+ 0 - 1
driver/vidc/inc/msm_vidc_dt.h

@@ -203,7 +203,6 @@ struct msm_vidc_dt {
 	phys_addr_t register_base;
 	u32 register_size;
 	u32 irq;
-	u32 sku_version;
 	struct allowed_clock_rates_table *allowed_clks_tbl;
 	u32 allowed_clks_tbl_size;
 	struct clock_freq_table clock_freq_tbl;

+ 4 - 1
driver/vidc/inc/msm_vidc_platform.h

@@ -44,7 +44,7 @@ struct msm_vidc_csc_coeff {
 struct msm_vidc_efuse_data {
 	u32 start_address;
 	u32 size;
-	u32 mask;
+	unsigned long mask;
 	u32 shift;
 	enum efuse_purpose purpose;
 };
@@ -69,6 +69,9 @@ struct msm_vidc_platform_data {
 	struct msm_vidc_csc_coeff csc_data;
 	struct msm_vidc_ubwc_config_data *ubwc_config;
 	u32 *bus_bw_nrt;
+	struct msm_vidc_efuse_data *efuse_data;
+	unsigned int efuse_data_size;
+	unsigned int sku_version;
 };
 
 struct msm_vidc_platform {

+ 0 - 20
driver/vidc/src/msm_vidc_dt.c

@@ -671,22 +671,6 @@ static int msm_vidc_load_reset_table(struct msm_vidc_core *core)
 	return 0;
 }
 
-static int msm_decide_dt_node(struct msm_vidc_core *core)
-{
-	int rc = 0;
-	struct platform_device *pdev = core->pdev;
-	u32 sku_index = 0;
-
-	rc = of_property_read_u32(pdev->dev.of_node, "sku-index",
-			&sku_index);
-	if (rc) {
-		d_vpr_h("'sku_index' not found in node\n");
-		return 0;
-	}
-
-	return 0;
-}
-
 static int msm_vidc_read_resources_from_dt(struct platform_device *pdev)
 {
 	int rc = 0;
@@ -707,10 +691,6 @@ static int msm_vidc_read_resources_from_dt(struct platform_device *pdev)
 	}
 	dt = core->dt;
 
-	rc = msm_decide_dt_node(core);
-	if (rc)
-		return rc;
-
 	INIT_LIST_HEAD(&dt->context_banks);
 
 	kres = platform_get_resource(pdev, IORESOURCE_MEM, 0);