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; }
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 }
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; }
/* * 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; }