static int rpm_change_memory_state(int retention_mask,
					int active_mask)
{
	int ret;
	struct msm_rpm_iv_pair cmd[2];
	struct msm_rpm_iv_pair status[2];

	cmd[0].id = MSM_RPM_ID_DDR_DMM_0;
	cmd[1].id = MSM_RPM_ID_DDR_DMM_1;

	status[0].id = MSM_RPM_STATUS_ID_DDR_DMM_0;
	status[1].id = MSM_RPM_STATUS_ID_DDR_DMM_1;

	cmd[0].value = retention_mask;
	cmd[1].value = active_mask;

	ret = msm_rpm_set(MSM_RPM_CTX_SET_0, cmd, 2);
	if (ret < 0) {
		pr_err("rpm set failed");
		return -EINVAL;
	}

	ret = msm_rpm_get_status(status, 2);
	if (ret < 0) {
		pr_err("rpm status failed");
		return -EINVAL;
	}
	if (status[0].value == retention_mask &&
		status[1].value == active_mask)
		return 0;
	else {
		pr_err("rpm failed to change memory state");
		return -EINVAL;
	}
}
static int vreg_set(struct vreg *vreg, unsigned mask0, unsigned val0,
		unsigned mask1, unsigned val1, unsigned cnt)
{
	unsigned prev0 = 0, prev1 = 0;
	int rc;

	/*
	 * Bypass the normal route for regulators that can be called to change
	 * just the active set values.
	 */
	if (vreg->pdata.sleep_selectable)
		return vreg_set_noirq(vreg, RPM_VREG_VOTER_REG_FRAMEWORK, 1,
					mask0, val0, mask1, val1, cnt, 1);

	prev0 = vreg->req[0].value;
	vreg->req[0].value &= ~mask0;
	vreg->req[0].value |= val0 & mask0;

	prev1 = vreg->req[1].value;
	vreg->req[1].value &= ~mask1;
	vreg->req[1].value |= val1 & mask1;

	/* Ignore duplicate requests */
	if (vreg->req[0].value == vreg->prev_active_req[0].value &&
	    vreg->req[1].value == vreg->prev_active_req[1].value) {
		if (msm_rpm_vreg_debug_mask & MSM_RPM_VREG_DEBUG_DUPLICATE)
			rpm_regulator_duplicate(vreg, MSM_RPM_CTX_SET_0, cnt);
		return 0;
	}

	rc = msm_rpm_set(MSM_RPM_CTX_SET_0, vreg->req, cnt);
	if (rc) {
		vreg->req[0].value = prev0;
		vreg->req[1].value = prev1;

		vreg_err(vreg, "msm_rpm_set failed, set=active, id=%d, rc=%d\n",
			vreg->req[0].id, rc);
	} else {
		if (msm_rpm_vreg_debug_mask & MSM_RPM_VREG_DEBUG_REQUEST)
			rpm_regulator_req(vreg, MSM_RPM_CTX_SET_0);
		vreg->prev_active_req[0].value = vreg->req[0].value;
		vreg->prev_active_req[1].value = vreg->req[1].value;
	}

	return rc;
}
Esempio n. 3
0
static void mdm_setup_vddmin_gpios(void)
{
#ifdef CONFIG_ARCH_EXYNOS
	return;
#else
	struct msm_rpm_iv_pair req;
	struct mdm_vddmin_resource *vddmin_res;
	int irq, ret;

	/* This resource may not be supported by some platforms. */
	vddmin_res = mdm_drv->pdata->vddmin_resource;
	if (!vddmin_res)
		return;

	req.id = vddmin_res->rpm_id;
	req.value = ((uint32_t)vddmin_res->ap2mdm_vddmin_gpio & 0x0000FFFF)
							<< 16;
	req.value |= ((uint32_t)vddmin_res->modes & 0x000000FF) << 8;
	req.value |= (uint32_t)vddmin_res->drive_strength & 0x000000FF;

	msm_rpm_set(MSM_RPM_CTX_SET_0, &req, 1);

	/* Monitor low power gpio from mdm */
	irq = MSM_GPIO_TO_INT(vddmin_res->mdm2ap_vddmin_gpio);
	if (irq < 0) {
		pr_err("%s: could not get LPM POWER IRQ resource.\n",
			__func__);
		goto error_end;
	}

	ret = request_threaded_irq(irq, NULL, mdm_vddmin_change,
		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
		"mdm lpm", NULL);

	if (ret < 0)
		pr_err("%s: MDM LPM IRQ#%d request failed with error=%d",
			__func__, irq, ret);
error_end:
	return;
#endif
}
Esempio n. 4
0
static void qsc_setup_vddmin_gpios(void)
{
	struct msm_rpm_iv_pair req;
	struct mdm_vddmin_resource *vddmin_res;
	int irq, ret;

	
	vddmin_res = mdm_drv->pdata->vddmin_resource;
	if (!vddmin_res)
		return;

	pr_info("Enabling vddmin logging\n");
	req.id = vddmin_res->rpm_id;
	req.value = ((uint32_t)vddmin_res->ap2mdm_vddmin_gpio & 0x0000FFFF)
							<< 16;
	req.value |= ((uint32_t)vddmin_res->modes & 0x000000FF) << 8;
	req.value |= (uint32_t)vddmin_res->drive_strength & 0x000000FF;

	msm_rpm_set(MSM_RPM_CTX_SET_0, &req, 1);

	
	irq = MSM_GPIO_TO_INT(vddmin_res->mdm2ap_vddmin_gpio);
	if (irq < 0) {
		pr_err("%s: could not get LPM POWER IRQ resource.\n",
			__func__);
		goto error_end;
	}

	ret = request_threaded_irq(irq, NULL, qsc_vddmin_change,
		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
		"mdm lpm", NULL);

	if (ret < 0)
		pr_err("%s: MDM LPM IRQ#%d request failed with error=%d",
			__func__, irq, ret);
error_end:
	return;
}
Esempio n. 5
0
/*
 * rpm_debug_resource_set()
 * 	Generic API to set a RPM resource to particular value
 *
 * TODO Currently it only accepts only one 32-bit value as parameter and
 * sets all the value parameters in the RPM request to this value.
 * This should be extended to accept multiple values
 */
static int rpm_debug_resource_set(void *data, u64 val)
{
	int i;
	int ret;

	struct msm_rpm_iv_pair req[MAX_REQUEST_LEN];
	struct msm_rpm_map_data *resource;

	resource = data;

	for (i = 0; i < resource->count; i++) {
		req[i].id = resource->id;
		req[i].value = (uint32_t) val;
	}

	ret = msm_rpm_set(MSM_RPM_CTX_SET_0, req, resource->count);

	if (ret) {
		pr_err("rpm_debug_resource_set(%d, %d) failed (%d)\n", resource->id,
				(uint32_t)val, ret);
	}

	return ret;
}