Lines Matching +full:qcom +full:- +full:cpufreq +full:- +full:nvmem

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
26 #include <linux/nvmem-consumer.h>
28 /* Register Offsets for RB-CPR and Bit Definitions */
124 #define FUSE_REVISION_UNKNOWN (-1)
253 return !drv->loop_disabled; in cpr_is_allowed()
258 writel_relaxed(value, drv->base + offset); in cpr_write()
263 return readl_relaxed(drv->base + offset); in cpr_read()
271 val = readl_relaxed(drv->base + offset); in cpr_masked_write()
274 writel_relaxed(val, drv->base + offset); in cpr_masked_write()
307 const struct cpr_desc *desc = drv->desc; in cpr_ctl_enable()
310 val = desc->timer_cons_down << RBIF_TIMER_ADJ_CONS_DOWN_SHIFT; in cpr_ctl_enable()
311 val |= desc->timer_cons_up << RBIF_TIMER_ADJ_CONS_UP_SHIFT; in cpr_ctl_enable()
317 corner->save_ctl); in cpr_ctl_enable()
318 cpr_irq_set(drv, corner->save_irq); in cpr_ctl_enable()
320 if (cpr_is_allowed(drv) && corner->max_uV > corner->min_uV) in cpr_ctl_enable()
359 corner->save_ctl = cpr_read(drv, REG_RBCPR_CTL); in cpr_corner_save()
360 corner->save_irq = cpr_read(drv, REG_RBIF_IRQ_EN(0)); in cpr_corner_save()
366 struct fuse_corner *fuse = corner->fuse_corner; in cpr_corner_restore()
367 const struct cpr_desc *desc = drv->desc; in cpr_corner_restore()
370 ro_sel = fuse->ring_osc_idx; in cpr_corner_restore()
371 gcnt = drv->gcnt; in cpr_corner_restore()
372 gcnt |= fuse->quot - corner->quot_adjust; in cpr_corner_restore()
375 step_quot = desc->idle_clocks << RBCPR_STEP_QUOT_IDLE_CLK_SHIFT; in cpr_corner_restore()
376 step_quot |= fuse->step_quot & RBCPR_STEP_QUOT_STEPQUOT_MASK; in cpr_corner_restore()
384 ctl = corner->save_ctl; in cpr_corner_restore()
386 irq = corner->save_irq; in cpr_corner_restore()
388 dev_dbg(drv->dev, "gcnt = %#08x, ctl = %#08x, irq = %#08x\n", gcnt, in cpr_corner_restore()
400 regmap_multi_reg_write(tcsr, f->accs, f->num_accs); in cpr_set_acc()
402 for (f -= 1; f >= end; f--) in cpr_set_acc()
403 regmap_multi_reg_write(tcsr, f->accs, f->num_accs); in cpr_set_acc()
411 struct fuse_corner *prev_fuse_corner = drv->corner->fuse_corner; in cpr_pre_voltage()
413 if (drv->tcsr && dir == DOWN) in cpr_pre_voltage()
414 cpr_set_acc(drv->tcsr, prev_fuse_corner, fuse_corner); in cpr_pre_voltage()
423 struct fuse_corner *prev_fuse_corner = drv->corner->fuse_corner; in cpr_post_voltage()
425 if (drv->tcsr && dir == UP) in cpr_post_voltage()
426 cpr_set_acc(drv->tcsr, prev_fuse_corner, fuse_corner); in cpr_post_voltage()
435 struct fuse_corner *fuse_corner = corner->fuse_corner; in cpr_scale_voltage()
441 ret = regulator_set_voltage(drv->vdd_apc, new_uV, new_uV); in cpr_scale_voltage()
443 dev_err_ratelimited(drv->dev, "failed to set apc voltage %d\n", in cpr_scale_voltage()
457 return drv->corner ? drv->corner - drv->corners + 1 : 0; in cpr_get_cur_perf_state()
465 const struct cpr_desc *desc = drv->desc; in cpr_scale()
470 step_uV = regulator_get_linear_step(drv->vdd_apc); in cpr_scale()
472 return -EINVAL; in cpr_scale()
474 corner = drv->corner; in cpr_scale()
480 last_uV = corner->last_uV; in cpr_scale()
483 if (desc->clamp_timer_interval && in cpr_scale()
484 error_steps < desc->up_threshold) { in cpr_scale()
490 error_steps = max(desc->up_threshold, in cpr_scale()
491 desc->vdd_apc_step_up_limit); in cpr_scale()
494 if (last_uV >= corner->max_uV) { in cpr_scale()
509 if (error_steps > desc->vdd_apc_step_up_limit) in cpr_scale()
510 error_steps = desc->vdd_apc_step_up_limit; in cpr_scale()
514 new_uV = min(new_uV, corner->max_uV); in cpr_scale()
516 dev_dbg(drv->dev, in cpr_scale()
517 "UP: -> new_uV: %d last_uV: %d perf state: %u\n", in cpr_scale()
520 if (desc->clamp_timer_interval && in cpr_scale()
521 error_steps < desc->down_threshold) { in cpr_scale()
527 error_steps = max(desc->down_threshold, in cpr_scale()
528 desc->vdd_apc_step_down_limit); in cpr_scale()
531 if (last_uV <= corner->min_uV) { in cpr_scale()
546 if (error_steps > desc->vdd_apc_step_down_limit) in cpr_scale()
547 error_steps = desc->vdd_apc_step_down_limit; in cpr_scale()
550 new_uV = last_uV - error_steps * step_uV; in cpr_scale()
551 new_uV = max(new_uV, corner->min_uV); in cpr_scale()
553 dev_dbg(drv->dev, in cpr_scale()
554 "DOWN: -> new_uV: %d last_uV: %d perf state: %u\n", in cpr_scale()
563 drv->corner->last_uV = new_uV; in cpr_scale()
573 val = desc->up_threshold; in cpr_scale()
579 /* Re-enable default interrupts */ in cpr_scale()
591 const struct cpr_desc *desc = drv->desc; in cpr_irq_handler()
595 mutex_lock(&drv->lock); in cpr_irq_handler()
598 if (drv->flags & FLAGS_IGNORE_1ST_IRQ_STATUS) in cpr_irq_handler()
601 dev_dbg(drv->dev, "IRQ_STATUS = %#02x\n", val); in cpr_irq_handler()
604 dev_dbg(drv->dev, "CPR is disabled\n"); in cpr_irq_handler()
606 } else if (cpr_ctl_is_busy(drv) && !desc->clamp_timer_interval) { in cpr_irq_handler()
607 dev_dbg(drv->dev, "CPR measurement is not ready\n"); in cpr_irq_handler()
610 dev_err_ratelimited(drv->dev, in cpr_irq_handler()
629 dev_dbg(drv->dev, "IRQ occurred for Mid Flag\n"); in cpr_irq_handler()
631 dev_dbg(drv->dev, in cpr_irq_handler()
636 cpr_corner_save(drv, drv->corner); in cpr_irq_handler()
639 mutex_unlock(&drv->lock); in cpr_irq_handler()
648 ret = regulator_enable(drv->vdd_apc); in cpr_enable()
652 mutex_lock(&drv->lock); in cpr_enable()
654 if (cpr_is_allowed(drv) && drv->corner) { in cpr_enable()
656 cpr_corner_restore(drv, drv->corner); in cpr_enable()
657 cpr_ctl_enable(drv, drv->corner); in cpr_enable()
660 mutex_unlock(&drv->lock); in cpr_enable()
667 mutex_lock(&drv->lock); in cpr_disable()
674 mutex_unlock(&drv->lock); in cpr_disable()
676 return regulator_disable(drv->vdd_apc); in cpr_disable()
684 const struct cpr_desc *desc = drv->desc; in cpr_config()
705 gcnt = (drv->ref_clk_khz * desc->gcnt_us) / 1000; in cpr_config()
708 drv->gcnt = gcnt; in cpr_config()
711 val = (drv->ref_clk_khz * desc->timer_delay_us) / 1000; in cpr_config()
713 dev_dbg(drv->dev, "Timer count: %#0x (for %d us)\n", val, in cpr_config()
714 desc->timer_delay_us); in cpr_config()
717 val = desc->timer_cons_down << RBIF_TIMER_ADJ_CONS_DOWN_SHIFT; in cpr_config()
718 val |= desc->timer_cons_up << RBIF_TIMER_ADJ_CONS_UP_SHIFT; in cpr_config()
719 val |= desc->clamp_timer_interval << RBIF_TIMER_ADJ_CLAMP_INT_SHIFT; in cpr_config()
723 val = desc->up_threshold << RBCPR_CTL_UP_THRESHOLD_SHIFT; in cpr_config()
724 val |= desc->down_threshold << RBCPR_CTL_DN_THRESHOLD_SHIFT; in cpr_config()
729 for (i = 0; i < drv->num_corners; i++) { in cpr_config()
730 corner = &drv->corners[i]; in cpr_config()
731 corner->save_ctl = val; in cpr_config()
732 corner->save_irq = CPR_INT_DEFAULT; in cpr_config()
739 drv->flags |= FLAGS_IGNORE_1ST_IRQ_STATUS; in cpr_config()
752 mutex_lock(&drv->lock); in cpr_set_performance_state()
754 dev_dbg(drv->dev, "%s: setting perf state: %u (prev state: %u)\n", in cpr_set_performance_state()
761 corner = drv->corners + state - 1; in cpr_set_performance_state()
762 end = &drv->corners[drv->num_corners - 1]; in cpr_set_performance_state()
763 if (corner > end || corner < drv->corners) { in cpr_set_performance_state()
764 ret = -EINVAL; in cpr_set_performance_state()
769 if (drv->corner > corner) in cpr_set_performance_state()
771 else if (drv->corner < corner) in cpr_set_performance_state()
777 new_uV = corner->last_uV; in cpr_set_performance_state()
779 new_uV = corner->uV; in cpr_set_performance_state()
790 if (drv->corner != corner) in cpr_set_performance_state()
795 drv->corner = corner; in cpr_set_performance_state()
798 mutex_unlock(&drv->lock); in cpr_set_performance_state()
806 struct fuse_corner *fuse = drv->fuse_corners; in cpr_populate_ring_osc_idx()
807 struct fuse_corner *end = fuse + drv->desc->num_fuse_corners; in cpr_populate_ring_osc_idx()
808 const struct cpr_fuse *fuses = drv->cpr_fuses; in cpr_populate_ring_osc_idx()
813 ret = nvmem_cell_read_variable_le_u32(drv->dev, fuses->ring_osc, &data); in cpr_populate_ring_osc_idx()
816 fuse->ring_osc_idx = data; in cpr_populate_ring_osc_idx()
832 ret = nvmem_cell_read_variable_le_u32(drv->dev, init_v_efuse, &bits); in cpr_read_fuse_uV()
836 steps = bits & ~BIT(desc->cpr_fuses.init_voltage_width - 1); in cpr_read_fuse_uV()
838 if (bits & BIT(desc->cpr_fuses.init_voltage_width - 1)) in cpr_read_fuse_uV()
839 steps = -steps; in cpr_read_fuse_uV()
841 step_size_uV = desc->cpr_fuses.init_voltage_step; in cpr_read_fuse_uV()
843 uV = fdata->ref_uV + steps * step_size_uV; in cpr_read_fuse_uV()
849 const struct cpr_desc *desc = drv->desc; in cpr_fuse_corner_init()
850 const struct cpr_fuse *fuses = drv->cpr_fuses; in cpr_fuse_corner_init()
851 const struct acc_desc *acc_desc = drv->acc_desc; in cpr_fuse_corner_init()
860 accs = acc_desc->settings; in cpr_fuse_corner_init()
862 step_volt = regulator_get_linear_step(drv->vdd_apc); in cpr_fuse_corner_init()
864 return -EINVAL; in cpr_fuse_corner_init()
867 fuse = drv->fuse_corners; in cpr_fuse_corner_init()
868 end = &fuse[desc->num_fuse_corners - 1]; in cpr_fuse_corner_init()
869 fdata = desc->cpr_fuses.fuse_corner_data; in cpr_fuse_corner_init()
877 fdata->min_uV = roundup(fdata->min_uV, step_volt); in cpr_fuse_corner_init()
878 fdata->max_uV = roundup(fdata->max_uV, step_volt); in cpr_fuse_corner_init()
881 uV = cpr_read_fuse_uV(desc, fdata, fuses->init_voltage, in cpr_fuse_corner_init()
886 fuse->min_uV = fdata->min_uV; in cpr_fuse_corner_init()
887 fuse->max_uV = fdata->max_uV; in cpr_fuse_corner_init()
888 fuse->uV = clamp(uV, fuse->min_uV, fuse->max_uV); in cpr_fuse_corner_init()
897 end->max_uV = max(end->max_uV, end->uV); in cpr_fuse_corner_init()
901 ret = nvmem_cell_read_variable_le_u32(drv->dev, fuses->quotient, &fuse->quot); in cpr_fuse_corner_init()
905 fuse->quot *= fdata->quot_scale; in cpr_fuse_corner_init()
906 fuse->quot += fdata->quot_offset; in cpr_fuse_corner_init()
907 fuse->quot += fdata->quot_adjust; in cpr_fuse_corner_init()
908 fuse->step_quot = desc->step_quot[fuse->ring_osc_idx]; in cpr_fuse_corner_init()
911 fuse->accs = accs; in cpr_fuse_corner_init()
912 fuse->num_accs = acc_desc->num_regs_per_fuse; in cpr_fuse_corner_init()
913 accs += acc_desc->num_regs_per_fuse; in cpr_fuse_corner_init()
920 for (fuse = drv->fuse_corners, i = 0; fuse <= end; fuse++, i++) { in cpr_fuse_corner_init()
921 if (fuse->uV > fuse->max_uV) in cpr_fuse_corner_init()
922 fuse->uV = fuse->max_uV; in cpr_fuse_corner_init()
923 else if (fuse->uV < fuse->min_uV) in cpr_fuse_corner_init()
924 fuse->uV = fuse->min_uV; in cpr_fuse_corner_init()
926 ret = regulator_is_supported_voltage(drv->vdd_apc, in cpr_fuse_corner_init()
927 fuse->min_uV, in cpr_fuse_corner_init()
928 fuse->min_uV); in cpr_fuse_corner_init()
930 dev_err(drv->dev, in cpr_fuse_corner_init()
932 fuse->min_uV, i); in cpr_fuse_corner_init()
933 return -EINVAL; in cpr_fuse_corner_init()
936 ret = regulator_is_supported_voltage(drv->vdd_apc, in cpr_fuse_corner_init()
937 fuse->max_uV, in cpr_fuse_corner_init()
938 fuse->max_uV); in cpr_fuse_corner_init()
940 dev_err(drv->dev, in cpr_fuse_corner_init()
942 fuse->max_uV, i); in cpr_fuse_corner_init()
943 return -EINVAL; in cpr_fuse_corner_init()
946 dev_dbg(drv->dev, in cpr_fuse_corner_init()
948 i, fuse->min_uV, fuse->uV, fuse->max_uV, in cpr_fuse_corner_init()
949 fuse->ring_osc_idx, fuse->quot, fuse->step_quot); in cpr_fuse_corner_init()
966 fuse = corner->fuse_corner; in cpr_calculate_scaling()
967 prev_fuse = fuse - 1; in cpr_calculate_scaling()
970 ret = nvmem_cell_read_variable_le_u32(drv->dev, quot_offset, &quot_diff); in cpr_calculate_scaling()
974 quot_diff *= fdata->quot_offset_scale; in cpr_calculate_scaling()
975 quot_diff += fdata->quot_offset_adjust; in cpr_calculate_scaling()
977 quot_diff = fuse->quot - prev_fuse->quot; in cpr_calculate_scaling()
980 freq_diff = fuse->max_freq - prev_fuse->max_freq; in cpr_calculate_scaling()
983 return min(scaling, fdata->max_quot_scale); in cpr_calculate_scaling()
994 fuse = corner->fuse_corner; in cpr_interpolate()
995 prev_fuse = fuse - 1; in cpr_interpolate()
997 f_high = fuse->max_freq; in cpr_interpolate()
998 f_low = prev_fuse->max_freq; in cpr_interpolate()
999 uV_high = fuse->uV; in cpr_interpolate()
1000 uV_low = prev_fuse->uV; in cpr_interpolate()
1001 f_diff = fuse->max_freq - corner->freq; in cpr_interpolate()
1008 if (f_high <= f_low || uV_high <= uV_low || f_high <= corner->freq) in cpr_interpolate()
1009 return corner->uV; in cpr_interpolate()
1011 temp = f_diff * (uV_high - uV_low); in cpr_interpolate()
1012 temp = div64_ul(temp, f_high - f_low); in cpr_interpolate()
1018 temp_limit = f_diff * fdata->max_volt_scale; in cpr_interpolate()
1021 uV = uV_high - min(temp, temp_limit); in cpr_interpolate()
1031 if (of_property_read_u32(np, "qcom,opp-fuse-level", &fuse_corner)) in cpr_get_fuse_corner()
1032 pr_err("%s: missing 'qcom,opp-fuse-level' property\n", in cpr_get_fuse_corner()
1060 child_req_np = of_parse_phandle(child_np, "required-opps", 0); in cpr_get_opp_hz_for_req()
1064 of_property_read_u64(child_np, "opp-hz", &rate); in cpr_get_opp_hz_for_req()
1077 const struct cpr_desc *desc = drv->desc; in cpr_corner_init()
1078 const struct cpr_fuse *fuses = drv->cpr_fuses; in cpr_corner_init()
1089 int step_volt = regulator_get_linear_step(drv->vdd_apc); in cpr_corner_init()
1093 return -EINVAL; in cpr_corner_init()
1095 corner = drv->corners; in cpr_corner_init()
1096 end = &corner[drv->num_corners - 1]; in cpr_corner_init()
1098 cdata = devm_kcalloc(drv->dev, drv->num_corners, in cpr_corner_init()
1102 return -ENOMEM; in cpr_corner_init()
1108 for (level = 1; level <= drv->num_corners; level++) { in cpr_corner_init()
1109 opp = dev_pm_opp_find_level_exact(&drv->pd.dev, level); in cpr_corner_init()
1111 return -EINVAL; in cpr_corner_init()
1115 return -EINVAL; in cpr_corner_init()
1117 fnum = fc - 1; in cpr_corner_init()
1118 freq = cpr_get_opp_hz_for_req(opp, drv->attached_cpu_dev); in cpr_corner_init()
1121 return -EINVAL; in cpr_corner_init()
1123 cdata[level - 1].fuse_corner = fnum; in cpr_corner_init()
1124 cdata[level - 1].freq = freq; in cpr_corner_init()
1126 fuse = &drv->fuse_corners[fnum]; in cpr_corner_init()
1127 dev_dbg(drv->dev, "freq: %lu level: %u fuse level: %u\n", in cpr_corner_init()
1128 freq, dev_pm_opp_get_level(opp) - 1, fnum); in cpr_corner_init()
1129 if (freq > fuse->max_freq) in cpr_corner_init()
1130 fuse->max_freq = freq; in cpr_corner_init()
1137 * scaling = min(1000 * (QUOT(corner_N) - QUOT(corner_N-1)) in cpr_corner_init()
1138 * / (freq(corner_N) - freq(corner_N-1)), max_factor) in cpr_corner_init()
1141 * QUOT(corner_N-1): quotient read from fuse for fuse corner (N - 1) in cpr_corner_init()
1143 * freq(corner_N-1): max frequency in MHz supported by fuse corner in cpr_corner_init()
1144 * (N - 1) in cpr_corner_init()
1150 * quot_adjust = (freq_max - freq_corner) * scaling / 1000 in cpr_corner_init()
1165 * +--------------- +---------------- in cpr_corner_init()
1175 fdata = &desc->cpr_fuses.fuse_corner_data[fnum]; in cpr_corner_init()
1177 fuse = &drv->fuse_corners[fnum]; in cpr_corner_init()
1179 prev_fuse = &drv->fuse_corners[fnum - 1]; in cpr_corner_init()
1183 corner->fuse_corner = fuse; in cpr_corner_init()
1184 corner->freq = cdata[i].freq; in cpr_corner_init()
1185 corner->uV = fuse->uV; in cpr_corner_init()
1187 if (prev_fuse && cdata[i - 1].freq == prev_fuse->max_freq) { in cpr_corner_init()
1194 } else if (corner->freq == fuse->max_freq) { in cpr_corner_init()
1200 freq_diff = fuse->max_freq - corner->freq; in cpr_corner_init()
1202 corner->quot_adjust = scaling * freq_diff_mhz / 1000; in cpr_corner_init()
1204 corner->uV = cpr_interpolate(corner, step_volt, fdata); in cpr_corner_init()
1207 corner->max_uV = fuse->max_uV; in cpr_corner_init()
1208 corner->min_uV = fuse->min_uV; in cpr_corner_init()
1209 corner->uV = clamp(corner->uV, corner->min_uV, corner->max_uV); in cpr_corner_init()
1210 corner->last_uV = corner->uV; in cpr_corner_init()
1213 if (desc->reduce_to_corner_uV && corner->uV < corner->max_uV) in cpr_corner_init()
1214 corner->max_uV = corner->uV; in cpr_corner_init()
1215 else if (desc->reduce_to_fuse_uV && fuse->uV < corner->max_uV) in cpr_corner_init()
1216 corner->max_uV = max(corner->min_uV, fuse->uV); in cpr_corner_init()
1218 dev_dbg(drv->dev, "corner %d: [%d %d %d] quot %d\n", i, in cpr_corner_init()
1219 corner->min_uV, corner->uV, corner->max_uV, in cpr_corner_init()
1220 fuse->quot - corner->quot_adjust); in cpr_corner_init()
1228 const struct cpr_desc *desc = drv->desc; in cpr_get_fuses()
1232 fuses = devm_kcalloc(drv->dev, desc->num_fuse_corners, in cpr_get_fuses()
1236 return ERR_PTR(-ENOMEM); in cpr_get_fuses()
1238 for (i = 0; i < desc->num_fuse_corners; i++) { in cpr_get_fuses()
1242 fuses[i].ring_osc = devm_kstrdup(drv->dev, tbuf, GFP_KERNEL); in cpr_get_fuses()
1244 return ERR_PTR(-ENOMEM); in cpr_get_fuses()
1247 fuses[i].init_voltage = devm_kstrdup(drv->dev, tbuf, in cpr_get_fuses()
1250 return ERR_PTR(-ENOMEM); in cpr_get_fuses()
1253 fuses[i].quotient = devm_kstrdup(drv->dev, tbuf, GFP_KERNEL); in cpr_get_fuses()
1255 return ERR_PTR(-ENOMEM); in cpr_get_fuses()
1258 fuses[i].quotient_offset = devm_kstrdup(drv->dev, tbuf, in cpr_get_fuses()
1261 return ERR_PTR(-ENOMEM); in cpr_get_fuses()
1269 drv->loop_disabled = false; in cpr_set_loop_allowed()
1274 const struct cpr_desc *desc = drv->desc; in cpr_init_parameters()
1277 clk = clk_get(drv->dev, "ref"); in cpr_init_parameters()
1281 drv->ref_clk_khz = clk_get_rate(clk) / 1000; in cpr_init_parameters()
1284 if (desc->timer_cons_up > RBIF_TIMER_ADJ_CONS_UP_MASK || in cpr_init_parameters()
1285 desc->timer_cons_down > RBIF_TIMER_ADJ_CONS_DOWN_MASK || in cpr_init_parameters()
1286 desc->up_threshold > RBCPR_CTL_UP_THRESHOLD_MASK || in cpr_init_parameters()
1287 desc->down_threshold > RBCPR_CTL_DN_THRESHOLD_MASK || in cpr_init_parameters()
1288 desc->idle_clocks > RBCPR_STEP_QUOT_IDLE_CLK_MASK || in cpr_init_parameters()
1289 desc->clamp_timer_interval > RBIF_TIMER_ADJ_CLAMP_INT_MASK) in cpr_init_parameters()
1290 return -EINVAL; in cpr_init_parameters()
1292 dev_dbg(drv->dev, "up threshold = %u, down threshold = %u\n", in cpr_init_parameters()
1293 desc->up_threshold, desc->down_threshold); in cpr_init_parameters()
1305 if (!drv->cpu_clk) { in cpr_find_initial_corner()
1306 dev_err(drv->dev, "cannot get rate from NULL clk\n"); in cpr_find_initial_corner()
1307 return -EINVAL; in cpr_find_initial_corner()
1310 end = &drv->corners[drv->num_corners - 1]; in cpr_find_initial_corner()
1311 rate = clk_get_rate(drv->cpu_clk); in cpr_find_initial_corner()
1324 for (iter = drv->corners; iter <= end; iter++) { in cpr_find_initial_corner()
1325 if (iter->freq > rate) in cpr_find_initial_corner()
1328 if (iter->freq == rate) { in cpr_find_initial_corner()
1329 drv->corner = iter; in cpr_find_initial_corner()
1332 if (iter->freq < rate) in cpr_find_initial_corner()
1333 drv->corner = iter; in cpr_find_initial_corner()
1336 if (!drv->corner) { in cpr_find_initial_corner()
1337 dev_err(drv->dev, "boot up corner not found\n"); in cpr_find_initial_corner()
1338 return -EINVAL; in cpr_find_initial_corner()
1341 dev_dbg(drv->dev, "boot up perf state: %u\n", i); in cpr_find_initial_corner()
1385 .quot_adjust = -20,
1451 const struct acc_desc *acc_desc = drv->acc_desc; in cpr_pd_attach_dev()
1454 mutex_lock(&drv->lock); in cpr_pd_attach_dev()
1456 dev_dbg(drv->dev, "attach callback for: %s\n", dev_name(dev)); in cpr_pd_attach_dev()
1465 if (drv->attached_cpu_dev) in cpr_pd_attach_dev()
1477 drv->cpu_clk = devm_clk_get(dev, NULL); in cpr_pd_attach_dev()
1478 if (IS_ERR(drv->cpu_clk)) { in cpr_pd_attach_dev()
1479 ret = PTR_ERR(drv->cpu_clk); in cpr_pd_attach_dev()
1480 if (ret != -EPROBE_DEFER) in cpr_pd_attach_dev()
1481 dev_err(drv->dev, "could not get cpu clk: %d\n", ret); in cpr_pd_attach_dev()
1484 drv->attached_cpu_dev = dev; in cpr_pd_attach_dev()
1486 dev_dbg(drv->dev, "using cpu clk from: %s\n", in cpr_pd_attach_dev()
1487 dev_name(drv->attached_cpu_dev)); in cpr_pd_attach_dev()
1493 * available after the cpufreq driver has attached to us. in cpr_pd_attach_dev()
1497 ret = dev_pm_opp_get_opp_count(&drv->pd.dev); in cpr_pd_attach_dev()
1499 dev_err(drv->dev, "could not get OPP count\n"); in cpr_pd_attach_dev()
1502 drv->num_corners = ret; in cpr_pd_attach_dev()
1504 if (drv->num_corners < 2) { in cpr_pd_attach_dev()
1505 dev_err(drv->dev, "need at least 2 OPPs to use CPR\n"); in cpr_pd_attach_dev()
1506 ret = -EINVAL; in cpr_pd_attach_dev()
1510 drv->corners = devm_kcalloc(drv->dev, drv->num_corners, in cpr_pd_attach_dev()
1511 sizeof(*drv->corners), in cpr_pd_attach_dev()
1513 if (!drv->corners) { in cpr_pd_attach_dev()
1514 ret = -ENOMEM; in cpr_pd_attach_dev()
1537 if (acc_desc->config) in cpr_pd_attach_dev()
1538 regmap_multi_reg_write(drv->tcsr, acc_desc->config, in cpr_pd_attach_dev()
1539 acc_desc->num_regs_per_fuse); in cpr_pd_attach_dev()
1542 if (acc_desc->enable_mask) in cpr_pd_attach_dev()
1543 regmap_update_bits(drv->tcsr, acc_desc->enable_reg, in cpr_pd_attach_dev()
1544 acc_desc->enable_mask, in cpr_pd_attach_dev()
1545 acc_desc->enable_mask); in cpr_pd_attach_dev()
1547 dev_info(drv->dev, "driver initialized with %u OPPs\n", in cpr_pd_attach_dev()
1548 drv->num_corners); in cpr_pd_attach_dev()
1551 mutex_unlock(&drv->lock); in cpr_pd_attach_dev()
1560 struct cpr_drv *drv = s->private; in cpr_debug_info_show()
1564 corner = drv->corner; in cpr_debug_info_show()
1565 fuse_corner = corner->fuse_corner; in cpr_debug_info_show()
1568 corner->last_uV); in cpr_debug_info_show()
1570 ro_sel = fuse_corner->ring_osc_idx; in cpr_debug_info_show()
1608 drv->debugfs = debugfs_create_dir("qcom_cpr", NULL); in cpr_debugfs_init()
1610 debugfs_create_file("debug_info", 0444, drv->debugfs, in cpr_debugfs_init()
1616 struct device *dev = &pdev->dev; in cpr_probe()
1624 if (!data || !data->cpr_desc || !data->acc_desc) in cpr_probe()
1625 return -EINVAL; in cpr_probe()
1629 return -ENOMEM; in cpr_probe()
1630 drv->dev = dev; in cpr_probe()
1631 drv->desc = data->cpr_desc; in cpr_probe()
1632 drv->acc_desc = data->acc_desc; in cpr_probe()
1634 drv->fuse_corners = devm_kcalloc(dev, drv->desc->num_fuse_corners, in cpr_probe()
1635 sizeof(*drv->fuse_corners), in cpr_probe()
1637 if (!drv->fuse_corners) in cpr_probe()
1638 return -ENOMEM; in cpr_probe()
1640 np = of_parse_phandle(dev->of_node, "acc-syscon", 0); in cpr_probe()
1642 return -ENODEV; in cpr_probe()
1644 drv->tcsr = syscon_node_to_regmap(np); in cpr_probe()
1646 if (IS_ERR(drv->tcsr)) in cpr_probe()
1647 return PTR_ERR(drv->tcsr); in cpr_probe()
1649 drv->base = devm_platform_ioremap_resource(pdev, 0); in cpr_probe()
1650 if (IS_ERR(drv->base)) in cpr_probe()
1651 return PTR_ERR(drv->base); in cpr_probe()
1655 return -EINVAL; in cpr_probe()
1657 drv->vdd_apc = devm_regulator_get(dev, "vdd-apc"); in cpr_probe()
1658 if (IS_ERR(drv->vdd_apc)) in cpr_probe()
1659 return PTR_ERR(drv->vdd_apc); in cpr_probe()
1672 drv->cpr_fuses = cpr_get_fuses(drv); in cpr_probe()
1673 if (IS_ERR(drv->cpr_fuses)) in cpr_probe()
1674 return PTR_ERR(drv->cpr_fuses); in cpr_probe()
1684 mutex_init(&drv->lock); in cpr_probe()
1693 drv->pd.name = devm_kstrdup_const(dev, dev->of_node->full_name, in cpr_probe()
1695 if (!drv->pd.name) in cpr_probe()
1696 return -EINVAL; in cpr_probe()
1698 drv->pd.power_off = cpr_power_off; in cpr_probe()
1699 drv->pd.power_on = cpr_power_on; in cpr_probe()
1700 drv->pd.set_performance_state = cpr_set_performance_state; in cpr_probe()
1701 drv->pd.opp_to_performance_state = cpr_get_performance_state; in cpr_probe()
1702 drv->pd.attach_dev = cpr_pd_attach_dev; in cpr_probe()
1704 ret = pm_genpd_init(&drv->pd, NULL, true); in cpr_probe()
1708 ret = of_genpd_add_provider_simple(dev->of_node, &drv->pd); in cpr_probe()
1718 pm_genpd_remove(&drv->pd); in cpr_probe()
1731 of_genpd_del_provider(pdev->dev.of_node); in cpr_remove()
1732 pm_genpd_remove(&drv->pd); in cpr_remove()
1734 debugfs_remove_recursive(drv->debugfs); in cpr_remove()
1740 { .compatible = "qcom,qcs404-cpr", .data = &qcs404_cpr_acc_desc },
1749 .name = "qcom-cpr",