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