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

Commit b8c7c9c8 authored by Sunid Wilson's avatar Sunid Wilson
Browse files

msm: fd: Add register mask to identify the bits to change



Currently we read register address offset and value
from dtsi and only set the bits that are currently
not set in the register. We do not consider the
use case were we would like to unset a register bit.
In order to add this capability we need a register mask
which is used to identify the register bits that we would
like to change.

Change-Id: Ia42613a4d99e31b30de6180f6d22838c682f5313
Signed-off-by: default avatarSunid Wilson <sunidw@codeaurora.org>
parent 7d54fbdb
Loading
Loading
Loading
Loading
+19 −8
Original line number Diff line number Diff line
@@ -41,8 +41,15 @@ Optional properties:
  - ib. Instantaneous bus bandwidth (Bps).
- mmagic-vdd-supply: phandle to GDSC regulator controlling mmagic.
- camss-vdd-supply: phandle to GDSC regulator controlling camss.
- qcom,vbif-reg-settings: relative address offsets and value pairs for
  VBIF registers.
- qcom,fd-core-reg-settings: relative address offsets and value pairs for
  FD CORE registers and bit mask.
  Format: <reg_addr_offset reg_value reg_mask>
- qcom,fd-misc-reg-settings: relative address offsets and value pairs for
  FD MISC registers and bit mask.
  Format: <reg_addr_offset reg_value reg_mask>
- qcom,fd-vbif-reg-settings: relative address offsets and value pairs for
  FD VBIF registers and bit mask.
  Format: <reg_addr_offset reg_value reg_mask>

Example:

@@ -82,7 +89,11 @@ Example:
        qcom,bus-bandwidth-vectors = <13000000 13000000>,
            <45000000 45000000>,
            <90000000 90000000>;
	qcom,vbif-reg-settings = <0x10 0x40004000>,
		<0x18 0x10000000>,
		<0x1c 0x10000000>;
        qcom,fd-vbif-reg-settings = <0x20 0x10000000 0x30000000>,
            <0x24 0x10000000 0x30000000>,
            <0x28 0x10000000 0x30000000>,
            <0x2c 0x10000000 0x30000000>;
        qcom,fd-misc-reg-settings = <0x20 0x2 0x3>,
            <0x24 0x2 0x3>;
        qcom,fd-core-reg-settings = <0x8 0x20 0xffffffff>;
    };
+67 −19
Original line number Diff line number Diff line
@@ -42,6 +42,19 @@
#define MSM_FD_HALT_TIMEOUT_MS 100
/* Smmu callback name */
#define MSM_FD_SMMU_CB_NAME "camera_fd"
/*
 * enum msm_fd_reg_setting_entries - FD register setting entries in DT.
 * @MSM_FD_REG_ADDR_OFFSET_IDX: Register address offset index.
 * @MSM_FD_REG_VALUE_IDX: Register value index.
 * @MSM_FD_REG_MASK_IDX: Regester mask index.
 * @MSM_FD_REG_LAST_IDX: Index count.
 */
enum msm_fd_dt_reg_setting_index {
	MSM_FD_REG_ADDR_OFFSET_IDX,
	MSM_FD_REG_VALUE_IDX,
	MSM_FD_REG_MASK_IDX,
	MSM_FD_REG_LAST_IDX
};

/*
 * msm_fd_hw_read_reg - Fd read from register.
@@ -593,7 +606,7 @@ void msm_fd_hw_release_irq(struct msm_fd_device *fd)
}

/*
 * msm_fd_hw_set_dt_parms() - read device tree params and write to registers.
 * msm_fd_hw_set_dt_parms_by_name() - read DT params and write to registers.
 * @fd: Pointer to fd device.
 * @dt_prop_name: Name of the device tree property to read.
 * @base_idx: Fd memory resource index.
@@ -603,7 +616,7 @@ void msm_fd_hw_release_irq(struct msm_fd_device *fd)
 *
 * Return: 0 on success and negative error on failure.
 */
int32_t msm_fd_hw_set_dt_parms(struct msm_fd_device *fd,
int32_t msm_fd_hw_set_dt_parms_by_name(struct msm_fd_device *fd,
			const char *dt_prop_name,
			enum msm_fd_mem_resources base_idx)
{
@@ -619,11 +632,11 @@ int32_t msm_fd_hw_set_dt_parms(struct msm_fd_device *fd,
		pr_err("%s: Error property does not exist\n", __func__);
		return -ENOENT;
	}
	if (dt_count % 8) {
	if (dt_count % (sizeof(int32_t) * MSM_FD_REG_LAST_IDX)) {
		pr_err("%s: Error invalid entries\n", __func__);
		return -EINVAL;
	}
	dt_count /= 4;
	dt_count /= sizeof(int32_t);
	if (dt_count != 0) {
		dt_reg_settings = kcalloc(dt_count,
			sizeof(uint32_t),
@@ -642,18 +655,59 @@ int32_t msm_fd_hw_set_dt_parms(struct msm_fd_device *fd,
			return -EINVAL;
		}

		for (i = 0; i < dt_count; i = i + 2) {
		for (i = 0; i < dt_count; i = i + MSM_FD_REG_LAST_IDX) {
			msm_fd_hw_reg_clr(fd, base_idx,
				dt_reg_settings[i + MSM_FD_REG_ADDR_OFFSET_IDX],
				dt_reg_settings[i + MSM_FD_REG_MASK_IDX]);
			msm_fd_hw_reg_set(fd, base_idx,
				dt_reg_settings[i + MSM_FD_REG_ADDR_OFFSET_IDX],
				dt_reg_settings[i + MSM_FD_REG_VALUE_IDX] &
				dt_reg_settings[i + MSM_FD_REG_MASK_IDX]);
			pr_debug("%s:%d] %p %08x\n", __func__, __LINE__,
				fd->iomem_base[base_idx] + dt_reg_settings[i],
				dt_reg_settings[i + 1]);
			msm_fd_hw_reg_set(fd, base_idx, dt_reg_settings[i],
				dt_reg_settings[i + 1]);
				fd->iomem_base[base_idx] +
				dt_reg_settings[i + MSM_FD_REG_ADDR_OFFSET_IDX],
				dt_reg_settings[i + MSM_FD_REG_VALUE_IDX] &
				dt_reg_settings[i + MSM_FD_REG_MASK_IDX]);
		}
		kfree(dt_reg_settings);
	}
	return 0;
}

/*
 * msm_fd_hw_set_dt_parms() - set FD device tree configuration.
 * @fd: Pointer to fd device.
 *
 * This function holds an array of device tree property names and calls
 * msm_fd_hw_set_dt_parms_by_name() for each property.
 *
 * Return: 0 on success and negative error on failure.
 */
int msm_fd_hw_set_dt_parms(struct msm_fd_device *fd)
{
	int rc = 0;
	uint8_t dt_prop_cnt = MSM_FD_IOMEM_LAST;
	char *dt_prop_name[MSM_FD_IOMEM_LAST] = {"qcom,fd-core-reg-settings",
		"qcom,fd-misc-reg-settings", "qcom,fd-vbif-reg-settings"};

	while (dt_prop_cnt) {
		dt_prop_cnt--;
		rc = msm_fd_hw_set_dt_parms_by_name(fd,
			dt_prop_name[dt_prop_cnt],
			dt_prop_cnt);
		if (rc == -ENOENT) {
			pr_debug("%s: No %s property\n", __func__,
				dt_prop_name[dt_prop_cnt]);
			rc = 0;
		} else if (rc < 0) {
			pr_err("%s: %s params set fail\n", __func__,
				dt_prop_name[dt_prop_cnt]);
			return rc;
		}
	}
	return rc;
}

/*
 * msm_fd_hw_release_mem_resources - Releases memory resources.
 * @fd: Pointer to fd device.
@@ -1177,15 +1231,9 @@ int msm_fd_hw_get(struct msm_fd_device *fd, unsigned int clock_rate_idx)
		if (msm_fd_hw_misc_irq_supported(fd))
			msm_fd_hw_misc_irq_enable(fd);

		ret = msm_fd_hw_set_dt_parms(fd, "qcom,vbif-reg-settings",
			MSM_FD_IOMEM_VBIF);
		if (ret == -ENOENT) {
			pr_debug("%s: No qcom,vbif-reg-settings property\n",
				__func__);
		} else if (ret < 0) {
			pr_err("%s: vbif params set fail\n", __func__);
			goto error_vbif;
		}
		ret = msm_fd_hw_set_dt_parms(fd);
		if (ret < 0)
			goto error_set_dt;
	}

	fd->ref_count++;
@@ -1193,7 +1241,7 @@ int msm_fd_hw_get(struct msm_fd_device *fd, unsigned int clock_rate_idx)

	return 0;

error_vbif:
error_set_dt:
	if (msm_fd_hw_misc_irq_supported(fd))
		msm_fd_hw_misc_irq_disable(fd);
	msm_fd_hw_disable_clocks(fd);