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

Commit 9f955dac authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: cpas: Implement CPAS HW Errata workarounds"

parents 9a22b945 12ae8509
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -800,8 +800,8 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
			goto done;
		}

		if (cpas_core->internal_ops.power_on_settings) {
			rc = cpas_core->internal_ops.power_on_settings(cpas_hw);
		if (cpas_core->internal_ops.power_on) {
			rc = cpas_core->internal_ops.power_on(cpas_hw);
			if (rc) {
				cam_cpas_soc_disable_resources(
					&cpas_hw->soc_info);
@@ -873,6 +873,15 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args,
	cpas_core->streamon_clients--;

	if (cpas_core->streamon_clients == 0) {
		if (cpas_core->internal_ops.power_off) {
			rc = cpas_core->internal_ops.power_off(cpas_hw);
			if (rc) {
				pr_err("failed in power_off settings rc=%d\n",
					rc);
				/* Do not return error, passthrough */
			}
		}

		rc = cam_cpas_soc_disable_resources(&cpas_hw->soc_info);
		if (rc) {
			pr_err("disable_resorce failed, rc=%d\n", rc);
+4 −2
Original line number Diff line number Diff line
@@ -45,7 +45,8 @@ enum cam_cpas_access_type {
 * @init_hw_version: Function pointer for hw init based on version
 * @handle_irq: Function poniter for irq handling
 * @setup_regbase: Function pointer for setup rebase indices
 * @power_on_settings: Function pointer for hw core specific power on settings
 * @power_on: Function pointer for hw core specific power on settings
 * @power_off: Function pointer for hw core specific power off settings
 *
 */
struct cam_cpas_internal_ops {
@@ -56,7 +57,8 @@ struct cam_cpas_internal_ops {
	irqreturn_t (*handle_irq)(int irq_num, void *data);
	int (*setup_regbase)(struct cam_hw_soc_info *soc_info,
		int32_t regbase_index[], int32_t num_reg_map);
	int (*power_on_settings)(struct cam_hw_info *cpas_hw);
	int (*power_on)(struct cam_hw_info *cpas_hw);
	int (*power_off)(struct cam_hw_info *cpas_hw);
};

/**
+7 −0
Original line number Diff line number Diff line
@@ -29,6 +29,13 @@

#define BITS_MASK_SHIFT(x, mask, shift) (((x) & (mask)) >> shift)

/* Number of times to retry while polling */
#define CAM_CPAS_POLL_RETRY_CNT 5
/* Minimum usecs to sleep while polling */
#define CAM_CPAS_POLL_MIN_USECS 200
/* Maximum usecs to sleep while polling */
#define CAM_CPAS_POLL_MAX_USECS 250

/**
 * enum cam_cpas_hw_type - Enum for CPAS HW type
 */
+2 −1
Original line number Diff line number Diff line
@@ -81,7 +81,8 @@ int cam_camsstop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops)
	internal_ops->init_hw_version = NULL;
	internal_ops->handle_irq = NULL;
	internal_ops->setup_regbase = cam_camsstop_setup_regbase_indices;
	internal_ops->power_on_settings = NULL;
	internal_ops->power_on = NULL;
	internal_ops->power_off = NULL;

	return 0;
}
+35 −2
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ irqreturn_t cam_cpastop_handle_irq(int irq_num, void *data)
	return IRQ_HANDLED;
}

static int cam_cpastop_static_settings(struct cam_hw_info *cpas_hw)
static int cam_cpastop_poweron(struct cam_hw_info *cpas_hw)
{
	int i;

@@ -256,6 +256,38 @@ static int cam_cpastop_static_settings(struct cam_hw_info *cpas_hw)
	return 0;
}

static int cam_cpastop_poweroff(struct cam_hw_info *cpas_hw)
{
	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
	struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info;
	int camnoc_index = cpas_core->regbase_index[CAM_CPAS_REG_CAMNOC];
	int rc = 0;
	struct cam_cpas_hw_errata_wa_list *errata_wa_list =
		camnoc_info->errata_wa_list;

	if (!errata_wa_list)
		return 0;

	if (errata_wa_list->camnoc_flush_slave_pending_trans.enable) {
		struct cam_cpas_hw_errata_wa *errata_wa =
			&errata_wa_list->camnoc_flush_slave_pending_trans;

		rc = cam_io_poll_value_wmask(
			soc_info->reg_map[camnoc_index].mem_base +
			errata_wa->data.reg_info.offset,
			errata_wa->data.reg_info.value,
			errata_wa->data.reg_info.mask,
			CAM_CPAS_POLL_RETRY_CNT,
			CAM_CPAS_POLL_MIN_USECS, CAM_CPAS_POLL_MAX_USECS);
		if (rc) {
			pr_err("camnoc flush slave pending trans failed\n");
			/* Do not return error, passthrough */
		}
	}

	return rc;
}

static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
	struct cam_cpas_hw_caps *hw_caps)
{
@@ -295,7 +327,8 @@ int cam_cpastop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops)
	internal_ops->init_hw_version = cam_cpastop_init_hw_version;
	internal_ops->handle_irq = cam_cpastop_handle_irq;
	internal_ops->setup_regbase = cam_cpastop_setup_regbase_indices;
	internal_ops->power_on_settings = cam_cpastop_static_settings;
	internal_ops->power_on = cam_cpastop_poweron;
	internal_ops->power_off = cam_cpastop_poweroff;

	return 0;
}
Loading