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

Commit ce0b1821 authored by Karthik Anantha Ram's avatar Karthik Anantha Ram
Browse files

msm: camera: icp: Add new ubwc support for ipe/bps



Add support to pick the ubwc fetch/write values based
on the ddr device type for ipe & bps.

Change-Id: I39c2030add3312ba0cb4ef4b5d6638ed54b2d54a
Signed-off-by: default avatarKarthik Anantha Ram <kartanan@codeaurora.org>
parent f597e868
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 */

#ifndef _HFI_INTF_H_
@@ -131,8 +131,17 @@ int hfi_set_fw_dump_level(uint32_t lvl);
 */
int hfi_enable_ipe_bps_pc(bool enable, uint32_t core_info);

/**
 * hfi_cmd_ubwc_config_ext() - UBWC configuration to firmware
 * @ubwc_ipe_cfg: UBWC ipe fetch/write configuration params
 * @ubwc_bps_cfg: UBWC bps fetch/write configuration params
 */
int hfi_cmd_ubwc_config_ext(uint32_t *ubwc_ipe_cfg,
	uint32_t *ubwc_bps_cfg);

/**
 * hfi_cmd_ubwc_config() - UBWC configuration to firmware
 *                         for older targets
 * @ubwc_cfg: UBWC configuration parameters
 */
int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg);
+20 −8
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *  Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 */

#ifndef _HFI_DEFS_H_
@@ -154,6 +154,7 @@
#define HFI_PROP_SYS_SUPPORTED           (HFI_PROPERTY_ICP_COMMON_START + 0x4)
#define HFI_PROP_SYS_IPEBPS_PC           (HFI_PROPERTY_ICP_COMMON_START + 0x5)
#define HFI_PROP_SYS_FW_DUMP_CFG         (HFI_PROPERTY_ICP_COMMON_START + 0x8)
#define HFI_PROPERTY_SYS_UBWC_CONFIG_EX  (HFI_PROPERTY_ICP_COMMON_START + 0x9)

/* Capabilities reported at sys init */
#define HFI_CAPS_PLACEHOLDER_1         (HFI_COMMON_BASE + 0x1)
@@ -274,7 +275,18 @@ struct hfi_ipe_bps_pc {
struct hfi_cmd_ubwc_cfg {
	uint32_t ubwc_fetch_cfg;
	uint32_t ubwc_write_cfg;
};
} __packed;

/**
 * struct hfi_cmd_ubwc_cfg_ext
 * Payload structure to configure HFI_UBWC_CFG_TYPE_EXT
 * @bps: UBWC configuration for bps
 * @ipe: UBWC configuration for ipe
 */
struct hfi_cmd_ubwc_cfg_ext {
	struct hfi_cmd_ubwc_cfg bps;
	struct hfi_cmd_ubwc_cfg ipe;
} __packed;

/**
 * struct hfi_cmd_sys_init
+41 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/io.h>
@@ -280,6 +280,10 @@ int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg)
	size = sizeof(struct hfi_cmd_prop) +
		sizeof(struct hfi_cmd_ubwc_cfg);

	CAM_DBG(CAM_HFI,
		"size of ubwc %u, ubwc_cfg [rd-0x%x,wr-0x%x]",
		size, ubwc_cfg[0],  ubwc_cfg[1]);

	prop = kzalloc(size, GFP_KERNEL);
	if (!prop)
		return -ENOMEM;
@@ -298,6 +302,42 @@ int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg)
	return 0;
}

int hfi_cmd_ubwc_config_ext(uint32_t *ubwc_ipe_cfg,
	uint32_t *ubwc_bps_cfg)
{
	uint8_t *prop;
	struct hfi_cmd_prop *dbg_prop;
	uint32_t size = 0;

	size = sizeof(struct hfi_cmd_prop) +
		sizeof(struct hfi_cmd_ubwc_cfg_ext);

	CAM_DBG(CAM_HFI,
		"size of ubwc %u, ubwc_ipe_cfg[rd-0x%x,wr-0x%x] ubwc_bps_cfg[rd-0x%x,wr-0x%x]",
		size, ubwc_ipe_cfg[0], ubwc_ipe_cfg[1],
		ubwc_bps_cfg[0], ubwc_bps_cfg[1]);

	prop = kzalloc(size, GFP_KERNEL);
	if (!prop)
		return -ENOMEM;

	dbg_prop = (struct hfi_cmd_prop *)prop;
	dbg_prop->size = size;
	dbg_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
	dbg_prop->num_prop = 1;
	dbg_prop->prop_data[0] = HFI_PROPERTY_SYS_UBWC_CONFIG_EX;
	dbg_prop->prop_data[1] = ubwc_bps_cfg[0];
	dbg_prop->prop_data[2] = ubwc_bps_cfg[1];
	dbg_prop->prop_data[3] = ubwc_ipe_cfg[0];
	dbg_prop->prop_data[4] = ubwc_ipe_cfg[1];

	hfi_write_cmd(prop);
	kfree(prop);

	return 0;
}


int hfi_enable_ipe_bps_pc(bool enable, uint32_t core_info)
{
	uint8_t *prop;
+29 −3
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/slab.h>
@@ -365,6 +365,9 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
	struct cam_a5_device_hw_info *hw_info = NULL;
	struct a5_soc_info *a5_soc = NULL;
	unsigned long flags;
	uint32_t ubwc_ipe_cfg[ICP_UBWC_MAX] = {0};
	uint32_t ubwc_bps_cfg[ICP_UBWC_MAX] = {0};
	uint32_t index = 0;
	int rc = 0;

	if (!device_priv) {
@@ -460,14 +463,37 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
			core_info->cpas_start = false;
		}
		break;
	case CAM_ICP_A5_CMD_UBWC_CFG:
	case CAM_ICP_A5_CMD_UBWC_CFG: {
		struct a5_ubwc_cfg_ext *ubwc_cfg_ext = NULL;

		a5_soc = soc_info->soc_private;
		if (!a5_soc) {
			CAM_ERR(CAM_ICP, "A5 private soc info is NULL");
			return -EINVAL;
		}
		rc = hfi_cmd_ubwc_config(a5_soc->ubwc_cfg);

		if (a5_soc->ubwc_config_ext) {
			/* Invoke kernel API to determine DDR type */
			if (of_fdt_get_ddrtype() == DDR_TYPE_LPDDR5)
				index = 1;

			ubwc_cfg_ext = &a5_soc->uconfig.ubwc_cfg_ext;
			ubwc_ipe_cfg[0] =
				ubwc_cfg_ext->ubwc_ipe_fetch_cfg[index];
			ubwc_ipe_cfg[1] =
				ubwc_cfg_ext->ubwc_ipe_write_cfg[index];
			ubwc_bps_cfg[0] =
				ubwc_cfg_ext->ubwc_bps_fetch_cfg[index];
			ubwc_bps_cfg[1] =
				ubwc_cfg_ext->ubwc_bps_write_cfg[index];
			rc = hfi_cmd_ubwc_config_ext(&ubwc_ipe_cfg[0],
					&ubwc_bps_cfg[0]);
		} else {
			rc = hfi_cmd_ubwc_config(a5_soc->uconfig.ubwc_cfg);
		}

		break;
	}
	default:
		break;
	}
+85 −6
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/io.h>
@@ -17,9 +17,10 @@ static int cam_a5_get_dt_properties(struct cam_hw_soc_info *soc_info)
{
	int rc = 0, i;
	const char *fw_name;
	struct a5_soc_info *camp_a5_soc_info;
	struct a5_soc_info *a5_soc_info;
	struct device_node *of_node = NULL;
	struct platform_device *pdev = NULL;
	struct a5_ubwc_cfg_ext *ubwc_cfg_ext = NULL;
	int num_ubwc_cfg;

	pdev = soc_info->pdev;
@@ -31,8 +32,8 @@ static int cam_a5_get_dt_properties(struct cam_hw_soc_info *soc_info)
		return rc;
	}

	camp_a5_soc_info = soc_info->soc_private;
	fw_name = camp_a5_soc_info->fw_name;
	a5_soc_info = soc_info->soc_private;
	fw_name = a5_soc_info->fw_name;

	rc = of_property_read_string(of_node, "fw_name", &fw_name);
	if (rc < 0) {
@@ -40,6 +41,84 @@ static int cam_a5_get_dt_properties(struct cam_hw_soc_info *soc_info)
		goto end;
	}

	ubwc_cfg_ext = &a5_soc_info->uconfig.ubwc_cfg_ext;
	num_ubwc_cfg = of_property_count_u32_elems(of_node,
		"ubwc-ipe-fetch-cfg");
	if ((num_ubwc_cfg < 0) || (num_ubwc_cfg > ICP_UBWC_MAX)) {
		CAM_DBG(CAM_ICP, "wrong ubwc_ipe_fetch_cfg: %d", num_ubwc_cfg);
		rc = num_ubwc_cfg;
		goto ubwc_ex_cfg;
	}

	for (i = 0; i < num_ubwc_cfg; i++) {
		rc = of_property_read_u32_index(of_node, "ubwc-ipe-fetch-cfg",
			i, &ubwc_cfg_ext->ubwc_ipe_fetch_cfg[i]);
		if (rc < 0) {
			CAM_ERR(CAM_ICP,
				"unable to read ubwc_ipe_fetch_cfg values");
			goto end;
		}
	}

	num_ubwc_cfg = of_property_count_u32_elems(of_node,
		"ubwc-ipe-write-cfg");
	if ((num_ubwc_cfg < 0) || (num_ubwc_cfg > ICP_UBWC_MAX)) {
		CAM_ERR(CAM_ICP, "wrong ubwc_ipe_write_cfg: %d", num_ubwc_cfg);
		rc = num_ubwc_cfg;
		goto end;
	}

	for (i = 0; i < num_ubwc_cfg; i++) {
		rc = of_property_read_u32_index(of_node, "ubwc-ipe-write-cfg",
				i, &ubwc_cfg_ext->ubwc_ipe_write_cfg[i]);
		if (rc < 0) {
			CAM_ERR(CAM_ICP,
				"unable to read ubwc_ipe_write_cfg values");
			goto end;
		}
	}

	num_ubwc_cfg = of_property_count_u32_elems(of_node,
		"ubwc-bps-fetch-cfg");
	if ((num_ubwc_cfg < 0) || (num_ubwc_cfg > ICP_UBWC_MAX)) {
		CAM_ERR(CAM_ICP, "wrong ubwc_bps_fetch_cfg: %d", num_ubwc_cfg);
		rc = num_ubwc_cfg;
		goto end;
	}

	for (i = 0; i < num_ubwc_cfg; i++) {
		rc = of_property_read_u32_index(of_node, "ubwc-bps-fetch-cfg",
			i, &ubwc_cfg_ext->ubwc_bps_fetch_cfg[i]);
		if (rc < 0) {
			CAM_ERR(CAM_ICP,
				"unable to read ubwc_bps_fetch_cfg values");
			goto end;
		}
	}

	num_ubwc_cfg = of_property_count_u32_elems(of_node,
		"ubwc-bps-write-cfg");
	if ((num_ubwc_cfg < 0) || (num_ubwc_cfg > ICP_UBWC_MAX)) {
		CAM_ERR(CAM_ICP, "wrong ubwc_bps_write_cfg: %d", num_ubwc_cfg);
		rc = num_ubwc_cfg;
		goto end;
	}

	for (i = 0; i < num_ubwc_cfg; i++) {
		rc = of_property_read_u32_index(of_node, "ubwc-bps-write-cfg",
			i, &ubwc_cfg_ext->ubwc_bps_write_cfg[i]);
		if (rc < 0) {
			CAM_ERR(CAM_ICP,
				"unable to read ubwc_bps_write_cfg values");
			goto end;
		}
	}

	a5_soc_info->ubwc_config_ext = true;
	CAM_DBG(CAM_ICP, "read ubwc_cfg_ext for ipe/bps");
	return rc;

ubwc_ex_cfg:
	num_ubwc_cfg = of_property_count_u32_elems(of_node, "ubwc-cfg");
	if ((num_ubwc_cfg < 0) || (num_ubwc_cfg > ICP_UBWC_MAX)) {
		CAM_ERR(CAM_ICP, "wrong ubwc_cfg: %d", num_ubwc_cfg);
@@ -49,9 +128,9 @@ static int cam_a5_get_dt_properties(struct cam_hw_soc_info *soc_info)

	for (i = 0; i < num_ubwc_cfg; i++) {
		rc = of_property_read_u32_index(of_node, "ubwc-cfg",
			i, &camp_a5_soc_info->ubwc_cfg[i]);
			i, &a5_soc_info->uconfig.ubwc_cfg[i]);
		if (rc < 0) {
			CAM_ERR(CAM_ICP, "unable to read ubwc cfg values");
			CAM_ERR(CAM_ICP, "unable to read ubwc_cfg values");
			break;
		}
	}
Loading