static int sr_class3_enable(struct voltagedomain *voltdm, struct omap_volt_data *volt_data) { omap_vp_enable(voltdm); return sr_enable(voltdm, volt_data); }
/** * sr_class1p5_enable() - class 1.5 mode of enable for a voltage domain * @voltdm: voltage domain to enable SR for * @voltdm_cdata: voltage domain specific private class data * @volt_data: voltdata for the current OPP being transitioned to * * when this gets called, we use the h/w loop to setup our voltages * to an calibrated voltage, detect any oscillations, recover from the same * and finally store the optimized voltage as the calibrated voltage in the * system. * * NOTE: Appropriate locks must be held by calling path to ensure mutual * exclusivity */ static int sr_class1p5_enable(struct voltagedomain *voltdm, void *voltdm_cdata, struct omap_volt_data *volt_data) { int r; struct sr_class1p5_work_data *work_data; /* check bypass flag, if enabled, do nothing */ if (volt_data->sr_bypass) return 0; if (IS_ERR_OR_NULL(voltdm) || IS_ERR_OR_NULL(volt_data)) { pr_err("%s: bad parameters!\n", __func__); return -EINVAL; } /* If already calibrated, nothing to do here.. */ if (volt_data->volt_calibrated) return 0; /* Based on Imoseyon's idea to properly calibrate high frequencies e.g. >= 1.4Ghz MPU */ if (volt_data->volt_nominal >= 1375000) { volt_data->volt_calibrated = volt_data->volt_nominal; volt_data->volt_dynamic_nominal = volt_data->volt_nominal; pr_info("[franciscofranco] %p - nominal %d", __func__, volt_data->volt_nominal); pr_info("[franciscofranco] %p - in the selected OPP its default nominal voltage is equal or above 1375mV so we don't calibrate it to prevent a crash.", __func__); return 0; } work_data = (struct sr_class1p5_work_data *)voltdm_cdata; if (IS_ERR_OR_NULL(work_data)) { pr_err("%s: bad work data??\n", __func__); return -EINVAL; } if (work_data->work_active) return 0; omap_vp_enable(voltdm); r = sr_enable(voltdm, volt_data); if (r) { pr_err("%s: sr[%s] failed\n", __func__, voltdm->name); sr_disable_errgen(voltdm); omap_vp_disable(voltdm); return r; } work_data->vdata = volt_data; work_data->work_active = true; work_data->num_calib_triggers = 0; /* Dont interrupt me untill calibration is complete */ pm_qos_update_request(&work_data->qos, 0); /* program the workqueue and leave it to calibrate offline.. */ schedule_delayed_work(&work_data->work, msecs_to_jiffies(SR1P5_SAMPLING_DELAY_MS * SR1P5_STABLE_SAMPLES)); return 0; }
/** * sr_classp5_start_hw_loop() * @sr: SmartReflex for which we start calibration * * Starts hardware calibration */ static int sr_classp5_start_hw_loop(struct omap_sr *sr) { int res; omap_vp_enable(sr->voltdm); res = sr_enable(sr); if (res) { pr_err("%s: %s failed to start HW loop\n", __func__, sr->name); omap_vp_disable(sr->voltdm); } return res; }
static int sr_class3_enable(struct voltagedomain *voltdm) { unsigned long volt = omap_voltage_get_nom_volt(voltdm); if (!volt) { pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n", __func__, voltdm->name); return -ENODATA; } omap_vp_enable(voltdm); return sr_enable(voltdm, volt); }
static int sr_class3_enable(struct omap_sr *sr) { unsigned long volt = voltdm_get_voltage(sr->voltdm); if (!volt) { pr_warning("%s: Curr voltage unknown. Cannot enable %s\n", __func__, sr->name); return -ENODATA; } omap_vp_enable(sr->voltdm); return sr_enable(sr->voltdm, volt); }
/** * sr_class1p5_enable() - class 1.5 mode of enable * @voltdm: voltage domain to enable SR for * @volt_data: voltdata to the voltage transition taking place * * when this gets called, we use the h/w loop to setup our voltages * to an calibrated voltage, detect any oscillations, recover from the same * and finally store the optimized voltage as the calibrated voltage in the * system */ static int sr_class1p5_enable(struct voltagedomain *voltdm, struct omap_volt_data *volt_data) { int r; struct sr_class1p5_work_data *work_data; if (IS_ERR_OR_NULL(voltdm) || IS_ERR_OR_NULL(volt_data)) { pr_err("%s: bad parameters!\n", __func__); return -EINVAL; } /* if already calibrated, nothing to do here.. */ if (volt_data->volt_calibrated) return 0; work_data = get_sr1p5_work(voltdm); if (unlikely(!work_data)) { pr_err("%s: aieeee.. bad work data??\n", __func__); return -EINVAL; } if (work_data->work_active) return 0; omap_vp_enable(voltdm); r = sr_enable(voltdm, volt_data); if (r) { pr_err("%s: sr[%s] failed\n", __func__, voltdm->name); omap_vp_disable(voltdm); return r; } work_data->vdata = volt_data; work_data->work_active = true; work_data->num_calib_triggers = 0; /* Hold a c-state constraint */ omap_pm_set_max_mpu_wakeup_lat(&work_data->qos_request, 1000); pr_debug("%s - %s: hold c-state\n", __func__, voltdm->name); /* program the workqueue and leave it to calibrate offline.. */ schedule_delayed_work(&work_data->work, msecs_to_jiffies(SR1P5_SAMPLING_DELAY_MS * SR1P5_STABLE_SAMPLES)); return 0; }
/** * sr_class1p5_enable() - class 1.5 mode of enable for a voltage domain * @voltdm: voltage domain to enable SR for * @voltdm_cdata: voltage domain specific private class data * @volt_data: voltdata for the current OPP being transitioned to * * when this gets called, we use the h/w loop to setup our voltages * to an calibrated voltage, detect any oscillations, recover from the same * and finally store the optimized voltage as the calibrated voltage in the * system. * * NOTE: Appropriate locks must be held by calling path to ensure mutual * exclusivity */ static int sr_class1p5_enable(struct voltagedomain *voltdm, void *voltdm_cdata, struct omap_volt_data *volt_data) { int r; struct sr_class1p5_work_data *work_data; if (IS_ERR_OR_NULL(voltdm) || IS_ERR_OR_NULL(volt_data)) { pr_err("%s: bad parameters!\n", __func__); return -EINVAL; } /* If already calibrated, nothing to do here.. */ if (volt_data->volt_calibrated) return 0; work_data = (struct sr_class1p5_work_data *)voltdm_cdata; if (IS_ERR_OR_NULL(work_data)) { pr_err("%s: bad work data??\n", __func__); return -EINVAL; } if (work_data->work_active) return 0; omap_vp_enable(voltdm); r = sr_enable(voltdm, volt_data); if (r) { pr_err("%s: sr[%s] failed\n", __func__, voltdm->name); sr_disable_errgen(voltdm); omap_vp_disable(voltdm); return r; } work_data->vdata = volt_data; work_data->work_active = true; work_data->num_calib_triggers = 0; /* program the workqueue and leave it to calibrate offline.. */ schedule_delayed_work(&work_data->work, msecs_to_jiffies(SR1P5_SAMPLING_DELAY_MS * SR1P5_STABLE_SAMPLES)); return 0; }