1/* 2 * GPMC support functions 3 * 4 * Copyright (C) 2005-2006 Nokia Corporation 5 * 6 * Author: Juha Yrjola 7 * 8 * Copyright (C) 2009 Texas Instruments 9 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 */ 15#undef DEBUG 16 17#include <linux/irq.h> 18#include <linux/kernel.h> 19#include <linux/init.h> 20#include <linux/err.h> 21#include <linux/clk.h> 22#include <linux/ioport.h> 23#include <linux/spinlock.h> 24#include <linux/io.h> 25#include <linux/module.h> 26#include <linux/interrupt.h> 27 28#include <asm/mach-types.h> 29#include <plat/gpmc.h> 30 31#include <plat/sdrc.h> 32 33/* GPMC register offsets */ 34#define GPMC_REVISION 0x00 35#define GPMC_SYSCONFIG 0x10 36#define GPMC_SYSSTATUS 0x14 37#define GPMC_IRQSTATUS 0x18 38#define GPMC_IRQENABLE 0x1c 39#define GPMC_TIMEOUT_CONTROL 0x40 40#define GPMC_ERR_ADDRESS 0x44 41#define GPMC_ERR_TYPE 0x48 42#define GPMC_CONFIG 0x50 43#define GPMC_STATUS 0x54 44#define GPMC_PREFETCH_CONFIG1 0x1e0 45#define GPMC_PREFETCH_CONFIG2 0x1e4 46#define GPMC_PREFETCH_CONTROL 0x1ec 47#define GPMC_PREFETCH_STATUS 0x1f0 48#define GPMC_ECC_CONFIG 0x1f4 49#define GPMC_ECC_CONTROL 0x1f8 50#define GPMC_ECC_SIZE_CONFIG 0x1fc 51#define GPMC_ECC1_RESULT 0x200 52 53#define GPMC_CS0_OFFSET 0x60 54#define GPMC_CS_SIZE 0x30 55 56#define GPMC_MEM_START 0x00000000 57#define GPMC_MEM_END 0x3FFFFFFF 58#define BOOT_ROM_SPACE 0x100000 /* 1MB */ 59 60#define GPMC_CHUNK_SHIFT 24 /* 16 MB */ 61#define GPMC_SECTION_SHIFT 28 /* 128 MB */ 62 63#define CS_NUM_SHIFT 24 64#define ENABLE_PREFETCH (0x1 << 7) 65#define DMA_MPU_MODE 2 66 67/* Structure to save gpmc cs context */ 68struct gpmc_cs_config { 69 u32 config1; 70 u32 config2; 71 u32 config3; 72 u32 config4; 73 u32 config5; 74 u32 config6; 75 u32 config7; 76 int is_valid; 77}; 78 79/* 80 * Structure to save/restore gpmc context 81 * to support core off on OMAP3 82 */ 83struct omap3_gpmc_regs { 84 u32 sysconfig; 85 u32 irqenable; 86 u32 timeout_ctrl; 87 u32 config; 88 u32 prefetch_config1; 89 u32 prefetch_config2; 90 u32 prefetch_control; 91 struct gpmc_cs_config cs_context[GPMC_CS_NUM]; 92}; 93 94static struct resource gpmc_mem_root; 95static struct resource gpmc_cs_mem[GPMC_CS_NUM]; 96static DEFINE_SPINLOCK(gpmc_mem_lock); 97static unsigned int gpmc_cs_map; /* flag for cs which are initialized */ 98static int gpmc_ecc_used = -EINVAL; /* cs using ecc engine */ 99 100static void __iomem *gpmc_base; 101 102static struct clk *gpmc_l3_clk; 103 104static irqreturn_t gpmc_handle_irq(int irq, void *dev); 105 106static void gpmc_write_reg(int idx, u32 val) 107{ 108 __raw_writel(val, gpmc_base + idx); 109} 110 111static u32 gpmc_read_reg(int idx) 112{ 113 return __raw_readl(gpmc_base + idx); 114} 115 116static void gpmc_cs_write_byte(int cs, int idx, u8 val) 117{ 118 void __iomem *reg_addr; 119 120 reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; 121 __raw_writeb(val, reg_addr); 122} 123 124static u8 gpmc_cs_read_byte(int cs, int idx) 125{ 126 void __iomem *reg_addr; 127 128 reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; 129 return __raw_readb(reg_addr); 130} 131 132void gpmc_cs_write_reg(int cs, int idx, u32 val) 133{ 134 void __iomem *reg_addr; 135 136 reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; 137 __raw_writel(val, reg_addr); 138} 139 140u32 gpmc_cs_read_reg(int cs, int idx) 141{ 142 void __iomem *reg_addr; 143 144 reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; 145 return __raw_readl(reg_addr); 146} 147 148/* TODO: Add support for gpmc_fck to clock framework and use it */ 149unsigned long gpmc_get_fclk_period(void) 150{ 151 unsigned long rate = clk_get_rate(gpmc_l3_clk); 152 153 if (rate == 0) { 154 printk(KERN_WARNING "gpmc_l3_clk not enabled\n"); 155 return 0; 156 } 157 158 rate /= 1000; 159 rate = 1000000000 / rate; /* In picoseconds */ 160 161 return rate; 162} 163 164unsigned int gpmc_ns_to_ticks(unsigned int time_ns) 165{ 166 unsigned long tick_ps; 167 168 /* Calculate in picosecs to yield more exact results */ 169 tick_ps = gpmc_get_fclk_period(); 170 171 return (time_ns * 1000 + tick_ps - 1) / tick_ps; 172} 173 174unsigned int gpmc_ps_to_ticks(unsigned int time_ps) 175{ 176 unsigned long tick_ps; 177 178 /* Calculate in picosecs to yield more exact results */ 179 tick_ps = gpmc_get_fclk_period(); 180 181 return (time_ps + tick_ps - 1) / tick_ps; 182} 183 184unsigned int gpmc_ticks_to_ns(unsigned int ticks) 185{ 186 return ticks * gpmc_get_fclk_period() / 1000; 187} 188 189unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns) 190{ 191 unsigned long ticks = gpmc_ns_to_ticks(time_ns); 192 193 return ticks * gpmc_get_fclk_period() / 1000; 194} 195 196#ifdef DEBUG 197static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, 198 int time, const char *name) 199#else 200static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, 201 int time) 202#endif 203{ 204 u32 l; 205 int ticks, mask, nr_bits; 206 207 if (time == 0) 208 ticks = 0; 209 else 210 ticks = gpmc_ns_to_ticks(time); 211 nr_bits = end_bit - st_bit + 1; 212 if (ticks >= 1 << nr_bits) { 213#ifdef DEBUG 214 printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n", 215 cs, name, time, ticks, 1 << nr_bits); 216#endif 217 return -1; 218 } 219 220 mask = (1 << nr_bits) - 1; 221 l = gpmc_cs_read_reg(cs, reg); 222#ifdef DEBUG 223 printk(KERN_INFO 224 "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", 225 cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, 226 (l >> st_bit) & mask, time); 227#endif 228 l &= ~(mask << st_bit); 229 l |= ticks << st_bit; 230 gpmc_cs_write_reg(cs, reg, l); 231 232 return 0; 233} 234 235#ifdef DEBUG 236#define GPMC_SET_ONE(reg, st, end, field) \ 237 if (set_gpmc_timing_reg(cs, (reg), (st), (end), \ 238 t->field, #field) < 0) \ 239 return -1 240#else 241#define GPMC_SET_ONE(reg, st, end, field) \ 242 if (set_gpmc_timing_reg(cs, (reg), (st), (end), t->field) < 0) \ 243 return -1 244#endif 245 246int gpmc_cs_calc_divider(int cs, unsigned int sync_clk) 247{ 248 int div; 249 u32 l; 250 251 l = sync_clk + (gpmc_get_fclk_period() - 1); 252 div = l / gpmc_get_fclk_period(); 253 if (div > 4) 254 return -1; 255 if (div <= 0) 256 div = 1; 257 258 return div; 259} 260 261int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) 262{ 263 int div; 264 u32 l; 265 266 div = gpmc_cs_calc_divider(cs, t->sync_clk); 267 if (div < 0) 268 return -1; 269 270 GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on); 271 GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off); 272 GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off); 273 274 GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on); 275 GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off); 276 GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off); 277 278 GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on); 279 GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off); 280 GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on); 281 GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off); 282 283 GPMC_SET_ONE(GPMC_CS_CONFIG5, 0, 4, rd_cycle); 284 GPMC_SET_ONE(GPMC_CS_CONFIG5, 8, 12, wr_cycle); 285 GPMC_SET_ONE(GPMC_CS_CONFIG5, 16, 20, access); 286 287 GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); 288 289 if (cpu_is_omap34xx()) { 290 GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); 291 GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); 292 } 293 294 /* caller is expected to have initialized CONFIG1 to cover 295 * at least sync vs async 296 */ 297 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); 298 if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) { 299#ifdef DEBUG 300 printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n", 301 cs, (div * gpmc_get_fclk_period()) / 1000, div); 302#endif 303 l &= ~0x03; 304 l |= (div - 1); 305 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); 306 } 307 308 return 0; 309} 310 311static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) 312{ 313 u32 l; 314 u32 mask; 315 316 mask = (1 << GPMC_SECTION_SHIFT) - size; 317 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); 318 l &= ~0x3f; 319 l = (base >> GPMC_CHUNK_SHIFT) & 0x3f; 320 l &= ~(0x0f << 8); 321 l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; 322 l |= GPMC_CONFIG7_CSVALID; 323 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); 324} 325 326static void gpmc_cs_disable_mem(int cs) 327{ 328 u32 l; 329 330 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); 331 l &= ~GPMC_CONFIG7_CSVALID; 332 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); 333} 334 335static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size) 336{ 337 u32 l; 338 u32 mask; 339 340 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); 341 *base = (l & 0x3f) << GPMC_CHUNK_SHIFT; 342 mask = (l >> 8) & 0x0f; 343 *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT); 344} 345 346static int gpmc_cs_mem_enabled(int cs) 347{ 348 u32 l; 349 350 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); 351 return l & GPMC_CONFIG7_CSVALID; 352} 353 354int gpmc_cs_set_reserved(int cs, int reserved) 355{ 356 if (cs > GPMC_CS_NUM) 357 return -ENODEV; 358 359 gpmc_cs_map &= ~(1 << cs); 360 gpmc_cs_map |= (reserved ? 1 : 0) << cs; 361 362 return 0; 363} 364 365int gpmc_cs_reserved(int cs) 366{ 367 if (cs > GPMC_CS_NUM) 368 return -ENODEV; 369 370 return gpmc_cs_map & (1 << cs); 371} 372 373static unsigned long gpmc_mem_align(unsigned long size) 374{ 375 int order; 376 377 size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1); 378 order = GPMC_CHUNK_SHIFT - 1; 379 do { 380 size >>= 1; 381 order++; 382 } while (size); 383 size = 1 << order; 384 return size; 385} 386 387static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size) 388{ 389 struct resource *res = &gpmc_cs_mem[cs]; 390 int r; 391 392 size = gpmc_mem_align(size); 393 spin_lock(&gpmc_mem_lock); 394 res->start = base; 395 res->end = base + size - 1; 396 r = request_resource(&gpmc_mem_root, res); 397 spin_unlock(&gpmc_mem_lock); 398 399 return r; 400} 401 402int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) 403{ 404 struct resource *res = &gpmc_cs_mem[cs]; 405 int r = -1; 406 407 if (cs > GPMC_CS_NUM) 408 return -ENODEV; 409 410 size = gpmc_mem_align(size); 411 if (size > (1 << GPMC_SECTION_SHIFT)) 412 return -ENOMEM; 413 414 spin_lock(&gpmc_mem_lock); 415 if (gpmc_cs_reserved(cs)) { 416 r = -EBUSY; 417 goto out; 418 } 419 if (gpmc_cs_mem_enabled(cs)) 420 r = adjust_resource(res, res->start & ~(size - 1), size); 421 if (r < 0) 422 r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0, 423 size, NULL, NULL); 424 if (r < 0) 425 goto out; 426 427 gpmc_cs_enable_mem(cs, res->start, resource_size(res)); 428 *base = res->start; 429 gpmc_cs_set_reserved(cs, 1); 430out: 431 spin_unlock(&gpmc_mem_lock); 432 return r; 433} 434EXPORT_SYMBOL(gpmc_cs_request); 435 436void gpmc_cs_free(int cs) 437{ 438 spin_lock(&gpmc_mem_lock); 439 if (cs >= GPMC_CS_NUM || cs < 0 || !gpmc_cs_reserved(cs)) { 440 printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); 441 BUG(); 442 spin_unlock(&gpmc_mem_lock); 443 return; 444 } 445 gpmc_cs_disable_mem(cs); 446 release_resource(&gpmc_cs_mem[cs]); 447 gpmc_cs_set_reserved(cs, 0); 448 spin_unlock(&gpmc_mem_lock); 449} 450EXPORT_SYMBOL(gpmc_cs_free); 451 452/** 453 * gpmc_read_status - read access request to get the different gpmc status 454 * @cmd: command type 455 * @return status 456 */ 457int gpmc_read_status(int cmd) 458{ 459 int status = -EINVAL; 460 u32 regval = 0; 461 462 switch (cmd) { 463 case GPMC_GET_IRQ_STATUS: 464 status = gpmc_read_reg(GPMC_IRQSTATUS); 465 break; 466 467 case GPMC_PREFETCH_FIFO_CNT: 468 regval = gpmc_read_reg(GPMC_PREFETCH_STATUS); 469 status = GPMC_PREFETCH_STATUS_FIFO_CNT(regval); 470 break; 471 472 case GPMC_PREFETCH_COUNT: 473 regval = gpmc_read_reg(GPMC_PREFETCH_STATUS); 474 status = GPMC_PREFETCH_STATUS_COUNT(regval); 475 break; 476 477 case GPMC_STATUS_BUFFER: 478 regval = gpmc_read_reg(GPMC_STATUS); 479 /* 1 : buffer is available to write */ 480 status = regval & GPMC_STATUS_BUFF_EMPTY; 481 break; 482 483 default: 484 printk(KERN_ERR "gpmc_read_status: Not supported\n"); 485 } 486 return status; 487} 488EXPORT_SYMBOL(gpmc_read_status); 489 490/** 491 * gpmc_cs_configure - write request to configure gpmc 492 * @cs: chip select number 493 * @cmd: command type 494 * @wval: value to write 495 * @return status of the operation 496 */ 497int gpmc_cs_configure(int cs, int cmd, int wval) 498{ 499 int err = 0; 500 u32 regval = 0; 501 502 switch (cmd) { 503 case GPMC_ENABLE_IRQ: 504 gpmc_write_reg(GPMC_IRQENABLE, wval); 505 break; 506 507 case GPMC_SET_IRQ_STATUS: 508 gpmc_write_reg(GPMC_IRQSTATUS, wval); 509 break; 510 511 case GPMC_CONFIG_WP: 512 regval = gpmc_read_reg(GPMC_CONFIG); 513 if (wval) 514 regval &= ~GPMC_CONFIG_WRITEPROTECT; /* WP is ON */ 515 else 516 regval |= GPMC_CONFIG_WRITEPROTECT; /* WP is OFF */ 517 gpmc_write_reg(GPMC_CONFIG, regval); 518 break; 519 520 case GPMC_CONFIG_RDY_BSY: 521 regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); 522 if (wval) 523 regval |= WR_RD_PIN_MONITORING; 524 else 525 regval &= ~WR_RD_PIN_MONITORING; 526 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); 527 break; 528 529 case GPMC_CONFIG_DEV_SIZE: 530 regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); 531 532 /* clear 2 target bits */ 533 regval &= ~GPMC_CONFIG1_DEVICESIZE(3); 534 535 /* set the proper value */ 536 regval |= GPMC_CONFIG1_DEVICESIZE(wval); 537 538 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); 539 break; 540 541 case GPMC_CONFIG_DEV_TYPE: 542 regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); 543 regval |= GPMC_CONFIG1_DEVICETYPE(wval); 544 if (wval == GPMC_DEVICETYPE_NOR) 545 regval |= GPMC_CONFIG1_MUXADDDATA; 546 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); 547 break; 548 549 default: 550 printk(KERN_ERR "gpmc_configure_cs: Not supported\n"); 551 err = -EINVAL; 552 } 553 554 return err; 555} 556EXPORT_SYMBOL(gpmc_cs_configure); 557 558/** 559 * gpmc_nand_read - nand specific read access request 560 * @cs: chip select number 561 * @cmd: command type 562 */ 563int gpmc_nand_read(int cs, int cmd) 564{ 565 int rval = -EINVAL; 566 567 switch (cmd) { 568 case GPMC_NAND_DATA: 569 rval = gpmc_cs_read_byte(cs, GPMC_CS_NAND_DATA); 570 break; 571 572 default: 573 printk(KERN_ERR "gpmc_read_nand_ctrl: Not supported\n"); 574 } 575 return rval; 576} 577EXPORT_SYMBOL(gpmc_nand_read); 578 579/** 580 * gpmc_nand_write - nand specific write request 581 * @cs: chip select number 582 * @cmd: command type 583 * @wval: value to write 584 */ 585int gpmc_nand_write(int cs, int cmd, int wval) 586{ 587 int err = 0; 588 589 switch (cmd) { 590 case GPMC_NAND_COMMAND: 591 gpmc_cs_write_byte(cs, GPMC_CS_NAND_COMMAND, wval); 592 break; 593 594 case GPMC_NAND_ADDRESS: 595 gpmc_cs_write_byte(cs, GPMC_CS_NAND_ADDRESS, wval); 596 break; 597 598 case GPMC_NAND_DATA: 599 gpmc_cs_write_byte(cs, GPMC_CS_NAND_DATA, wval); 600 601 default: 602 printk(KERN_ERR "gpmc_write_nand_ctrl: Not supported\n"); 603 err = -EINVAL; 604 } 605 return err; 606} 607EXPORT_SYMBOL(gpmc_nand_write); 608 609 610 611/** 612 * gpmc_prefetch_enable - configures and starts prefetch transfer 613 * @cs: cs (chip select) number 614 * @fifo_th: fifo threshold to be used for read/ write 615 * @dma_mode: dma mode enable (1) or disable (0) 616 * @u32_count: number of bytes to be transferred 617 * @is_write: prefetch read(0) or write post(1) mode 618 */ 619int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, 620 unsigned int u32_count, int is_write) 621{ 622 623 if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { 624 pr_err("gpmc: fifo threshold is not supported\n"); 625 return -1; 626 } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { 627 /* Set the amount of bytes to be prefetched */ 628 gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); 629 630 /* Set dma/mpu mode, the prefetch read / post write and 631 * enable the engine. Set which cs is has requested for. 632 */ 633 gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | 634 PREFETCH_FIFOTHRESHOLD(fifo_th) | 635 ENABLE_PREFETCH | 636 (dma_mode << DMA_MPU_MODE) | 637 (0x1 & is_write))); 638 639 /* Start the prefetch engine */ 640 gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x1); 641 } else { 642 return -EBUSY; 643 } 644 645 return 0; 646} 647EXPORT_SYMBOL(gpmc_prefetch_enable); 648 649/** 650 * gpmc_prefetch_reset - disables and stops the prefetch engine 651 */ 652int gpmc_prefetch_reset(int cs) 653{ 654 u32 config1; 655 656 /* check if the same module/cs is trying to reset */ 657 config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); 658 if (((config1 >> CS_NUM_SHIFT) & 0x7) != cs) 659 return -EINVAL; 660 661 /* Stop the PFPW engine */ 662 gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x0); 663 664 /* Reset/disable the PFPW engine */ 665 gpmc_write_reg(GPMC_PREFETCH_CONFIG1, 0x0); 666 667 return 0; 668} 669EXPORT_SYMBOL(gpmc_prefetch_reset); 670 671static void __init gpmc_mem_init(void) 672{ 673 int cs; 674 unsigned long boot_rom_space = 0; 675 676 /* never allocate the first page, to facilitate bug detection; 677 * even if we didn't boot from ROM. 678 */ 679 boot_rom_space = BOOT_ROM_SPACE; 680 /* In apollon the CS0 is mapped as 0x0000 0000 */ 681 if (machine_is_omap_apollon()) 682 boot_rom_space = 0; 683 gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space; 684 gpmc_mem_root.end = GPMC_MEM_END; 685 686 /* Reserve all regions that has been set up by bootloader */ 687 for (cs = 0; cs < GPMC_CS_NUM; cs++) { 688 u32 base, size; 689 690 if (!gpmc_cs_mem_enabled(cs)) 691 continue; 692 gpmc_cs_get_memconf(cs, &base, &size); 693 if (gpmc_cs_insert_mem(cs, base, size) < 0) 694 BUG(); 695 } 696} 697 698static int __init gpmc_init(void) 699{ 700 u32 l, irq; 701 int cs, ret = -EINVAL; 702 int gpmc_irq; 703 char *ck = NULL; 704 705 if (cpu_is_omap24xx()) { 706 ck = "core_l3_ck"; 707 if (cpu_is_omap2420()) 708 l = OMAP2420_GPMC_BASE; 709 else 710 l = OMAP34XX_GPMC_BASE; 711 gpmc_irq = INT_34XX_GPMC_IRQ; 712 } else if (cpu_is_omap34xx()) { 713 ck = "gpmc_fck"; 714 l = OMAP34XX_GPMC_BASE; 715 gpmc_irq = INT_34XX_GPMC_IRQ; 716 } else if (cpu_is_omap44xx()) { 717 ck = "gpmc_ck"; 718 l = OMAP44XX_GPMC_BASE; 719 gpmc_irq = OMAP44XX_IRQ_GPMC; 720 } 721 722 if (WARN_ON(!ck)) 723 return ret; 724 725 gpmc_l3_clk = clk_get(NULL, ck); 726 if (IS_ERR(gpmc_l3_clk)) { 727 printk(KERN_ERR "Could not get GPMC clock %s\n", ck); 728 BUG(); 729 } 730 731 gpmc_base = ioremap(l, SZ_4K); 732 if (!gpmc_base) { 733 clk_put(gpmc_l3_clk); 734 printk(KERN_ERR "Could not get GPMC register memory\n"); 735 BUG(); 736 } 737 738 clk_enable(gpmc_l3_clk); 739 740 l = gpmc_read_reg(GPMC_REVISION); 741 printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f); 742 /* Set smart idle mode and automatic L3 clock gating */ 743 l = gpmc_read_reg(GPMC_SYSCONFIG); 744 l &= 0x03 << 3; 745 l |= (0x02 << 3) | (1 << 0); 746 gpmc_write_reg(GPMC_SYSCONFIG, l); 747 gpmc_mem_init(); 748 749 /* initalize the irq_chained */ 750 irq = OMAP_GPMC_IRQ_BASE; 751 for (cs = 0; cs < GPMC_CS_NUM; cs++) { 752 irq_set_chip_and_handler(irq, &dummy_irq_chip, 753 handle_simple_irq); 754 set_irq_flags(irq, IRQF_VALID); 755 irq++; 756 } 757 758 ret = request_irq(gpmc_irq, 759 gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base); 760 if (ret) 761 pr_err("gpmc: irq-%d could not claim: err %d\n", 762 gpmc_irq, ret); 763 return ret; 764} 765postcore_initcall(gpmc_init); 766 767static irqreturn_t gpmc_handle_irq(int irq, void *dev) 768{ 769 u8 cs; 770 771 /* check cs to invoke the irq */ 772 cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7; 773 if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END) 774 generic_handle_irq(OMAP_GPMC_IRQ_BASE+cs); 775 776 return IRQ_HANDLED; 777} 778 779#ifdef CONFIG_ARCH_OMAP3 780static struct omap3_gpmc_regs gpmc_context; 781 782void omap3_gpmc_save_context(void) 783{ 784 int i; 785 786 gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG); 787 gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE); 788 gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL); 789 gpmc_context.config = gpmc_read_reg(GPMC_CONFIG); 790 gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); 791 gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2); 792 gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL); 793 for (i = 0; i < GPMC_CS_NUM; i++) { 794 gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i); 795 if (gpmc_context.cs_context[i].is_valid) { 796 gpmc_context.cs_context[i].config1 = 797 gpmc_cs_read_reg(i, GPMC_CS_CONFIG1); 798 gpmc_context.cs_context[i].config2 = 799 gpmc_cs_read_reg(i, GPMC_CS_CONFIG2); 800 gpmc_context.cs_context[i].config3 = 801 gpmc_cs_read_reg(i, GPMC_CS_CONFIG3); 802 gpmc_context.cs_context[i].config4 = 803 gpmc_cs_read_reg(i, GPMC_CS_CONFIG4); 804 gpmc_context.cs_context[i].config5 = 805 gpmc_cs_read_reg(i, GPMC_CS_CONFIG5); 806 gpmc_context.cs_context[i].config6 = 807 gpmc_cs_read_reg(i, GPMC_CS_CONFIG6); 808 gpmc_context.cs_context[i].config7 = 809 gpmc_cs_read_reg(i, GPMC_CS_CONFIG7); 810 } 811 } 812} 813 814void omap3_gpmc_restore_context(void) 815{ 816 int i; 817 818 gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig); 819 gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable); 820 gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl); 821 gpmc_write_reg(GPMC_CONFIG, gpmc_context.config); 822 gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1); 823 gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2); 824 gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control); 825 for (i = 0; i < GPMC_CS_NUM; i++) { 826 if (gpmc_context.cs_context[i].is_valid) { 827 gpmc_cs_write_reg(i, GPMC_CS_CONFIG1, 828 gpmc_context.cs_context[i].config1); 829 gpmc_cs_write_reg(i, GPMC_CS_CONFIG2, 830 gpmc_context.cs_context[i].config2); 831 gpmc_cs_write_reg(i, GPMC_CS_CONFIG3, 832 gpmc_context.cs_context[i].config3); 833 gpmc_cs_write_reg(i, GPMC_CS_CONFIG4, 834 gpmc_context.cs_context[i].config4); 835 gpmc_cs_write_reg(i, GPMC_CS_CONFIG5, 836 gpmc_context.cs_context[i].config5); 837 gpmc_cs_write_reg(i, GPMC_CS_CONFIG6, 838 gpmc_context.cs_context[i].config6); 839 gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, 840 gpmc_context.cs_context[i].config7); 841 } 842 } 843} 844#endif /* CONFIG_ARCH_OMAP3 */ 845 846/** 847 * gpmc_enable_hwecc - enable hardware ecc functionality 848 * @cs: chip select number 849 * @mode: read/write mode 850 * @dev_width: device bus width(1 for x16, 0 for x8) 851 * @ecc_size: bytes for which ECC will be generated 852 */ 853int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size) 854{ 855 unsigned int val; 856 857 /* check if ecc module is in used */ 858 if (gpmc_ecc_used != -EINVAL) 859 return -EINVAL; 860 861 gpmc_ecc_used = cs; 862 863 /* clear ecc and enable bits */ 864 val = ((0x00000001<<8) | 0x00000001); 865 gpmc_write_reg(GPMC_ECC_CONTROL, val); 866 867 /* program ecc and result sizes */ 868 val = ((((ecc_size >> 1) - 1) << 22) | (0x0000000F)); 869 gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, val); 870 871 switch (mode) { 872 case GPMC_ECC_READ: 873 gpmc_write_reg(GPMC_ECC_CONTROL, 0x101); 874 break; 875 case GPMC_ECC_READSYN: 876 gpmc_write_reg(GPMC_ECC_CONTROL, 0x100); 877 break; 878 case GPMC_ECC_WRITE: 879 gpmc_write_reg(GPMC_ECC_CONTROL, 0x101); 880 break; 881 default: 882 printk(KERN_INFO "Error: Unrecognized Mode[%d]!\n", mode); 883 break; 884 } 885 886 /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ 887 val = (dev_width << 7) | (cs << 1) | (0x1); 888 gpmc_write_reg(GPMC_ECC_CONFIG, val); 889 return 0; 890} 891EXPORT_SYMBOL_GPL(gpmc_enable_hwecc); 892 893/** 894 * gpmc_calculate_ecc - generate non-inverted ecc bytes 895 * @cs: chip select number 896 * @dat: data pointer over which ecc is computed 897 * @ecc_code: ecc code buffer 898 * 899 * Using non-inverted ECC is considered ugly since writing a blank 900 * page (padding) will clear the ECC bytes. This is not a problem as long 901 * no one is trying to write data on the seemingly unused page. Reading 902 * an erased page will produce an ECC mismatch between generated and read 903 * ECC bytes that has to be dealt with separately. 904 */ 905int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code) 906{ 907 unsigned int val = 0x0; 908 909 if (gpmc_ecc_used != cs) 910 return -EINVAL; 911 912 /* read ecc result */ 913 val = gpmc_read_reg(GPMC_ECC1_RESULT); 914 *ecc_code++ = val; /* P128e, ..., P1e */ 915 *ecc_code++ = val >> 16; /* P128o, ..., P1o */ 916 /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */ 917 *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0); 918 919 gpmc_ecc_used = -EINVAL; 920 return 0; 921} 922EXPORT_SYMBOL_GPL(gpmc_calculate_ecc); 923