Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
0004  */
0005 
0006 #include <linux/clk.h>
0007 #include <linux/device.h>
0008 #include <linux/io.h>
0009 #include <linux/iopoll.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/mod_devicetable.h>
0013 #include <linux/nvmem-provider.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/pm_domain.h>
0016 #include <linux/pm_runtime.h>
0017 #include <linux/property.h>
0018 #include <linux/regulator/consumer.h>
0019 
0020 /* Blow timer clock frequency in Mhz */
0021 #define QFPROM_BLOW_TIMER_OFFSET 0x03c
0022 
0023 /* Amount of time required to hold charge to blow fuse in micro-seconds */
0024 #define QFPROM_FUSE_BLOW_POLL_US    100
0025 #define QFPROM_FUSE_BLOW_TIMEOUT_US 10000
0026 
0027 #define QFPROM_BLOW_STATUS_OFFSET   0x048
0028 #define QFPROM_BLOW_STATUS_BUSY     0x1
0029 #define QFPROM_BLOW_STATUS_READY    0x0
0030 
0031 #define QFPROM_ACCEL_OFFSET     0x044
0032 
0033 #define QFPROM_VERSION_OFFSET       0x0
0034 #define QFPROM_MAJOR_VERSION_SHIFT  28
0035 #define QFPROM_MAJOR_VERSION_MASK   GENMASK(31, QFPROM_MAJOR_VERSION_SHIFT)
0036 #define QFPROM_MINOR_VERSION_SHIFT  16
0037 #define QFPROM_MINOR_VERSION_MASK   GENMASK(27, QFPROM_MINOR_VERSION_SHIFT)
0038 
0039 static bool read_raw_data;
0040 module_param(read_raw_data, bool, 0644);
0041 MODULE_PARM_DESC(read_raw_data, "Read raw instead of corrected data");
0042 
0043 /**
0044  * struct qfprom_soc_data - config that varies from SoC to SoC.
0045  *
0046  * @accel_value:             Should contain qfprom accel value.
0047  * @qfprom_blow_timer_value: The timer value of qfprom when doing efuse blow.
0048  * @qfprom_blow_set_freq:    The frequency required to set when we start the
0049  *                           fuse blowing.
0050  * @qfprom_blow_uV:          LDO voltage to be set when doing efuse blow
0051  */
0052 struct qfprom_soc_data {
0053     u32 accel_value;
0054     u32 qfprom_blow_timer_value;
0055     u32 qfprom_blow_set_freq;
0056     int qfprom_blow_uV;
0057 };
0058 
0059 /**
0060  * struct qfprom_priv - structure holding qfprom attributes
0061  *
0062  * @qfpraw:       iomapped memory space for qfprom-efuse raw address space.
0063  * @qfpconf:      iomapped memory space for qfprom-efuse configuration address
0064  *                space.
0065  * @qfpcorrected: iomapped memory space for qfprom corrected address space.
0066  * @qfpsecurity:  iomapped memory space for qfprom security control space.
0067  * @dev:          qfprom device structure.
0068  * @secclk:       Clock supply.
0069  * @vcc:          Regulator supply.
0070  * @soc_data:     Data that for things that varies from SoC to SoC.
0071  */
0072 struct qfprom_priv {
0073     void __iomem *qfpraw;
0074     void __iomem *qfpconf;
0075     void __iomem *qfpcorrected;
0076     void __iomem *qfpsecurity;
0077     struct device *dev;
0078     struct clk *secclk;
0079     struct regulator *vcc;
0080     const struct qfprom_soc_data *soc_data;
0081 };
0082 
0083 /**
0084  * struct qfprom_touched_values - saved values to restore after blowing
0085  *
0086  * @clk_rate: The rate the clock was at before blowing.
0087  * @accel_val: The value of the accel reg before blowing.
0088  * @timer_val: The value of the timer before blowing.
0089  */
0090 struct qfprom_touched_values {
0091     unsigned long clk_rate;
0092     u32 accel_val;
0093     u32 timer_val;
0094 };
0095 
0096 /**
0097  * struct qfprom_soc_compatible_data - Data matched against the SoC
0098  * compatible string.
0099  *
0100  * @keepout: Array of keepout regions for this SoC.
0101  * @nkeepout: Number of elements in the keepout array.
0102  */
0103 struct qfprom_soc_compatible_data {
0104     const struct nvmem_keepout *keepout;
0105     unsigned int nkeepout;
0106 };
0107 
0108 static const struct nvmem_keepout sc7180_qfprom_keepout[] = {
0109     {.start = 0x128, .end = 0x148},
0110     {.start = 0x220, .end = 0x228}
0111 };
0112 
0113 static const struct qfprom_soc_compatible_data sc7180_qfprom = {
0114     .keepout = sc7180_qfprom_keepout,
0115     .nkeepout = ARRAY_SIZE(sc7180_qfprom_keepout)
0116 };
0117 
0118 static const struct nvmem_keepout sc7280_qfprom_keepout[] = {
0119     {.start = 0x128, .end = 0x148},
0120     {.start = 0x238, .end = 0x248}
0121 };
0122 
0123 static const struct qfprom_soc_compatible_data sc7280_qfprom = {
0124     .keepout = sc7280_qfprom_keepout,
0125     .nkeepout = ARRAY_SIZE(sc7280_qfprom_keepout)
0126 };
0127 
0128 /**
0129  * qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
0130  * @priv: Our driver data.
0131  * @old:  The data that was stashed from before fuse blowing.
0132  *
0133  * Resets the value of the blow timer, accel register and the clock
0134  * and voltage settings.
0135  *
0136  * Prints messages if there are errors but doesn't return an error code
0137  * since there's not much we can do upon failure.
0138  */
0139 static void qfprom_disable_fuse_blowing(const struct qfprom_priv *priv,
0140                     const struct qfprom_touched_values *old)
0141 {
0142     int ret;
0143 
0144     writel(old->timer_val, priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
0145     writel(old->accel_val, priv->qfpconf + QFPROM_ACCEL_OFFSET);
0146 
0147     dev_pm_genpd_set_performance_state(priv->dev, 0);
0148     pm_runtime_put(priv->dev);
0149 
0150     /*
0151      * This may be a shared rail and may be able to run at a lower rate
0152      * when we're not blowing fuses.  At the moment, the regulator framework
0153      * applies voltage constraints even on disabled rails, so remove our
0154      * constraints and allow the rail to be adjusted by other users.
0155      */
0156     ret = regulator_set_voltage(priv->vcc, 0, INT_MAX);
0157     if (ret)
0158         dev_warn(priv->dev, "Failed to set 0 voltage (ignoring)\n");
0159 
0160     ret = regulator_disable(priv->vcc);
0161     if (ret)
0162         dev_warn(priv->dev, "Failed to disable regulator (ignoring)\n");
0163 
0164     ret = clk_set_rate(priv->secclk, old->clk_rate);
0165     if (ret)
0166         dev_warn(priv->dev,
0167              "Failed to set clock rate for disable (ignoring)\n");
0168 
0169     clk_disable_unprepare(priv->secclk);
0170 }
0171 
0172 /**
0173  * qfprom_enable_fuse_blowing() - Enable fuse blowing.
0174  * @priv: Our driver data.
0175  * @old:  We'll stash stuff here to use when disabling.
0176  *
0177  * Sets the value of the blow timer, accel register and the clock
0178  * and voltage settings.
0179  *
0180  * Prints messages if there are errors so caller doesn't need to.
0181  *
0182  * Return: 0 or -err.
0183  */
0184 static int qfprom_enable_fuse_blowing(const struct qfprom_priv *priv,
0185                       struct qfprom_touched_values *old)
0186 {
0187     int ret;
0188     int qfprom_blow_uV = priv->soc_data->qfprom_blow_uV;
0189 
0190     ret = clk_prepare_enable(priv->secclk);
0191     if (ret) {
0192         dev_err(priv->dev, "Failed to enable clock\n");
0193         return ret;
0194     }
0195 
0196     old->clk_rate = clk_get_rate(priv->secclk);
0197     ret = clk_set_rate(priv->secclk, priv->soc_data->qfprom_blow_set_freq);
0198     if (ret) {
0199         dev_err(priv->dev, "Failed to set clock rate for enable\n");
0200         goto err_clk_prepared;
0201     }
0202 
0203     /*
0204      * Hardware requires a minimum voltage for fuse blowing.
0205      * This may be a shared rail so don't specify a maximum.
0206      * Regulator constraints will cap to the actual maximum.
0207      */
0208     ret = regulator_set_voltage(priv->vcc, qfprom_blow_uV, INT_MAX);
0209     if (ret) {
0210         dev_err(priv->dev, "Failed to set %duV\n", qfprom_blow_uV);
0211         goto err_clk_rate_set;
0212     }
0213 
0214     ret = regulator_enable(priv->vcc);
0215     if (ret) {
0216         dev_err(priv->dev, "Failed to enable regulator\n");
0217         goto err_clk_rate_set;
0218     }
0219 
0220     ret = pm_runtime_resume_and_get(priv->dev);
0221     if (ret < 0) {
0222         dev_err(priv->dev, "Failed to enable power-domain\n");
0223         goto err_reg_enable;
0224     }
0225     dev_pm_genpd_set_performance_state(priv->dev, INT_MAX);
0226 
0227     old->timer_val = readl(priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
0228     old->accel_val = readl(priv->qfpconf + QFPROM_ACCEL_OFFSET);
0229     writel(priv->soc_data->qfprom_blow_timer_value,
0230            priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
0231     writel(priv->soc_data->accel_value,
0232            priv->qfpconf + QFPROM_ACCEL_OFFSET);
0233 
0234     return 0;
0235 
0236 err_reg_enable:
0237     regulator_disable(priv->vcc);
0238 err_clk_rate_set:
0239     clk_set_rate(priv->secclk, old->clk_rate);
0240 err_clk_prepared:
0241     clk_disable_unprepare(priv->secclk);
0242     return ret;
0243 }
0244 
0245 /**
0246  * qfprom_reg_write() - Write to fuses.
0247  * @context: Our driver data.
0248  * @reg:     The offset to write at.
0249  * @_val:    Pointer to data to write.
0250  * @bytes:   The number of bytes to write.
0251  *
0252  * Writes to fuses.  WARNING: THIS IS PERMANENT.
0253  *
0254  * Return: 0 or -err.
0255  */
0256 static int qfprom_reg_write(void *context, unsigned int reg, void *_val,
0257                 size_t bytes)
0258 {
0259     struct qfprom_priv *priv = context;
0260     struct qfprom_touched_values old;
0261     int words = bytes / 4;
0262     u32 *value = _val;
0263     u32 blow_status;
0264     int ret;
0265     int i;
0266 
0267     dev_dbg(priv->dev,
0268         "Writing to raw qfprom region : %#010x of size: %zu\n",
0269         reg, bytes);
0270 
0271     /*
0272      * The hardware only allows us to write word at a time, but we can
0273      * read byte at a time.  Until the nvmem framework allows a separate
0274      * word_size and stride for reading vs. writing, we'll enforce here.
0275      */
0276     if (bytes % 4) {
0277         dev_err(priv->dev,
0278             "%zu is not an integral number of words\n", bytes);
0279         return -EINVAL;
0280     }
0281     if (reg % 4) {
0282         dev_err(priv->dev,
0283             "Invalid offset: %#x.  Must be word aligned\n", reg);
0284         return -EINVAL;
0285     }
0286 
0287     ret = qfprom_enable_fuse_blowing(priv, &old);
0288     if (ret)
0289         return ret;
0290 
0291     ret = readl_relaxed_poll_timeout(
0292         priv->qfpconf + QFPROM_BLOW_STATUS_OFFSET,
0293         blow_status, blow_status == QFPROM_BLOW_STATUS_READY,
0294         QFPROM_FUSE_BLOW_POLL_US, QFPROM_FUSE_BLOW_TIMEOUT_US);
0295 
0296     if (ret) {
0297         dev_err(priv->dev,
0298             "Timeout waiting for initial ready; aborting.\n");
0299         goto exit_enabled_fuse_blowing;
0300     }
0301 
0302     for (i = 0; i < words; i++)
0303         writel(value[i], priv->qfpraw + reg + (i * 4));
0304 
0305     ret = readl_relaxed_poll_timeout(
0306         priv->qfpconf + QFPROM_BLOW_STATUS_OFFSET,
0307         blow_status, blow_status == QFPROM_BLOW_STATUS_READY,
0308         QFPROM_FUSE_BLOW_POLL_US, QFPROM_FUSE_BLOW_TIMEOUT_US);
0309 
0310     /* Give an error, but not much we can do in this case */
0311     if (ret)
0312         dev_err(priv->dev, "Timeout waiting for finish.\n");
0313 
0314 exit_enabled_fuse_blowing:
0315     qfprom_disable_fuse_blowing(priv, &old);
0316 
0317     return ret;
0318 }
0319 
0320 static int qfprom_reg_read(void *context,
0321             unsigned int reg, void *_val, size_t bytes)
0322 {
0323     struct qfprom_priv *priv = context;
0324     u8 *val = _val;
0325     int i = 0, words = bytes;
0326     void __iomem *base = priv->qfpcorrected;
0327 
0328     if (read_raw_data && priv->qfpraw)
0329         base = priv->qfpraw;
0330 
0331     while (words--)
0332         *val++ = readb(base + reg + i++);
0333 
0334     return 0;
0335 }
0336 
0337 static void qfprom_runtime_disable(void *data)
0338 {
0339     pm_runtime_disable(data);
0340 }
0341 
0342 static const struct qfprom_soc_data qfprom_7_8_data = {
0343     .accel_value = 0xD10,
0344     .qfprom_blow_timer_value = 25,
0345     .qfprom_blow_set_freq = 4800000,
0346     .qfprom_blow_uV = 1800000,
0347 };
0348 
0349 static const struct qfprom_soc_data qfprom_7_15_data = {
0350     .accel_value = 0xD08,
0351     .qfprom_blow_timer_value = 24,
0352     .qfprom_blow_set_freq = 4800000,
0353     .qfprom_blow_uV = 1900000,
0354 };
0355 
0356 static int qfprom_probe(struct platform_device *pdev)
0357 {
0358     struct nvmem_config econfig = {
0359         .name = "qfprom",
0360         .stride = 1,
0361         .word_size = 1,
0362         .id = NVMEM_DEVID_AUTO,
0363         .reg_read = qfprom_reg_read,
0364     };
0365     struct device *dev = &pdev->dev;
0366     struct resource *res;
0367     struct nvmem_device *nvmem;
0368     const struct qfprom_soc_compatible_data *soc_data;
0369     struct qfprom_priv *priv;
0370     int ret;
0371 
0372     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0373     if (!priv)
0374         return -ENOMEM;
0375 
0376     /* The corrected section is always provided */
0377     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0378     priv->qfpcorrected = devm_ioremap_resource(dev, res);
0379     if (IS_ERR(priv->qfpcorrected))
0380         return PTR_ERR(priv->qfpcorrected);
0381 
0382     econfig.size = resource_size(res);
0383     econfig.dev = dev;
0384     econfig.priv = priv;
0385 
0386     priv->dev = dev;
0387     soc_data = device_get_match_data(dev);
0388     if (soc_data) {
0389         econfig.keepout = soc_data->keepout;
0390         econfig.nkeepout = soc_data->nkeepout;
0391     }
0392 
0393     /*
0394      * If more than one region is provided then the OS has the ability
0395      * to write.
0396      */
0397     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
0398     if (res) {
0399         u32 version;
0400         int major_version, minor_version;
0401 
0402         priv->qfpraw = devm_ioremap_resource(dev, res);
0403         if (IS_ERR(priv->qfpraw))
0404             return PTR_ERR(priv->qfpraw);
0405         res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
0406         priv->qfpconf = devm_ioremap_resource(dev, res);
0407         if (IS_ERR(priv->qfpconf))
0408             return PTR_ERR(priv->qfpconf);
0409         res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
0410         priv->qfpsecurity = devm_ioremap_resource(dev, res);
0411         if (IS_ERR(priv->qfpsecurity))
0412             return PTR_ERR(priv->qfpsecurity);
0413 
0414         version = readl(priv->qfpsecurity + QFPROM_VERSION_OFFSET);
0415         major_version = (version & QFPROM_MAJOR_VERSION_MASK) >>
0416                 QFPROM_MAJOR_VERSION_SHIFT;
0417         minor_version = (version & QFPROM_MINOR_VERSION_MASK) >>
0418                 QFPROM_MINOR_VERSION_SHIFT;
0419 
0420         if (major_version == 7 && minor_version == 8)
0421             priv->soc_data = &qfprom_7_8_data;
0422         else if (major_version == 7 && minor_version == 15)
0423             priv->soc_data = &qfprom_7_15_data;
0424 
0425         priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
0426         if (IS_ERR(priv->vcc))
0427             return PTR_ERR(priv->vcc);
0428 
0429         priv->secclk = devm_clk_get(dev, "core");
0430         if (IS_ERR(priv->secclk)) {
0431             ret = PTR_ERR(priv->secclk);
0432             if (ret != -EPROBE_DEFER)
0433                 dev_err(dev, "Error getting clock: %d\n", ret);
0434             return ret;
0435         }
0436 
0437         /* Only enable writing if we have SoC data. */
0438         if (priv->soc_data)
0439             econfig.reg_write = qfprom_reg_write;
0440     }
0441 
0442     pm_runtime_enable(dev);
0443     ret = devm_add_action_or_reset(dev, qfprom_runtime_disable, dev);
0444     if (ret)
0445         return ret;
0446 
0447     nvmem = devm_nvmem_register(dev, &econfig);
0448 
0449     return PTR_ERR_OR_ZERO(nvmem);
0450 }
0451 
0452 static const struct of_device_id qfprom_of_match[] = {
0453     { .compatible = "qcom,qfprom",},
0454     { .compatible = "qcom,sc7180-qfprom", .data = &sc7180_qfprom},
0455     { .compatible = "qcom,sc7280-qfprom", .data = &sc7280_qfprom},
0456     {/* sentinel */},
0457 };
0458 MODULE_DEVICE_TABLE(of, qfprom_of_match);
0459 
0460 static struct platform_driver qfprom_driver = {
0461     .probe = qfprom_probe,
0462     .driver = {
0463         .name = "qcom,qfprom",
0464         .of_match_table = qfprom_of_match,
0465     },
0466 };
0467 module_platform_driver(qfprom_driver);
0468 MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>");
0469 MODULE_DESCRIPTION("Qualcomm QFPROM driver");
0470 MODULE_LICENSE("GPL v2");