linux/arch/powerpc/platforms/powermac/nvram.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org)
   4 *
   5 *  Todo: - add support for the OF persistent properties
   6 */
   7#include <linux/export.h>
   8#include <linux/kernel.h>
   9#include <linux/stddef.h>
  10#include <linux/string.h>
  11#include <linux/nvram.h>
  12#include <linux/init.h>
  13#include <linux/delay.h>
  14#include <linux/errno.h>
  15#include <linux/adb.h>
  16#include <linux/pmu.h>
  17#include <linux/memblock.h>
  18#include <linux/completion.h>
  19#include <linux/spinlock.h>
  20#include <asm/sections.h>
  21#include <asm/io.h>
  22#include <asm/prom.h>
  23#include <asm/machdep.h>
  24#include <asm/nvram.h>
  25
  26#include "pmac.h"
  27
  28#define DEBUG
  29
  30#ifdef DEBUG
  31#define DBG(x...) printk(x)
  32#else
  33#define DBG(x...)
  34#endif
  35
  36#define NVRAM_SIZE              0x2000  /* 8kB of non-volatile RAM */
  37
  38#define CORE99_SIGNATURE        0x5a
  39#define CORE99_ADLER_START      0x14
  40
  41/* On Core99, nvram is either a sharp, a micron or an AMD flash */
  42#define SM_FLASH_STATUS_DONE    0x80
  43#define SM_FLASH_STATUS_ERR     0x38
  44
  45#define SM_FLASH_CMD_ERASE_CONFIRM      0xd0
  46#define SM_FLASH_CMD_ERASE_SETUP        0x20
  47#define SM_FLASH_CMD_RESET              0xff
  48#define SM_FLASH_CMD_WRITE_SETUP        0x40
  49#define SM_FLASH_CMD_CLEAR_STATUS       0x50
  50#define SM_FLASH_CMD_READ_STATUS        0x70
  51
  52/* CHRP NVRAM header */
  53struct chrp_header {
  54  u8            signature;
  55  u8            cksum;
  56  u16           len;
  57  char          name[12];
  58  u8            data[];
  59};
  60
  61struct core99_header {
  62  struct chrp_header    hdr;
  63  u32                   adler;
  64  u32                   generation;
  65  u32                   reserved[2];
  66};
  67
  68/*
  69 * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
  70 */
  71static int nvram_naddrs;
  72static volatile unsigned char __iomem *nvram_data;
  73static int is_core_99;
  74static int core99_bank = 0;
  75static int nvram_partitions[3];
  76// XXX Turn that into a sem
  77static DEFINE_RAW_SPINLOCK(nv_lock);
  78
  79static int (*core99_write_bank)(int bank, u8* datas);
  80static int (*core99_erase_bank)(int bank);
  81
  82static char *nvram_image;
  83
  84
  85static unsigned char core99_nvram_read_byte(int addr)
  86{
  87        if (nvram_image == NULL)
  88                return 0xff;
  89        return nvram_image[addr];
  90}
  91
  92static void core99_nvram_write_byte(int addr, unsigned char val)
  93{
  94        if (nvram_image == NULL)
  95                return;
  96        nvram_image[addr] = val;
  97}
  98
  99static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index)
 100{
 101        int i;
 102
 103        if (nvram_image == NULL)
 104                return -ENODEV;
 105        if (*index > NVRAM_SIZE)
 106                return 0;
 107
 108        i = *index;
 109        if (i + count > NVRAM_SIZE)
 110                count = NVRAM_SIZE - i;
 111
 112        memcpy(buf, &nvram_image[i], count);
 113        *index = i + count;
 114        return count;
 115}
 116
 117static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index)
 118{
 119        int i;
 120
 121        if (nvram_image == NULL)
 122                return -ENODEV;
 123        if (*index > NVRAM_SIZE)
 124                return 0;
 125
 126        i = *index;
 127        if (i + count > NVRAM_SIZE)
 128                count = NVRAM_SIZE - i;
 129
 130        memcpy(&nvram_image[i], buf, count);
 131        *index = i + count;
 132        return count;
 133}
 134
 135static ssize_t core99_nvram_size(void)
 136{
 137        if (nvram_image == NULL)
 138                return -ENODEV;
 139        return NVRAM_SIZE;
 140}
 141
 142#ifdef CONFIG_PPC32
 143static volatile unsigned char __iomem *nvram_addr;
 144static int nvram_mult;
 145
 146static ssize_t ppc32_nvram_size(void)
 147{
 148        return NVRAM_SIZE;
 149}
 150
 151static unsigned char direct_nvram_read_byte(int addr)
 152{
 153        return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
 154}
 155
 156static void direct_nvram_write_byte(int addr, unsigned char val)
 157{
 158        out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
 159}
 160
 161
 162static unsigned char indirect_nvram_read_byte(int addr)
 163{
 164        unsigned char val;
 165        unsigned long flags;
 166
 167        raw_spin_lock_irqsave(&nv_lock, flags);
 168        out_8(nvram_addr, addr >> 5);
 169        val = in_8(&nvram_data[(addr & 0x1f) << 4]);
 170        raw_spin_unlock_irqrestore(&nv_lock, flags);
 171
 172        return val;
 173}
 174
 175static void indirect_nvram_write_byte(int addr, unsigned char val)
 176{
 177        unsigned long flags;
 178
 179        raw_spin_lock_irqsave(&nv_lock, flags);
 180        out_8(nvram_addr, addr >> 5);
 181        out_8(&nvram_data[(addr & 0x1f) << 4], val);
 182        raw_spin_unlock_irqrestore(&nv_lock, flags);
 183}
 184
 185
 186#ifdef CONFIG_ADB_PMU
 187
 188static void pmu_nvram_complete(struct adb_request *req)
 189{
 190        if (req->arg)
 191                complete((struct completion *)req->arg);
 192}
 193
 194static unsigned char pmu_nvram_read_byte(int addr)
 195{
 196        struct adb_request req;
 197        DECLARE_COMPLETION_ONSTACK(req_complete);
 198        
 199        req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
 200        if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
 201                        (addr >> 8) & 0xff, addr & 0xff))
 202                return 0xff;
 203        if (system_state == SYSTEM_RUNNING)
 204                wait_for_completion(&req_complete);
 205        while (!req.complete)
 206                pmu_poll();
 207        return req.reply[0];
 208}
 209
 210static void pmu_nvram_write_byte(int addr, unsigned char val)
 211{
 212        struct adb_request req;
 213        DECLARE_COMPLETION_ONSTACK(req_complete);
 214        
 215        req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
 216        if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
 217                        (addr >> 8) & 0xff, addr & 0xff, val))
 218                return;
 219        if (system_state == SYSTEM_RUNNING)
 220                wait_for_completion(&req_complete);
 221        while (!req.complete)
 222                pmu_poll();
 223}
 224
 225#endif /* CONFIG_ADB_PMU */
 226#endif /* CONFIG_PPC32 */
 227
 228static u8 chrp_checksum(struct chrp_header* hdr)
 229{
 230        u8 *ptr;
 231        u16 sum = hdr->signature;
 232        for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
 233                sum += *ptr;
 234        while (sum > 0xFF)
 235                sum = (sum & 0xFF) + (sum>>8);
 236        return sum;
 237}
 238
 239static u32 core99_calc_adler(u8 *buffer)
 240{
 241        int cnt;
 242        u32 low, high;
 243
 244        buffer += CORE99_ADLER_START;
 245        low = 1;
 246        high = 0;
 247        for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
 248                if ((cnt % 5000) == 0) {
 249                        high  %= 65521UL;
 250                        high %= 65521UL;
 251                }
 252                low += buffer[cnt];
 253                high += low;
 254        }
 255        low  %= 65521UL;
 256        high %= 65521UL;
 257
 258        return (high << 16) | low;
 259}
 260
 261static u32 core99_check(u8* datas)
 262{
 263        struct core99_header* hdr99 = (struct core99_header*)datas;
 264
 265        if (hdr99->hdr.signature != CORE99_SIGNATURE) {
 266                DBG("Invalid signature\n");
 267                return 0;
 268        }
 269        if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
 270                DBG("Invalid checksum\n");
 271                return 0;
 272        }
 273        if (hdr99->adler != core99_calc_adler(datas)) {
 274                DBG("Invalid adler\n");
 275                return 0;
 276        }
 277        return hdr99->generation;
 278}
 279
 280static int sm_erase_bank(int bank)
 281{
 282        int stat;
 283        unsigned long timeout;
 284
 285        u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
 286
 287        DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
 288
 289        out_8(base, SM_FLASH_CMD_ERASE_SETUP);
 290        out_8(base, SM_FLASH_CMD_ERASE_CONFIRM);
 291        timeout = 0;
 292        do {
 293                if (++timeout > 1000000) {
 294                        printk(KERN_ERR "nvram: Sharp/Micron flash erase timeout !\n");
 295                        break;
 296                }
 297                out_8(base, SM_FLASH_CMD_READ_STATUS);
 298                stat = in_8(base);
 299        } while (!(stat & SM_FLASH_STATUS_DONE));
 300
 301        out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
 302        out_8(base, SM_FLASH_CMD_RESET);
 303
 304        if (memchr_inv(base, 0xff, NVRAM_SIZE)) {
 305                printk(KERN_ERR "nvram: Sharp/Micron flash erase failed !\n");
 306                return -ENXIO;
 307        }
 308        return 0;
 309}
 310
 311static int sm_write_bank(int bank, u8* datas)
 312{
 313        int i, stat = 0;
 314        unsigned long timeout;
 315
 316        u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
 317
 318        DBG("nvram: Sharp/Micron Writing bank %d...\n", bank);
 319
 320        for (i=0; i<NVRAM_SIZE; i++) {
 321                out_8(base+i, SM_FLASH_CMD_WRITE_SETUP);
 322                udelay(1);
 323                out_8(base+i, datas[i]);
 324                timeout = 0;
 325                do {
 326                        if (++timeout > 1000000) {
 327                                printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n");
 328                                break;
 329                        }
 330                        out_8(base, SM_FLASH_CMD_READ_STATUS);
 331                        stat = in_8(base);
 332                } while (!(stat & SM_FLASH_STATUS_DONE));
 333                if (!(stat & SM_FLASH_STATUS_DONE))
 334                        break;
 335        }
 336        out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
 337        out_8(base, SM_FLASH_CMD_RESET);
 338        if (memcmp(base, datas, NVRAM_SIZE)) {
 339                printk(KERN_ERR "nvram: Sharp/Micron flash write failed !\n");
 340                return -ENXIO;
 341        }
 342        return 0;
 343}
 344
 345static int amd_erase_bank(int bank)
 346{
 347        int stat = 0;
 348        unsigned long timeout;
 349
 350        u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
 351
 352        DBG("nvram: AMD Erasing bank %d...\n", bank);
 353
 354        /* Unlock 1 */
 355        out_8(base+0x555, 0xaa);
 356        udelay(1);
 357        /* Unlock 2 */
 358        out_8(base+0x2aa, 0x55);
 359        udelay(1);
 360
 361        /* Sector-Erase */
 362        out_8(base+0x555, 0x80);
 363        udelay(1);
 364        out_8(base+0x555, 0xaa);
 365        udelay(1);
 366        out_8(base+0x2aa, 0x55);
 367        udelay(1);
 368        out_8(base, 0x30);
 369        udelay(1);
 370
 371        timeout = 0;
 372        do {
 373                if (++timeout > 1000000) {
 374                        printk(KERN_ERR "nvram: AMD flash erase timeout !\n");
 375                        break;
 376                }
 377                stat = in_8(base) ^ in_8(base);
 378        } while (stat != 0);
 379        
 380        /* Reset */
 381        out_8(base, 0xf0);
 382        udelay(1);
 383
 384        if (memchr_inv(base, 0xff, NVRAM_SIZE)) {
 385                printk(KERN_ERR "nvram: AMD flash erase failed !\n");
 386                return -ENXIO;
 387        }
 388        return 0;
 389}
 390
 391static int amd_write_bank(int bank, u8* datas)
 392{
 393        int i, stat = 0;
 394        unsigned long timeout;
 395
 396        u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
 397
 398        DBG("nvram: AMD Writing bank %d...\n", bank);
 399
 400        for (i=0; i<NVRAM_SIZE; i++) {
 401                /* Unlock 1 */
 402                out_8(base+0x555, 0xaa);
 403                udelay(1);
 404                /* Unlock 2 */
 405                out_8(base+0x2aa, 0x55);
 406                udelay(1);
 407
 408                /* Write single word */
 409                out_8(base+0x555, 0xa0);
 410                udelay(1);
 411                out_8(base+i, datas[i]);
 412                
 413                timeout = 0;
 414                do {
 415                        if (++timeout > 1000000) {
 416                                printk(KERN_ERR "nvram: AMD flash write timeout !\n");
 417                                break;
 418                        }
 419                        stat = in_8(base) ^ in_8(base);
 420                } while (stat != 0);
 421                if (stat != 0)
 422                        break;
 423        }
 424
 425        /* Reset */
 426        out_8(base, 0xf0);
 427        udelay(1);
 428
 429        if (memcmp(base, datas, NVRAM_SIZE)) {
 430                printk(KERN_ERR "nvram: AMD flash write failed !\n");
 431                return -ENXIO;
 432        }
 433        return 0;
 434}
 435
 436static void __init lookup_partitions(void)
 437{
 438        u8 buffer[17];
 439        int i, offset;
 440        struct chrp_header* hdr;
 441
 442        if (pmac_newworld) {
 443                nvram_partitions[pmac_nvram_OF] = -1;
 444                nvram_partitions[pmac_nvram_XPRAM] = -1;
 445                nvram_partitions[pmac_nvram_NR] = -1;
 446                hdr = (struct chrp_header *)buffer;
 447
 448                offset = 0;
 449                buffer[16] = 0;
 450                do {
 451                        for (i=0;i<16;i++)
 452                                buffer[i] = ppc_md.nvram_read_val(offset+i);
 453                        if (!strcmp(hdr->name, "common"))
 454                                nvram_partitions[pmac_nvram_OF] = offset + 0x10;
 455                        if (!strcmp(hdr->name, "APL,MacOS75")) {
 456                                nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
 457                                nvram_partitions[pmac_nvram_NR] = offset + 0x110;
 458                        }
 459                        offset += (hdr->len * 0x10);
 460                } while(offset < NVRAM_SIZE);
 461        } else {
 462                nvram_partitions[pmac_nvram_OF] = 0x1800;
 463                nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
 464                nvram_partitions[pmac_nvram_NR] = 0x1400;
 465        }
 466        DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
 467        DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
 468        DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
 469}
 470
 471static void core99_nvram_sync(void)
 472{
 473        struct core99_header* hdr99;
 474        unsigned long flags;
 475
 476        if (!is_core_99 || !nvram_data || !nvram_image)
 477                return;
 478
 479        raw_spin_lock_irqsave(&nv_lock, flags);
 480        if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
 481                NVRAM_SIZE))
 482                goto bail;
 483
 484        DBG("Updating nvram...\n");
 485
 486        hdr99 = (struct core99_header*)nvram_image;
 487        hdr99->generation++;
 488        hdr99->hdr.signature = CORE99_SIGNATURE;
 489        hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
 490        hdr99->adler = core99_calc_adler(nvram_image);
 491        core99_bank = core99_bank ? 0 : 1;
 492        if (core99_erase_bank)
 493                if (core99_erase_bank(core99_bank)) {
 494                        printk("nvram: Error erasing bank %d\n", core99_bank);
 495                        goto bail;
 496                }
 497        if (core99_write_bank)
 498                if (core99_write_bank(core99_bank, nvram_image))
 499                        printk("nvram: Error writing bank %d\n", core99_bank);
 500 bail:
 501        raw_spin_unlock_irqrestore(&nv_lock, flags);
 502
 503#ifdef DEBUG
 504        mdelay(2000);
 505#endif
 506}
 507
 508static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr)
 509{
 510        int i;
 511        u32 gen_bank0, gen_bank1;
 512
 513        if (nvram_naddrs < 1) {
 514                printk(KERN_ERR "nvram: no address\n");
 515                return -EINVAL;
 516        }
 517        nvram_image = memblock_alloc(NVRAM_SIZE, SMP_CACHE_BYTES);
 518        if (!nvram_image)
 519                panic("%s: Failed to allocate %u bytes\n", __func__,
 520                      NVRAM_SIZE);
 521        nvram_data = ioremap(addr, NVRAM_SIZE*2);
 522        nvram_naddrs = 1; /* Make sure we get the correct case */
 523
 524        DBG("nvram: Checking bank 0...\n");
 525
 526        gen_bank0 = core99_check((u8 *)nvram_data);
 527        gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
 528        core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
 529
 530        DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
 531        DBG("nvram: Active bank is: %d\n", core99_bank);
 532
 533        for (i=0; i<NVRAM_SIZE; i++)
 534                nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
 535
 536        ppc_md.nvram_read_val   = core99_nvram_read_byte;
 537        ppc_md.nvram_write_val  = core99_nvram_write_byte;
 538        ppc_md.nvram_read       = core99_nvram_read;
 539        ppc_md.nvram_write      = core99_nvram_write;
 540        ppc_md.nvram_size       = core99_nvram_size;
 541        ppc_md.nvram_sync       = core99_nvram_sync;
 542        ppc_md.machine_shutdown = core99_nvram_sync;
 543        /* 
 544         * Maybe we could be smarter here though making an exclusive list
 545         * of known flash chips is a bit nasty as older OF didn't provide us
 546         * with a useful "compatible" entry. A solution would be to really
 547         * identify the chip using flash id commands and base ourselves on
 548         * a list of known chips IDs
 549         */
 550        if (of_device_is_compatible(dp, "amd-0137")) {
 551                core99_erase_bank = amd_erase_bank;
 552                core99_write_bank = amd_write_bank;
 553        } else {
 554                core99_erase_bank = sm_erase_bank;
 555                core99_write_bank = sm_write_bank;
 556        }
 557        return 0;
 558}
 559
 560int __init pmac_nvram_init(void)
 561{
 562        struct device_node *dp;
 563        struct resource r1, r2;
 564        unsigned int s1 = 0, s2 = 0;
 565        int err = 0;
 566
 567        nvram_naddrs = 0;
 568
 569        dp = of_find_node_by_name(NULL, "nvram");
 570        if (dp == NULL) {
 571                printk(KERN_ERR "Can't find NVRAM device\n");
 572                return -ENODEV;
 573        }
 574
 575        /* Try to obtain an address */
 576        if (of_address_to_resource(dp, 0, &r1) == 0) {
 577                nvram_naddrs = 1;
 578                s1 = resource_size(&r1);
 579                if (of_address_to_resource(dp, 1, &r2) == 0) {
 580                        nvram_naddrs = 2;
 581                        s2 = resource_size(&r2);
 582                }
 583        }
 584
 585        is_core_99 = of_device_is_compatible(dp, "nvram,flash");
 586        if (is_core_99) {
 587                err = core99_nvram_setup(dp, r1.start);
 588                goto bail;
 589        }
 590
 591#ifdef CONFIG_PPC32
 592        if (machine_is(chrp) && nvram_naddrs == 1) {
 593                nvram_data = ioremap(r1.start, s1);
 594                nvram_mult = 1;
 595                ppc_md.nvram_read_val   = direct_nvram_read_byte;
 596                ppc_md.nvram_write_val  = direct_nvram_write_byte;
 597                ppc_md.nvram_size       = ppc32_nvram_size;
 598        } else if (nvram_naddrs == 1) {
 599                nvram_data = ioremap(r1.start, s1);
 600                nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
 601                ppc_md.nvram_read_val   = direct_nvram_read_byte;
 602                ppc_md.nvram_write_val  = direct_nvram_write_byte;
 603                ppc_md.nvram_size       = ppc32_nvram_size;
 604        } else if (nvram_naddrs == 2) {
 605                nvram_addr = ioremap(r1.start, s1);
 606                nvram_data = ioremap(r2.start, s2);
 607                ppc_md.nvram_read_val   = indirect_nvram_read_byte;
 608                ppc_md.nvram_write_val  = indirect_nvram_write_byte;
 609                ppc_md.nvram_size       = ppc32_nvram_size;
 610        } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
 611#ifdef CONFIG_ADB_PMU
 612                nvram_naddrs = -1;
 613                ppc_md.nvram_read_val   = pmu_nvram_read_byte;
 614                ppc_md.nvram_write_val  = pmu_nvram_write_byte;
 615                ppc_md.nvram_size       = ppc32_nvram_size;
 616#endif /* CONFIG_ADB_PMU */
 617        } else {
 618                printk(KERN_ERR "Incompatible type of NVRAM\n");
 619                err = -ENXIO;
 620        }
 621#endif /* CONFIG_PPC32 */
 622bail:
 623        of_node_put(dp);
 624        if (err == 0)
 625                lookup_partitions();
 626        return err;
 627}
 628
 629int pmac_get_partition(int partition)
 630{
 631        return nvram_partitions[partition];
 632}
 633
 634u8 pmac_xpram_read(int xpaddr)
 635{
 636        int offset = pmac_get_partition(pmac_nvram_XPRAM);
 637
 638        if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
 639                return 0xff;
 640
 641        return ppc_md.nvram_read_val(xpaddr + offset);
 642}
 643
 644void pmac_xpram_write(int xpaddr, u8 data)
 645{
 646        int offset = pmac_get_partition(pmac_nvram_XPRAM);
 647
 648        if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
 649                return;
 650
 651        ppc_md.nvram_write_val(xpaddr + offset, data);
 652}
 653
 654EXPORT_SYMBOL(pmac_get_partition);
 655EXPORT_SYMBOL(pmac_xpram_read);
 656EXPORT_SYMBOL(pmac_xpram_write);
 657