linux/drivers/mtd/spi-nor/otp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * OTP support for SPI NOR flashes
   4 *
   5 * Copyright (C) 2021 Michael Walle <michael@walle.cc>
   6 */
   7
   8#include <linux/log2.h>
   9#include <linux/mtd/mtd.h>
  10#include <linux/mtd/spi-nor.h>
  11
  12#include "core.h"
  13
  14#define spi_nor_otp_region_len(nor) ((nor)->params->otp.org->len)
  15#define spi_nor_otp_n_regions(nor) ((nor)->params->otp.org->n_regions)
  16
  17/**
  18 * spi_nor_otp_read_secr() - read security register
  19 * @nor:        pointer to 'struct spi_nor'
  20 * @addr:       offset to read from
  21 * @len:        number of bytes to read
  22 * @buf:        pointer to dst buffer
  23 *
  24 * Read a security register by using the SPINOR_OP_RSECR commands.
  25 *
  26 * In Winbond/GigaDevice datasheets the term "security register" stands for
  27 * an one-time-programmable memory area, consisting of multiple bytes (usually
  28 * 256). Thus one "security register" maps to one OTP region.
  29 *
  30 * This method is used on GigaDevice and Winbond flashes.
  31 *
  32 * Please note, the read must not span multiple registers.
  33 *
  34 * Return: number of bytes read successfully, -errno otherwise
  35 */
  36int spi_nor_otp_read_secr(struct spi_nor *nor, loff_t addr, size_t len, u8 *buf)
  37{
  38        u8 addr_width, read_opcode, read_dummy;
  39        struct spi_mem_dirmap_desc *rdesc;
  40        enum spi_nor_protocol read_proto;
  41        int ret;
  42
  43        read_opcode = nor->read_opcode;
  44        addr_width = nor->addr_width;
  45        read_dummy = nor->read_dummy;
  46        read_proto = nor->read_proto;
  47        rdesc = nor->dirmap.rdesc;
  48
  49        nor->read_opcode = SPINOR_OP_RSECR;
  50        nor->read_dummy = 8;
  51        nor->read_proto = SNOR_PROTO_1_1_1;
  52        nor->dirmap.rdesc = NULL;
  53
  54        ret = spi_nor_read_data(nor, addr, len, buf);
  55
  56        nor->read_opcode = read_opcode;
  57        nor->addr_width = addr_width;
  58        nor->read_dummy = read_dummy;
  59        nor->read_proto = read_proto;
  60        nor->dirmap.rdesc = rdesc;
  61
  62        return ret;
  63}
  64
  65/**
  66 * spi_nor_otp_write_secr() - write security register
  67 * @nor:        pointer to 'struct spi_nor'
  68 * @addr:       offset to write to
  69 * @len:        number of bytes to write
  70 * @buf:        pointer to src buffer
  71 *
  72 * Write a security register by using the SPINOR_OP_PSECR commands.
  73 *
  74 * For more information on the term "security register", see the documentation
  75 * of spi_nor_otp_read_secr().
  76 *
  77 * This method is used on GigaDevice and Winbond flashes.
  78 *
  79 * Please note, the write must not span multiple registers.
  80 *
  81 * Return: number of bytes written successfully, -errno otherwise
  82 */
  83int spi_nor_otp_write_secr(struct spi_nor *nor, loff_t addr, size_t len,
  84                           const u8 *buf)
  85{
  86        enum spi_nor_protocol write_proto;
  87        struct spi_mem_dirmap_desc *wdesc;
  88        u8 addr_width, program_opcode;
  89        int ret, written;
  90
  91        program_opcode = nor->program_opcode;
  92        addr_width = nor->addr_width;
  93        write_proto = nor->write_proto;
  94        wdesc = nor->dirmap.wdesc;
  95
  96        nor->program_opcode = SPINOR_OP_PSECR;
  97        nor->write_proto = SNOR_PROTO_1_1_1;
  98        nor->dirmap.wdesc = NULL;
  99
 100        /*
 101         * We only support a write to one single page. For now all winbond
 102         * flashes only have one page per security register.
 103         */
 104        ret = spi_nor_write_enable(nor);
 105        if (ret)
 106                goto out;
 107
 108        written = spi_nor_write_data(nor, addr, len, buf);
 109        if (written < 0)
 110                goto out;
 111
 112        ret = spi_nor_wait_till_ready(nor);
 113
 114out:
 115        nor->program_opcode = program_opcode;
 116        nor->addr_width = addr_width;
 117        nor->write_proto = write_proto;
 118        nor->dirmap.wdesc = wdesc;
 119
 120        return ret ?: written;
 121}
 122
 123/**
 124 * spi_nor_otp_erase_secr() - erase a security register
 125 * @nor:        pointer to 'struct spi_nor'
 126 * @addr:       offset of the security register to be erased
 127 *
 128 * Erase a security register by using the SPINOR_OP_ESECR command.
 129 *
 130 * For more information on the term "security register", see the documentation
 131 * of spi_nor_otp_read_secr().
 132 *
 133 * This method is used on GigaDevice and Winbond flashes.
 134 *
 135 * Return: 0 on success, -errno otherwise
 136 */
 137int spi_nor_otp_erase_secr(struct spi_nor *nor, loff_t addr)
 138{
 139        u8 erase_opcode = nor->erase_opcode;
 140        int ret;
 141
 142        ret = spi_nor_write_enable(nor);
 143        if (ret)
 144                return ret;
 145
 146        nor->erase_opcode = SPINOR_OP_ESECR;
 147        ret = spi_nor_erase_sector(nor, addr);
 148        nor->erase_opcode = erase_opcode;
 149        if (ret)
 150                return ret;
 151
 152        return spi_nor_wait_till_ready(nor);
 153}
 154
 155static int spi_nor_otp_lock_bit_cr(unsigned int region)
 156{
 157        static const int lock_bits[] = { SR2_LB1, SR2_LB2, SR2_LB3 };
 158
 159        if (region >= ARRAY_SIZE(lock_bits))
 160                return -EINVAL;
 161
 162        return lock_bits[region];
 163}
 164
 165/**
 166 * spi_nor_otp_lock_sr2() - lock the OTP region
 167 * @nor:        pointer to 'struct spi_nor'
 168 * @region:     OTP region
 169 *
 170 * Lock the OTP region by writing the status register-2. This method is used on
 171 * GigaDevice and Winbond flashes.
 172 *
 173 * Return: 0 on success, -errno otherwise.
 174 */
 175int spi_nor_otp_lock_sr2(struct spi_nor *nor, unsigned int region)
 176{
 177        u8 *cr = nor->bouncebuf;
 178        int ret, lock_bit;
 179
 180        lock_bit = spi_nor_otp_lock_bit_cr(region);
 181        if (lock_bit < 0)
 182                return lock_bit;
 183
 184        ret = spi_nor_read_cr(nor, cr);
 185        if (ret)
 186                return ret;
 187
 188        /* no need to write the register if region is already locked */
 189        if (cr[0] & lock_bit)
 190                return 0;
 191
 192        cr[0] |= lock_bit;
 193
 194        return spi_nor_write_16bit_cr_and_check(nor, cr[0]);
 195}
 196
 197/**
 198 * spi_nor_otp_is_locked_sr2() - get the OTP region lock status
 199 * @nor:        pointer to 'struct spi_nor'
 200 * @region:     OTP region
 201 *
 202 * Retrieve the OTP region lock bit by reading the status register-2. This
 203 * method is used on GigaDevice and Winbond flashes.
 204 *
 205 * Return: 0 on success, -errno otherwise.
 206 */
 207int spi_nor_otp_is_locked_sr2(struct spi_nor *nor, unsigned int region)
 208{
 209        u8 *cr = nor->bouncebuf;
 210        int ret, lock_bit;
 211
 212        lock_bit = spi_nor_otp_lock_bit_cr(region);
 213        if (lock_bit < 0)
 214                return lock_bit;
 215
 216        ret = spi_nor_read_cr(nor, cr);
 217        if (ret)
 218                return ret;
 219
 220        return cr[0] & lock_bit;
 221}
 222
 223static loff_t spi_nor_otp_region_start(const struct spi_nor *nor, unsigned int region)
 224{
 225        const struct spi_nor_otp_organization *org = nor->params->otp.org;
 226
 227        return org->base + region * org->offset;
 228}
 229
 230static size_t spi_nor_otp_size(struct spi_nor *nor)
 231{
 232        return spi_nor_otp_n_regions(nor) * spi_nor_otp_region_len(nor);
 233}
 234
 235/* Translate the file offsets from and to OTP regions. */
 236static loff_t spi_nor_otp_region_to_offset(struct spi_nor *nor, unsigned int region)
 237{
 238        return region * spi_nor_otp_region_len(nor);
 239}
 240
 241static unsigned int spi_nor_otp_offset_to_region(struct spi_nor *nor, loff_t ofs)
 242{
 243        return div64_u64(ofs, spi_nor_otp_region_len(nor));
 244}
 245
 246static int spi_nor_mtd_otp_info(struct mtd_info *mtd, size_t len,
 247                                size_t *retlen, struct otp_info *buf)
 248{
 249        struct spi_nor *nor = mtd_to_spi_nor(mtd);
 250        const struct spi_nor_otp_ops *ops = nor->params->otp.ops;
 251        unsigned int n_regions = spi_nor_otp_n_regions(nor);
 252        unsigned int i;
 253        int ret, locked;
 254
 255        if (len < n_regions * sizeof(*buf))
 256                return -ENOSPC;
 257
 258        ret = spi_nor_lock_and_prep(nor);
 259        if (ret)
 260                return ret;
 261
 262        for (i = 0; i < n_regions; i++) {
 263                buf->start = spi_nor_otp_region_to_offset(nor, i);
 264                buf->length = spi_nor_otp_region_len(nor);
 265
 266                locked = ops->is_locked(nor, i);
 267                if (locked < 0) {
 268                        ret = locked;
 269                        goto out;
 270                }
 271
 272                buf->locked = !!locked;
 273                buf++;
 274        }
 275
 276        *retlen = n_regions * sizeof(*buf);
 277
 278out:
 279        spi_nor_unlock_and_unprep(nor);
 280
 281        return ret;
 282}
 283
 284static int spi_nor_mtd_otp_range_is_locked(struct spi_nor *nor, loff_t ofs,
 285                                           size_t len)
 286{
 287        const struct spi_nor_otp_ops *ops = nor->params->otp.ops;
 288        unsigned int region;
 289        int locked;
 290
 291        /*
 292         * If any of the affected OTP regions are locked the entire range is
 293         * considered locked.
 294         */
 295        for (region = spi_nor_otp_offset_to_region(nor, ofs);
 296             region <= spi_nor_otp_offset_to_region(nor, ofs + len - 1);
 297             region++) {
 298                locked = ops->is_locked(nor, region);
 299                /* take the branch it is locked or in case of an error */
 300                if (locked)
 301                        return locked;
 302        }
 303
 304        return 0;
 305}
 306
 307static int spi_nor_mtd_otp_read_write(struct mtd_info *mtd, loff_t ofs,
 308                                      size_t total_len, size_t *retlen,
 309                                      const u8 *buf, bool is_write)
 310{
 311        struct spi_nor *nor = mtd_to_spi_nor(mtd);
 312        const struct spi_nor_otp_ops *ops = nor->params->otp.ops;
 313        const size_t rlen = spi_nor_otp_region_len(nor);
 314        loff_t rstart, rofs;
 315        unsigned int region;
 316        size_t len;
 317        int ret;
 318
 319        if (ofs < 0 || ofs >= spi_nor_otp_size(nor))
 320                return 0;
 321
 322        /* don't access beyond the end */
 323        total_len = min_t(size_t, total_len, spi_nor_otp_size(nor) - ofs);
 324
 325        if (!total_len)
 326                return 0;
 327
 328        ret = spi_nor_lock_and_prep(nor);
 329        if (ret)
 330                return ret;
 331
 332        if (is_write) {
 333                ret = spi_nor_mtd_otp_range_is_locked(nor, ofs, total_len);
 334                if (ret < 0) {
 335                        goto out;
 336                } else if (ret) {
 337                        ret = -EROFS;
 338                        goto out;
 339                }
 340        }
 341
 342        while (total_len) {
 343                /*
 344                 * The OTP regions are mapped into a contiguous area starting
 345                 * at 0 as expected by the MTD layer. This will map the MTD
 346                 * file offsets to the address of an OTP region as used in the
 347                 * actual SPI commands.
 348                 */
 349                region = spi_nor_otp_offset_to_region(nor, ofs);
 350                rstart = spi_nor_otp_region_start(nor, region);
 351
 352                /*
 353                 * The size of a OTP region is expected to be a power of two,
 354                 * thus we can just mask the lower bits and get the offset into
 355                 * a region.
 356                 */
 357                rofs = ofs & (rlen - 1);
 358
 359                /* don't access beyond one OTP region */
 360                len = min_t(size_t, total_len, rlen - rofs);
 361
 362                if (is_write)
 363                        ret = ops->write(nor, rstart + rofs, len, buf);
 364                else
 365                        ret = ops->read(nor, rstart + rofs, len, (u8 *)buf);
 366                if (ret == 0)
 367                        ret = -EIO;
 368                if (ret < 0)
 369                        goto out;
 370
 371                *retlen += ret;
 372                ofs += ret;
 373                buf += ret;
 374                total_len -= ret;
 375        }
 376        ret = 0;
 377
 378out:
 379        spi_nor_unlock_and_unprep(nor);
 380        return ret;
 381}
 382
 383static int spi_nor_mtd_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
 384                                size_t *retlen, u8 *buf)
 385{
 386        return spi_nor_mtd_otp_read_write(mtd, from, len, retlen, buf, false);
 387}
 388
 389static int spi_nor_mtd_otp_write(struct mtd_info *mtd, loff_t to, size_t len,
 390                                 size_t *retlen, const u8 *buf)
 391{
 392        return spi_nor_mtd_otp_read_write(mtd, to, len, retlen, buf, true);
 393}
 394
 395static int spi_nor_mtd_otp_erase(struct mtd_info *mtd, loff_t from, size_t len)
 396{
 397        struct spi_nor *nor = mtd_to_spi_nor(mtd);
 398        const struct spi_nor_otp_ops *ops = nor->params->otp.ops;
 399        const size_t rlen = spi_nor_otp_region_len(nor);
 400        unsigned int region;
 401        loff_t rstart;
 402        int ret;
 403
 404        /* OTP erase is optional */
 405        if (!ops->erase)
 406                return -EOPNOTSUPP;
 407
 408        if (!len)
 409                return 0;
 410
 411        if (from < 0 || (from + len) > spi_nor_otp_size(nor))
 412                return -EINVAL;
 413
 414        /* the user has to explicitly ask for whole regions */
 415        if (!IS_ALIGNED(len, rlen) || !IS_ALIGNED(from, rlen))
 416                return -EINVAL;
 417
 418        ret = spi_nor_lock_and_prep(nor);
 419        if (ret)
 420                return ret;
 421
 422        ret = spi_nor_mtd_otp_range_is_locked(nor, from, len);
 423        if (ret < 0) {
 424                goto out;
 425        } else if (ret) {
 426                ret = -EROFS;
 427                goto out;
 428        }
 429
 430        while (len) {
 431                region = spi_nor_otp_offset_to_region(nor, from);
 432                rstart = spi_nor_otp_region_start(nor, region);
 433
 434                ret = ops->erase(nor, rstart);
 435                if (ret)
 436                        goto out;
 437
 438                len -= rlen;
 439                from += rlen;
 440        }
 441
 442out:
 443        spi_nor_unlock_and_unprep(nor);
 444
 445        return ret;
 446}
 447
 448static int spi_nor_mtd_otp_lock(struct mtd_info *mtd, loff_t from, size_t len)
 449{
 450        struct spi_nor *nor = mtd_to_spi_nor(mtd);
 451        const struct spi_nor_otp_ops *ops = nor->params->otp.ops;
 452        const size_t rlen = spi_nor_otp_region_len(nor);
 453        unsigned int region;
 454        int ret;
 455
 456        if (from < 0 || (from + len) > spi_nor_otp_size(nor))
 457                return -EINVAL;
 458
 459        /* the user has to explicitly ask for whole regions */
 460        if (!IS_ALIGNED(len, rlen) || !IS_ALIGNED(from, rlen))
 461                return -EINVAL;
 462
 463        ret = spi_nor_lock_and_prep(nor);
 464        if (ret)
 465                return ret;
 466
 467        while (len) {
 468                region = spi_nor_otp_offset_to_region(nor, from);
 469                ret = ops->lock(nor, region);
 470                if (ret)
 471                        goto out;
 472
 473                len -= rlen;
 474                from += rlen;
 475        }
 476
 477out:
 478        spi_nor_unlock_and_unprep(nor);
 479
 480        return ret;
 481}
 482
 483void spi_nor_otp_init(struct spi_nor *nor)
 484{
 485        struct mtd_info *mtd = &nor->mtd;
 486
 487        if (!nor->params->otp.ops)
 488                return;
 489
 490        if (WARN_ON(!is_power_of_2(spi_nor_otp_region_len(nor))))
 491                return;
 492
 493        /*
 494         * We only support user_prot callbacks (yet).
 495         *
 496         * Some SPI NOR flashes like Macronix ones can be ordered in two
 497         * different variants. One with a factory locked OTP area and one where
 498         * it is left to the user to write to it. The factory locked OTP is
 499         * usually preprogrammed with an "electrical serial number". We don't
 500         * support these for now.
 501         */
 502        mtd->_get_user_prot_info = spi_nor_mtd_otp_info;
 503        mtd->_read_user_prot_reg = spi_nor_mtd_otp_read;
 504        mtd->_write_user_prot_reg = spi_nor_mtd_otp_write;
 505        mtd->_lock_user_prot_reg = spi_nor_mtd_otp_lock;
 506        mtd->_erase_user_prot_reg = spi_nor_mtd_otp_erase;
 507}
 508