^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/nvmem-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Blow timer clock frequency in Mhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define QFPROM_BLOW_TIMER_OFFSET 0x03c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* Amount of time required to hold charge to blow fuse in micro-seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define QFPROM_FUSE_BLOW_POLL_US 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define QFPROM_FUSE_BLOW_TIMEOUT_US 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define QFPROM_BLOW_STATUS_OFFSET 0x048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define QFPROM_BLOW_STATUS_BUSY 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define QFPROM_BLOW_STATUS_READY 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define QFPROM_ACCEL_OFFSET 0x044
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define QFPROM_VERSION_OFFSET 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define QFPROM_MAJOR_VERSION_SHIFT 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define QFPROM_MAJOR_VERSION_MASK GENMASK(31, QFPROM_MAJOR_VERSION_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define QFPROM_MINOR_VERSION_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define QFPROM_MINOR_VERSION_MASK GENMASK(27, QFPROM_MINOR_VERSION_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static bool read_raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) module_param(read_raw_data, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MODULE_PARM_DESC(read_raw_data, "Read raw instead of corrected data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * struct qfprom_soc_data - config that varies from SoC to SoC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @accel_value: Should contain qfprom accel value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @qfprom_blow_timer_value: The timer value of qfprom when doing efuse blow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @qfprom_blow_set_freq: The frequency required to set when we start the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * fuse blowing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct qfprom_soc_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u32 accel_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) u32 qfprom_blow_timer_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u32 qfprom_blow_set_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * struct qfprom_priv - structure holding qfprom attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * @qfpraw: iomapped memory space for qfprom-efuse raw address space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @qfpconf: iomapped memory space for qfprom-efuse configuration address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @qfpcorrected: iomapped memory space for qfprom corrected address space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @qfpsecurity: iomapped memory space for qfprom security control space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * @dev: qfprom device structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @secclk: Clock supply.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * @vcc: Regulator supply.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * @soc_data: Data that for things that varies from SoC to SoC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct qfprom_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) void __iomem *qfpraw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void __iomem *qfpconf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) void __iomem *qfpcorrected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) void __iomem *qfpsecurity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct clk *secclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct regulator *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) const struct qfprom_soc_data *soc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * struct qfprom_touched_values - saved values to restore after blowing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @clk_rate: The rate the clock was at before blowing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * @accel_val: The value of the accel reg before blowing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * @timer_val: The value of the timer before blowing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct qfprom_touched_values {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned long clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u32 accel_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u32 timer_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * @priv: Our driver data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @old: The data that was stashed from before fuse blowing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * Resets the value of the blow timer, accel register and the clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * and voltage settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * Prints messages if there are errors but doesn't return an error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * since there's not much we can do upon failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void qfprom_disable_fuse_blowing(const struct qfprom_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) const struct qfprom_touched_values *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) writel(old->timer_val, priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) writel(old->accel_val, priv->qfpconf + QFPROM_ACCEL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * This may be a shared rail and may be able to run at a lower rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * when we're not blowing fuses. At the moment, the regulator framework
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * applies voltage constraints even on disabled rails, so remove our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * constraints and allow the rail to be adjusted by other users.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ret = regulator_set_voltage(priv->vcc, 0, INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) dev_warn(priv->dev, "Failed to set 0 voltage (ignoring)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ret = regulator_disable(priv->vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) dev_warn(priv->dev, "Failed to disable regulator (ignoring)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ret = clk_set_rate(priv->secclk, old->clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) dev_warn(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) "Failed to set clock rate for disable (ignoring)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) clk_disable_unprepare(priv->secclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * qfprom_enable_fuse_blowing() - Enable fuse blowing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @priv: Our driver data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @old: We'll stash stuff here to use when disabling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Sets the value of the blow timer, accel register and the clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * and voltage settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Prints messages if there are errors so caller doesn't need to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * Return: 0 or -err.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int qfprom_enable_fuse_blowing(const struct qfprom_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct qfprom_touched_values *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ret = clk_prepare_enable(priv->secclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) dev_err(priv->dev, "Failed to enable clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) old->clk_rate = clk_get_rate(priv->secclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ret = clk_set_rate(priv->secclk, priv->soc_data->qfprom_blow_set_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) dev_err(priv->dev, "Failed to set clock rate for enable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) goto err_clk_prepared;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * Hardware requires 1.8V min for fuse blowing; this may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * a rail shared do don't specify a max--regulator constraints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * will handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ret = regulator_set_voltage(priv->vcc, 1800000, INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dev_err(priv->dev, "Failed to set 1.8 voltage\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) goto err_clk_rate_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ret = regulator_enable(priv->vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) dev_err(priv->dev, "Failed to enable regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) goto err_clk_rate_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) old->timer_val = readl(priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) old->accel_val = readl(priv->qfpconf + QFPROM_ACCEL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) writel(priv->soc_data->qfprom_blow_timer_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) writel(priv->soc_data->accel_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) priv->qfpconf + QFPROM_ACCEL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) err_clk_rate_set:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) clk_set_rate(priv->secclk, old->clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) err_clk_prepared:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) clk_disable_unprepare(priv->secclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * qfprom_efuse_reg_write() - Write to fuses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * @context: Our driver data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * @reg: The offset to write at.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * @_val: Pointer to data to write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * @bytes: The number of bytes to write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * Writes to fuses. WARNING: THIS IS PERMANENT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Return: 0 or -err.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int qfprom_reg_write(void *context, unsigned int reg, void *_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) size_t bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct qfprom_priv *priv = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct qfprom_touched_values old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int words = bytes / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u32 *value = _val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u32 blow_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) dev_dbg(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) "Writing to raw qfprom region : %#010x of size: %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) reg, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * The hardware only allows us to write word at a time, but we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * read byte at a time. Until the nvmem framework allows a separate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * word_size and stride for reading vs. writing, we'll enforce here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (bytes % 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev_err(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) "%zu is not an integral number of words\n", bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (reg % 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) dev_err(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) "Invalid offset: %#x. Must be word aligned\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = qfprom_enable_fuse_blowing(priv, &old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ret = readl_relaxed_poll_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) priv->qfpconf + QFPROM_BLOW_STATUS_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) blow_status, blow_status == QFPROM_BLOW_STATUS_READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) QFPROM_FUSE_BLOW_POLL_US, QFPROM_FUSE_BLOW_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) dev_err(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) "Timeout waiting for initial ready; aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) goto exit_enabled_fuse_blowing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) for (i = 0; i < words; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) writel(value[i], priv->qfpraw + reg + (i * 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ret = readl_relaxed_poll_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) priv->qfpconf + QFPROM_BLOW_STATUS_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) blow_status, blow_status == QFPROM_BLOW_STATUS_READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) QFPROM_FUSE_BLOW_POLL_US, QFPROM_FUSE_BLOW_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* Give an error, but not much we can do in this case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dev_err(priv->dev, "Timeout waiting for finish.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) exit_enabled_fuse_blowing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) qfprom_disable_fuse_blowing(priv, &old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static int qfprom_reg_read(void *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) unsigned int reg, void *_val, size_t bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct qfprom_priv *priv = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) u8 *val = _val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int i = 0, words = bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) void __iomem *base = priv->qfpcorrected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (read_raw_data && priv->qfpraw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) base = priv->qfpraw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) while (words--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *val++ = readb(base + reg + i++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static const struct qfprom_soc_data qfprom_7_8_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .accel_value = 0xD10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .qfprom_blow_timer_value = 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .qfprom_blow_set_freq = 4800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int qfprom_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct nvmem_config econfig = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .name = "qfprom",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .stride = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .word_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .id = NVMEM_DEVID_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .reg_read = qfprom_reg_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct nvmem_device *nvmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct qfprom_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* The corrected section is always provided */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) priv->qfpcorrected = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (IS_ERR(priv->qfpcorrected))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return PTR_ERR(priv->qfpcorrected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) econfig.size = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) econfig.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) econfig.priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * If more than one region is provided then the OS has the ability
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * to write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) int major_version, minor_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) priv->qfpraw = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (IS_ERR(priv->qfpraw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return PTR_ERR(priv->qfpraw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) priv->qfpconf = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (IS_ERR(priv->qfpconf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return PTR_ERR(priv->qfpconf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) priv->qfpsecurity = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (IS_ERR(priv->qfpsecurity))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return PTR_ERR(priv->qfpsecurity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) version = readl(priv->qfpsecurity + QFPROM_VERSION_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) major_version = (version & QFPROM_MAJOR_VERSION_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) QFPROM_MAJOR_VERSION_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) minor_version = (version & QFPROM_MINOR_VERSION_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) QFPROM_MINOR_VERSION_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (major_version == 7 && minor_version == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) priv->soc_data = &qfprom_7_8_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (IS_ERR(priv->vcc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return PTR_ERR(priv->vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) priv->secclk = devm_clk_get(dev, "core");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (IS_ERR(priv->secclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ret = PTR_ERR(priv->secclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (ret != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) dev_err(dev, "Error getting clock: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Only enable writing if we have SoC data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (priv->soc_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) econfig.reg_write = qfprom_reg_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) nvmem = devm_nvmem_register(dev, &econfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return PTR_ERR_OR_ZERO(nvmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static const struct of_device_id qfprom_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) { .compatible = "qcom,qfprom",},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {/* sentinel */},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) MODULE_DEVICE_TABLE(of, qfprom_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static struct platform_driver qfprom_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .probe = qfprom_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .name = "qcom,qfprom",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .of_match_table = qfprom_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) module_platform_driver(qfprom_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) MODULE_DESCRIPTION("Qualcomm QFPROM driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) MODULE_LICENSE("GPL v2");