static int tz_start(struct devfreq *devfreq)
{
	struct devfreq_msm_adreno_tz_data *priv;
	unsigned int tz_pwrlevels[MSM_ADRENO_MAX_PWRLEVELS + 1];
	int i, out, ret;

	if (devfreq->data == NULL) {
		pr_err(TAG "data is required for this governor\n");
		return -EINVAL;
	}

	priv = devfreq->data;
	priv->nb.notifier_call = tz_notify;

	out = 1;
	if (devfreq->profile->max_state < MSM_ADRENO_MAX_PWRLEVELS) {
		for (i = 0; i < devfreq->profile->max_state; i++)
			tz_pwrlevels[out++] = devfreq->profile->freq_table[i];
		tz_pwrlevels[0] = i;
	} else {
		pr_err(TAG "tz_pwrlevels[] is too short\n");
		return -EINVAL;
	}

	ret = scm_call(SCM_SVC_DCVS, TZ_INIT_ID, tz_pwrlevels,
			sizeof(tz_pwrlevels), NULL, 0);

	if (ret != 0)
		pr_err(TAG "tz_init failed\n");

	return kgsl_devfreq_add_notifier(devfreq->dev.parent, &priv->nb);
}
static int tz_start(struct devfreq *devfreq)
{
	struct devfreq_msm_adreno_tz_data *priv;
	unsigned int tz_pwrlevels[MSM_ADRENO_MAX_PWRLEVELS + 1];
	unsigned int t1, t2 = 2 * HIST;
	int i, out, ret;

	struct msm_adreno_extended_profile *ext_profile = container_of(
					(devfreq->profile),
					struct msm_adreno_extended_profile,
					profile);

	/*
	 * Assuming that we have only one instance of the adreno device
	 * connected to this governor,
	 * can safely restore the pointer to the governor private data
	 * from the container of the device profile
	 */
	devfreq->data = ext_profile->private_data;

	priv = devfreq->data;
	priv->nb.notifier_call = tz_notify;

	out = 1;
	if (devfreq->profile->max_state < MSM_ADRENO_MAX_PWRLEVELS) {
		for (i = 0; i < devfreq->profile->max_state; i++)
			tz_pwrlevels[out++] = devfreq->profile->freq_table[i];
		tz_pwrlevels[0] = i;
	} else {
		pr_err(TAG "tz_pwrlevels[] is too short\n");
		return -EINVAL;
	}

	ret = scm_call(SCM_SVC_DCVS, TZ_INIT_ID, tz_pwrlevels,
			sizeof(tz_pwrlevels), NULL, 0);

	if (ret != 0)
		pr_err(TAG "tz_init failed\n");

	/* Set up the cut-over percentages for the bus calculation. */
	if (priv->bus.num) {
		for (i = 0; i < priv->bus.num; i++) {
			t1 = (u32)(100 * priv->bus.ib[i]) /
					(u32)priv->bus.ib[priv->bus.num - 1];
			priv->bus.p_up[i] = t1 - HIST;
			priv->bus.p_down[i] = t2 - 2 * HIST;
			t2 = t1;
		}
		/* Set the upper-most and lower-most bounds correctly. */
		priv->bus.p_down[0] = 0;
		priv->bus.p_down[1] = (priv->bus.p_down[1] > (2 * HIST)) ?
					priv->bus.p_down[1] : (2 * HIST);
		if (priv->bus.num - 1 >= 0)
			priv->bus.p_up[priv->bus.num - 1] = 100;
		_update_cutoff(priv, priv->bus.max);
	}

	return kgsl_devfreq_add_notifier(devfreq->dev.parent, &priv->nb);
}
static int tz_start(struct devfreq *devfreq)
{
	struct devfreq_msm_adreno_tz_data *priv;
	unsigned int tz_pwrlevels[MSM_ADRENO_MAX_PWRLEVELS + 1];
	int i, out, ret;
	unsigned int version;

	struct msm_adreno_extended_profile *gpu_profile = container_of(
					(devfreq->profile),
					struct msm_adreno_extended_profile,
					profile);

	/*
	 * Assuming that we have only one instance of the adreno device
	 * connected to this governor,
	 * can safely restore the pointer to the governor private data
	 * from the container of the device profile
	 */
	devfreq->data = gpu_profile->private_data;
	partner_gpu_profile = gpu_profile;

	priv = devfreq->data;
	priv->nb.notifier_call = tz_notify;

	out = 1;
	if (devfreq->profile->max_state < MSM_ADRENO_MAX_PWRLEVELS) {
		for (i = 0; i < devfreq->profile->max_state; i++)
			tz_pwrlevels[out++] = devfreq->profile->freq_table[i];
		tz_pwrlevels[0] = i;
	} else {
		pr_err(TAG "tz_pwrlevels[] is too short\n");
		return -EINVAL;
	}

	gpu_profile->partner_wq = create_freezable_workqueue
					("governor_msm_adreno_tz_wq");
	INIT_WORK(&gpu_profile->partner_start_event_ws,
					do_partner_start_event);
	INIT_WORK(&gpu_profile->partner_stop_event_ws,
					do_partner_stop_event);
	INIT_WORK(&gpu_profile->partner_suspend_event_ws,
					do_partner_suspend_event);
	INIT_WORK(&gpu_profile->partner_resume_event_ws,
					do_partner_resume_event);

	ret = tz_init(priv, tz_pwrlevels, sizeof(tz_pwrlevels), &version,
				sizeof(version));
	if (ret != 0 || version > MAX_TZ_VERSION) {
		pr_err(TAG "tz_init failed\n");
		return ret;
	}

	return kgsl_devfreq_add_notifier(devfreq->dev.parent, &priv->nb);
}
Exemplo n.º 4
0
static int tz_start(struct devfreq *devfreq)
{
	struct devfreq_msm_adreno_tz_data *priv;
	unsigned int tz_pwrlevels[MSM_ADRENO_MAX_PWRLEVELS + 1];
	unsigned int t1, t2 = 2 * HIST;
	int i, out, ret;

	if (devfreq->data == NULL) {
		pr_err(TAG "data is required for this governor\n");
		return -EINVAL;
	}

	priv = devfreq->data;
	priv->nb.notifier_call = tz_notify;

	out = 1;
	if (devfreq->profile->max_state < MSM_ADRENO_MAX_PWRLEVELS) {
		for (i = 0; i < devfreq->profile->max_state; i++)
			tz_pwrlevels[out++] = devfreq->profile->freq_table[i];
		tz_pwrlevels[0] = i;
	} else {
		pr_err(TAG "tz_pwrlevels[] is too short\n");
		return -EINVAL;
	}

	ret = scm_call(SCM_SVC_DCVS, TZ_INIT_ID, tz_pwrlevels,
			sizeof(tz_pwrlevels), NULL, 0);

	if (ret != 0) {
		pr_err(TAG "tz_init failed\n");
		return ret;
	}

	/* Set up the cut-over percentages for the bus calculation. */
	if (priv->bus.num) {
		for (i = 0; i < priv->bus.num; i++) {
			t1 = (u32)(100 * priv->bus.ib[i]) /
					(u32)priv->bus.ib[priv->bus.num - 1];
			priv->bus.p_up[i] = t1 - HIST;
			priv->bus.p_down[i] = t2 - 2 * HIST;
			t2 = t1;
		}
		/* Set the upper-most and lower-most bounds correctly. */
		priv->bus.p_down[0] = 0;
		priv->bus.p_down[1] = (priv->bus.p_down[1] > (2 * HIST)) ?
					priv->bus.p_down[1] : (2 * HIST);
		if (priv->bus.num - 1 >= 0)
			priv->bus.p_up[priv->bus.num - 1] = 100;
		_update_cutoff(priv, priv->bus.max);
	}

	return kgsl_devfreq_add_notifier(devfreq->dev.parent, &priv->nb);
}