Lines Matching +full:efuse +full:- +full:settings

1 // SPDX-License-Identifier: GPL-2.0-only
13 #include <linux/nvmem-provider.h>
23 /* Amount of time required to hold charge to blow fuse in micro-seconds */
44 * struct qfprom_soc_data - config that varies from SoC to SoC.
47 * @qfprom_blow_timer_value: The timer value of qfprom when doing efuse blow.
50 * @qfprom_blow_uV: LDO voltage to be set when doing efuse blow
60 * struct qfprom_priv - structure holding qfprom attributes
62 * @qfpraw: iomapped memory space for qfprom-efuse raw address space.
63 * @qfpconf: iomapped memory space for qfprom-efuse configuration address
84 * struct qfprom_touched_values - saved values to restore after blowing
97 * struct qfprom_soc_compatible_data - Data matched against the SoC
129 * qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
134 * and voltage settings.
144 writel(old->timer_val, priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET); in qfprom_disable_fuse_blowing()
145 writel(old->accel_val, priv->qfpconf + QFPROM_ACCEL_OFFSET); in qfprom_disable_fuse_blowing()
147 dev_pm_genpd_set_performance_state(priv->dev, 0); in qfprom_disable_fuse_blowing()
148 pm_runtime_put(priv->dev); in qfprom_disable_fuse_blowing()
156 ret = regulator_set_voltage(priv->vcc, 0, INT_MAX); in qfprom_disable_fuse_blowing()
158 dev_warn(priv->dev, "Failed to set 0 voltage (ignoring)\n"); in qfprom_disable_fuse_blowing()
160 ret = regulator_disable(priv->vcc); in qfprom_disable_fuse_blowing()
162 dev_warn(priv->dev, "Failed to disable regulator (ignoring)\n"); in qfprom_disable_fuse_blowing()
164 ret = clk_set_rate(priv->secclk, old->clk_rate); in qfprom_disable_fuse_blowing()
166 dev_warn(priv->dev, in qfprom_disable_fuse_blowing()
169 clk_disable_unprepare(priv->secclk); in qfprom_disable_fuse_blowing()
173 * qfprom_enable_fuse_blowing() - Enable fuse blowing.
178 * and voltage settings.
182 * Return: 0 or -err.
188 int qfprom_blow_uV = priv->soc_data->qfprom_blow_uV; in qfprom_enable_fuse_blowing()
190 ret = clk_prepare_enable(priv->secclk); in qfprom_enable_fuse_blowing()
192 dev_err(priv->dev, "Failed to enable clock\n"); in qfprom_enable_fuse_blowing()
196 old->clk_rate = clk_get_rate(priv->secclk); in qfprom_enable_fuse_blowing()
197 ret = clk_set_rate(priv->secclk, priv->soc_data->qfprom_blow_set_freq); in qfprom_enable_fuse_blowing()
199 dev_err(priv->dev, "Failed to set clock rate for enable\n"); in qfprom_enable_fuse_blowing()
208 ret = regulator_set_voltage(priv->vcc, qfprom_blow_uV, INT_MAX); in qfprom_enable_fuse_blowing()
210 dev_err(priv->dev, "Failed to set %duV\n", qfprom_blow_uV); in qfprom_enable_fuse_blowing()
214 ret = regulator_enable(priv->vcc); in qfprom_enable_fuse_blowing()
216 dev_err(priv->dev, "Failed to enable regulator\n"); in qfprom_enable_fuse_blowing()
220 ret = pm_runtime_resume_and_get(priv->dev); in qfprom_enable_fuse_blowing()
222 dev_err(priv->dev, "Failed to enable power-domain\n"); in qfprom_enable_fuse_blowing()
225 dev_pm_genpd_set_performance_state(priv->dev, INT_MAX); in qfprom_enable_fuse_blowing()
227 old->timer_val = readl(priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET); in qfprom_enable_fuse_blowing()
228 old->accel_val = readl(priv->qfpconf + QFPROM_ACCEL_OFFSET); in qfprom_enable_fuse_blowing()
229 writel(priv->soc_data->qfprom_blow_timer_value, in qfprom_enable_fuse_blowing()
230 priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET); in qfprom_enable_fuse_blowing()
231 writel(priv->soc_data->accel_value, in qfprom_enable_fuse_blowing()
232 priv->qfpconf + QFPROM_ACCEL_OFFSET); in qfprom_enable_fuse_blowing()
237 regulator_disable(priv->vcc); in qfprom_enable_fuse_blowing()
239 clk_set_rate(priv->secclk, old->clk_rate); in qfprom_enable_fuse_blowing()
241 clk_disable_unprepare(priv->secclk); in qfprom_enable_fuse_blowing()
246 * qfprom_reg_write() - Write to fuses.
254 * Return: 0 or -err.
267 dev_dbg(priv->dev, in qfprom_reg_write()
277 dev_err(priv->dev, in qfprom_reg_write()
279 return -EINVAL; in qfprom_reg_write()
282 dev_err(priv->dev, in qfprom_reg_write()
284 return -EINVAL; in qfprom_reg_write()
292 priv->qfpconf + QFPROM_BLOW_STATUS_OFFSET, in qfprom_reg_write()
297 dev_err(priv->dev, in qfprom_reg_write()
303 writel(value[i], priv->qfpraw + reg + (i * 4)); in qfprom_reg_write()
306 priv->qfpconf + QFPROM_BLOW_STATUS_OFFSET, in qfprom_reg_write()
312 dev_err(priv->dev, "Timeout waiting for finish.\n"); in qfprom_reg_write()
325 void __iomem *base = priv->qfpcorrected; in qfprom_reg_read()
329 if (read_raw_data && priv->qfpraw) in qfprom_reg_read()
330 base = priv->qfpraw; in qfprom_reg_read()
342 unsigned int byte_offset = cell->offset % sizeof(u32); in qfprom_fixup_dt_cell_info()
344 cell->bit_offset += byte_offset * BITS_PER_BYTE; in qfprom_fixup_dt_cell_info()
345 cell->offset -= byte_offset; in qfprom_fixup_dt_cell_info()
346 if (byte_offset && !cell->nbits) in qfprom_fixup_dt_cell_info()
347 cell->nbits = cell->bytes * BITS_PER_BYTE; in qfprom_fixup_dt_cell_info()
380 struct device *dev = &pdev->dev; in qfprom_probe()
389 return -ENOMEM; in qfprom_probe()
392 priv->qfpcorrected = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in qfprom_probe()
393 if (IS_ERR(priv->qfpcorrected)) in qfprom_probe()
394 return PTR_ERR(priv->qfpcorrected); in qfprom_probe()
400 priv->dev = dev; in qfprom_probe()
403 econfig.keepout = soc_data->keepout; in qfprom_probe()
404 econfig.nkeepout = soc_data->nkeepout; in qfprom_probe()
416 priv->qfpraw = devm_ioremap_resource(dev, res); in qfprom_probe()
417 if (IS_ERR(priv->qfpraw)) in qfprom_probe()
418 return PTR_ERR(priv->qfpraw); in qfprom_probe()
419 priv->qfpconf = devm_platform_ioremap_resource(pdev, 2); in qfprom_probe()
420 if (IS_ERR(priv->qfpconf)) in qfprom_probe()
421 return PTR_ERR(priv->qfpconf); in qfprom_probe()
422 priv->qfpsecurity = devm_platform_ioremap_resource(pdev, 3); in qfprom_probe()
423 if (IS_ERR(priv->qfpsecurity)) in qfprom_probe()
424 return PTR_ERR(priv->qfpsecurity); in qfprom_probe()
426 version = readl(priv->qfpsecurity + QFPROM_VERSION_OFFSET); in qfprom_probe()
433 priv->soc_data = &qfprom_7_8_data; in qfprom_probe()
435 priv->soc_data = &qfprom_7_15_data; in qfprom_probe()
437 priv->vcc = devm_regulator_get(&pdev->dev, "vcc"); in qfprom_probe()
438 if (IS_ERR(priv->vcc)) in qfprom_probe()
439 return PTR_ERR(priv->vcc); in qfprom_probe()
441 priv->secclk = devm_clk_get_optional(dev, "core"); in qfprom_probe()
442 if (IS_ERR(priv->secclk)) in qfprom_probe()
443 return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n"); in qfprom_probe()
446 if (priv->soc_data && priv->secclk) in qfprom_probe()
462 { .compatible = "qcom,sc7180-qfprom", .data = &sc7180_qfprom},
463 { .compatible = "qcom,sc7280-qfprom", .data = &sc7280_qfprom},