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