uboot/drivers/mtd/spi/ramtron.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2010
   3 * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24/*
  25 * Note: RAMTRON SPI FRAMs are ferroelectric, nonvolatile RAMs
  26 * with an interface identical to SPI flash devices.
  27 * However since they behave like RAM there are no delays or
  28 * busy polls required. They can sustain read or write at the
  29 * allowed SPI bus speed, which can be 40 MHz for some devices.
  30 *
  31 * Unfortunately some RAMTRON devices do not have a means of
  32 * identifying them. They will leave the SO line undriven when
  33 * the READ-ID command is issued. It is therefore mandatory
  34 * that the MISO line has a proper pull-up, so that READ-ID
  35 * will return a row of 0xff. This 0xff pseudo-id will cause
  36 * probes by all vendor specific functions that are designed
  37 * to handle it. If the MISO line is not pulled up, READ-ID
  38 * could return any random noise, even mimicking another
  39 * device.
  40 *
  41 * We use CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
  42 * to define which device will be assumed after a simple status
  43 * register verify. This method is prone to false positive
  44 * detection and should therefore be the last to be tried.
  45 * Enter it in the last position in the table in spi_flash.c!
  46 *
  47 * The define CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC both activates
  48 * compilation of the special handler and defines the device
  49 * to assume.
  50 */
  51
  52#include <common.h>
  53#include <malloc.h>
  54#include <spi_flash.h>
  55#include "spi_flash_internal.h"
  56
  57/* RAMTRON commands common to all devices */
  58#define CMD_RAMTRON_WREN        0x06    /* Write Enable */
  59#define CMD_RAMTRON_WRDI        0x04    /* Write Disable */
  60#define CMD_RAMTRON_RDSR        0x05    /* Read Status Register */
  61#define CMD_RAMTRON_WRSR        0x01    /* Write Status Register */
  62#define CMD_RAMTRON_READ        0x03    /* Read Data Bytes */
  63#define CMD_RAMTRON_WRITE       0x02    /* Write Data Bytes */
  64/* not all have those: */
  65#define CMD_RAMTRON_FSTRD       0x0b    /* Fast Read (for compatibility - not used here) */
  66#define CMD_RAMTRON_SLEEP       0xb9    /* Enter Sleep Mode */
  67#define CMD_RAMTRON_RDID        0x9f    /* Read ID */
  68#define CMD_RAMTRON_SNR         0xc3    /* Read Serial Number */
  69
  70/*
  71 * Properties of supported FRAMs
  72 * Note: speed is currently not used because we have no method to deliver that
  73 * value to the upper layers
  74 */
  75struct ramtron_spi_fram_params {
  76        u32     size;           /* size in bytes */
  77        u8      addr_len;       /* number of address bytes */
  78        u8      merge_cmd;      /* some address bits are in the command byte */
  79        u8      id1;            /* device ID 1 (family, density) */
  80        u8      id2;            /* device ID 2 (sub, rev, rsvd) */
  81        u32     speed;          /* max. SPI clock in Hz */
  82        const char *name;       /* name for display and/or matching */
  83};
  84
  85struct ramtron_spi_fram {
  86        struct spi_flash flash;
  87        const struct ramtron_spi_fram_params *params;
  88};
  89
  90static inline struct ramtron_spi_fram *to_ramtron_spi_fram(struct spi_flash
  91                                                             *flash)
  92{
  93        return container_of(flash, struct ramtron_spi_fram, flash);
  94}
  95
  96/*
  97 * table describing supported FRAM chips:
  98 * chips without RDID command must have the values 0xff for id1 and id2
  99 */
 100static const struct ramtron_spi_fram_params ramtron_spi_fram_table[] = {
 101        {
 102                .size = 32*1024,
 103                .addr_len = 2,
 104                .merge_cmd = 0,
 105                .id1 = 0x22,
 106                .id2 = 0x00,
 107                .speed = 40000000,
 108                .name = "FM25V02",
 109        },
 110        {
 111                .size = 32*1024,
 112                .addr_len = 2,
 113                .merge_cmd = 0,
 114                .id1 = 0x22,
 115                .id2 = 0x01,
 116                .speed = 40000000,
 117                .name = "FM25VN02",
 118        },
 119        {
 120                .size = 64*1024,
 121                .addr_len = 2,
 122                .merge_cmd = 0,
 123                .id1 = 0x23,
 124                .id2 = 0x00,
 125                .speed = 40000000,
 126                .name = "FM25V05",
 127        },
 128        {
 129                .size = 64*1024,
 130                .addr_len = 2,
 131                .merge_cmd = 0,
 132                .id1 = 0x23,
 133                .id2 = 0x01,
 134                .speed = 40000000,
 135                .name = "FM25VN05",
 136        },
 137        {
 138                .size = 128*1024,
 139                .addr_len = 3,
 140                .merge_cmd = 0,
 141                .id1 = 0x24,
 142                .id2 = 0x00,
 143                .speed = 40000000,
 144                .name = "FM25V10",
 145        },
 146        {
 147                .size = 128*1024,
 148                .addr_len = 3,
 149                .merge_cmd = 0,
 150                .id1 = 0x24,
 151                .id2 = 0x01,
 152                .speed = 40000000,
 153                .name = "FM25VN10",
 154        },
 155#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
 156        {
 157                .size = 256*1024,
 158                .addr_len = 3,
 159                .merge_cmd = 0,
 160                .id1 = 0xff,
 161                .id2 = 0xff,
 162                .speed = 40000000,
 163                .name = "FM25H20",
 164        },
 165#endif
 166};
 167
 168static int ramtron_common(struct spi_flash *flash,
 169                u32 offset, size_t len, void *buf, u8 command)
 170{
 171        struct ramtron_spi_fram *sn = to_ramtron_spi_fram(flash);
 172        u8 cmd[4];
 173        int cmd_len;
 174        int ret;
 175
 176        if (sn->params->addr_len == 3 && sn->params->merge_cmd == 0) {
 177                cmd[0] = command;
 178                cmd[1] = offset >> 16;
 179                cmd[2] = offset >> 8;
 180                cmd[3] = offset;
 181                cmd_len = 4;
 182        } else if (sn->params->addr_len == 2 && sn->params->merge_cmd == 0) {
 183                cmd[0] = command;
 184                cmd[1] = offset >> 8;
 185                cmd[2] = offset;
 186                cmd_len = 3;
 187        } else {
 188                printf("SF: unsupported addr_len or merge_cmd\n");
 189                return -1;
 190        }
 191
 192        /* claim the bus */
 193        ret = spi_claim_bus(flash->spi);
 194        if (ret) {
 195                debug("SF: Unable to claim SPI bus\n");
 196                return ret;
 197        }
 198
 199        if (command == CMD_RAMTRON_WRITE) {
 200                /* send WREN */
 201                ret = spi_flash_cmd(flash->spi, CMD_RAMTRON_WREN, NULL, 0);
 202                if (ret < 0) {
 203                        debug("SF: Enabling Write failed\n");
 204                        goto releasebus;
 205                }
 206        }
 207
 208        /* do the transaction */
 209        if (command == CMD_RAMTRON_WRITE)
 210                ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, buf, len);
 211        else
 212                ret = spi_flash_cmd_read(flash->spi, cmd, cmd_len, buf, len);
 213        if (ret < 0)
 214                debug("SF: Transaction failed\n");
 215
 216releasebus:
 217        /* release the bus */
 218        spi_release_bus(flash->spi);
 219        return ret;
 220}
 221
 222static int ramtron_read(struct spi_flash *flash,
 223                u32 offset, size_t len, void *buf)
 224{
 225        return ramtron_common(flash, offset, len, buf,
 226                CMD_RAMTRON_READ);
 227}
 228
 229static int ramtron_write(struct spi_flash *flash,
 230                u32 offset, size_t len, const void *buf)
 231{
 232        return ramtron_common(flash, offset, len, (void *)buf,
 233                CMD_RAMTRON_WRITE);
 234}
 235
 236int ramtron_erase(struct spi_flash *flash, u32 offset, size_t len)
 237{
 238        debug("SF: Erase of RAMTRON FRAMs is pointless\n");
 239        return -1;
 240}
 241
 242/*
 243 * nore: we are called here with idcode pointing to the first non-0x7f byte
 244 * already!
 245 */
 246struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
 247{
 248        const struct ramtron_spi_fram_params *params;
 249        struct ramtron_spi_fram *sn;
 250        unsigned int i;
 251#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
 252        int ret;
 253        u8 sr;
 254#endif
 255
 256        /* NOTE: the bus has been claimed before this function is called! */
 257        switch (idcode[0]) {
 258        case 0xc2:
 259                /* JEDEC conformant RAMTRON id */
 260                for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) {
 261                        params = &ramtron_spi_fram_table[i];
 262                        if (idcode[1] == params->id1 && idcode[2] == params->id2)
 263                                goto found;
 264                }
 265                break;
 266#ifdef CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC
 267        case 0xff:
 268                /*
 269                 * probably open MISO line, pulled up.
 270                 * We COULD have a non JEDEC conformant FRAM here,
 271                 * read the status register to verify
 272                 */
 273                ret = spi_flash_cmd(spi, CMD_RAMTRON_RDSR, &sr, 1);
 274                if (ret)
 275                        return NULL;
 276
 277                /* Bits 5,4,0 are fixed 0 for all devices */
 278                if ((sr & 0x31) != 0x00)
 279                        return NULL;
 280                /* now find the device */
 281                for (i = 0; i < ARRAY_SIZE(ramtron_spi_fram_table); i++) {
 282                        params = &ramtron_spi_fram_table[i];
 283                        if (!strcmp(params->name, CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC))
 284                                goto found;
 285                }
 286                debug("SF: Unsupported non-JEDEC RAMTRON device "
 287                        CONFIG_SPI_FRAM_RAMTRON_NON_JEDEC "\n");
 288                break;
 289#endif
 290        default:
 291                break;
 292        }
 293
 294        /* arriving here means no method has found a device we can handle */
 295        debug("SF/ramtron: unsupported device id0=%02x id1=%02x id2=%02x\n",
 296                idcode[0], idcode[1], idcode[2]);
 297        return NULL;
 298
 299found:
 300        sn = malloc(sizeof(*sn));
 301        if (!sn) {
 302                debug("SF: Failed to allocate memory\n");
 303                return NULL;
 304        }
 305
 306        sn->params = params;
 307        sn->flash.spi = spi;
 308        sn->flash.name = params->name;
 309
 310        sn->flash.write = ramtron_write;
 311        sn->flash.read = ramtron_read;
 312        sn->flash.erase = ramtron_erase;
 313        sn->flash.size = params->size;
 314
 315        printf("SF: Detected %s with size ", params->name);
 316        print_size(sn->flash.size, "\n");
 317
 318        return &sn->flash;
 319}
 320