diff options
Diffstat (limited to 'arch/arm/mach-omap2/gpmc.c')
-rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 113 |
1 files changed, 106 insertions, 7 deletions
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index f3c992e29651..5bc3ca03551c 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -24,9 +24,9 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | 25 | ||
26 | #include <asm/mach-types.h> | 26 | #include <asm/mach-types.h> |
27 | #include <mach/gpmc.h> | 27 | #include <plat/gpmc.h> |
28 | 28 | ||
29 | #include <mach/sdrc.h> | 29 | #include <plat/sdrc.h> |
30 | 30 | ||
31 | /* GPMC register offsets */ | 31 | /* GPMC register offsets */ |
32 | #define GPMC_REVISION 0x00 | 32 | #define GPMC_REVISION 0x00 |
@@ -62,6 +62,33 @@ | |||
62 | #define ENABLE_PREFETCH (0x1 << 7) | 62 | #define ENABLE_PREFETCH (0x1 << 7) |
63 | #define DMA_MPU_MODE 2 | 63 | #define DMA_MPU_MODE 2 |
64 | 64 | ||
65 | /* Structure to save gpmc cs context */ | ||
66 | struct gpmc_cs_config { | ||
67 | u32 config1; | ||
68 | u32 config2; | ||
69 | u32 config3; | ||
70 | u32 config4; | ||
71 | u32 config5; | ||
72 | u32 config6; | ||
73 | u32 config7; | ||
74 | int is_valid; | ||
75 | }; | ||
76 | |||
77 | /* | ||
78 | * Structure to save/restore gpmc context | ||
79 | * to support core off on OMAP3 | ||
80 | */ | ||
81 | struct omap3_gpmc_regs { | ||
82 | u32 sysconfig; | ||
83 | u32 irqenable; | ||
84 | u32 timeout_ctrl; | ||
85 | u32 config; | ||
86 | u32 prefetch_config1; | ||
87 | u32 prefetch_config2; | ||
88 | u32 prefetch_control; | ||
89 | struct gpmc_cs_config cs_context[GPMC_CS_NUM]; | ||
90 | }; | ||
91 | |||
65 | static struct resource gpmc_mem_root; | 92 | static struct resource gpmc_mem_root; |
66 | static struct resource gpmc_cs_mem[GPMC_CS_NUM]; | 93 | static struct resource gpmc_cs_mem[GPMC_CS_NUM]; |
67 | static DEFINE_SPINLOCK(gpmc_mem_lock); | 94 | static DEFINE_SPINLOCK(gpmc_mem_lock); |
@@ -261,7 +288,7 @@ static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) | |||
261 | l = (base >> GPMC_CHUNK_SHIFT) & 0x3f; | 288 | l = (base >> GPMC_CHUNK_SHIFT) & 0x3f; |
262 | l &= ~(0x0f << 8); | 289 | l &= ~(0x0f << 8); |
263 | l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; | 290 | l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; |
264 | l |= 1 << 6; /* CSVALID */ | 291 | l |= GPMC_CONFIG7_CSVALID; |
265 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); | 292 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); |
266 | } | 293 | } |
267 | 294 | ||
@@ -270,7 +297,7 @@ static void gpmc_cs_disable_mem(int cs) | |||
270 | u32 l; | 297 | u32 l; |
271 | 298 | ||
272 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); | 299 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); |
273 | l &= ~(1 << 6); /* CSVALID */ | 300 | l &= ~GPMC_CONFIG7_CSVALID; |
274 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); | 301 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); |
275 | } | 302 | } |
276 | 303 | ||
@@ -290,7 +317,7 @@ static int gpmc_cs_mem_enabled(int cs) | |||
290 | u32 l; | 317 | u32 l; |
291 | 318 | ||
292 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); | 319 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); |
293 | return l & (1 << 6); | 320 | return l & GPMC_CONFIG7_CSVALID; |
294 | } | 321 | } |
295 | 322 | ||
296 | int gpmc_cs_set_reserved(int cs, int reserved) | 323 | int gpmc_cs_set_reserved(int cs, int reserved) |
@@ -478,7 +505,7 @@ static void __init gpmc_mem_init(void) | |||
478 | void __init gpmc_init(void) | 505 | void __init gpmc_init(void) |
479 | { | 506 | { |
480 | u32 l; | 507 | u32 l; |
481 | char *ck; | 508 | char *ck = NULL; |
482 | 509 | ||
483 | if (cpu_is_omap24xx()) { | 510 | if (cpu_is_omap24xx()) { |
484 | ck = "core_l3_ck"; | 511 | ck = "core_l3_ck"; |
@@ -490,10 +517,13 @@ void __init gpmc_init(void) | |||
490 | ck = "gpmc_fck"; | 517 | ck = "gpmc_fck"; |
491 | l = OMAP34XX_GPMC_BASE; | 518 | l = OMAP34XX_GPMC_BASE; |
492 | } else if (cpu_is_omap44xx()) { | 519 | } else if (cpu_is_omap44xx()) { |
493 | ck = "gpmc_fck"; | 520 | ck = "gpmc_ck"; |
494 | l = OMAP44XX_GPMC_BASE; | 521 | l = OMAP44XX_GPMC_BASE; |
495 | } | 522 | } |
496 | 523 | ||
524 | if (WARN_ON(!ck)) | ||
525 | return; | ||
526 | |||
497 | gpmc_l3_clk = clk_get(NULL, ck); | 527 | gpmc_l3_clk = clk_get(NULL, ck); |
498 | if (IS_ERR(gpmc_l3_clk)) { | 528 | if (IS_ERR(gpmc_l3_clk)) { |
499 | printk(KERN_ERR "Could not get GPMC clock %s\n", ck); | 529 | printk(KERN_ERR "Could not get GPMC clock %s\n", ck); |
@@ -507,6 +537,8 @@ void __init gpmc_init(void) | |||
507 | BUG(); | 537 | BUG(); |
508 | } | 538 | } |
509 | 539 | ||
540 | clk_enable(gpmc_l3_clk); | ||
541 | |||
510 | l = gpmc_read_reg(GPMC_REVISION); | 542 | l = gpmc_read_reg(GPMC_REVISION); |
511 | printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f); | 543 | printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f); |
512 | /* Set smart idle mode and automatic L3 clock gating */ | 544 | /* Set smart idle mode and automatic L3 clock gating */ |
@@ -516,3 +548,70 @@ void __init gpmc_init(void) | |||
516 | gpmc_write_reg(GPMC_SYSCONFIG, l); | 548 | gpmc_write_reg(GPMC_SYSCONFIG, l); |
517 | gpmc_mem_init(); | 549 | gpmc_mem_init(); |
518 | } | 550 | } |
551 | |||
552 | #ifdef CONFIG_ARCH_OMAP3 | ||
553 | static struct omap3_gpmc_regs gpmc_context; | ||
554 | |||
555 | void omap3_gpmc_save_context(void) | ||
556 | { | ||
557 | int i; | ||
558 | |||
559 | gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG); | ||
560 | gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE); | ||
561 | gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL); | ||
562 | gpmc_context.config = gpmc_read_reg(GPMC_CONFIG); | ||
563 | gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); | ||
564 | gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2); | ||
565 | gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL); | ||
566 | for (i = 0; i < GPMC_CS_NUM; i++) { | ||
567 | gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i); | ||
568 | if (gpmc_context.cs_context[i].is_valid) { | ||
569 | gpmc_context.cs_context[i].config1 = | ||
570 | gpmc_cs_read_reg(i, GPMC_CS_CONFIG1); | ||
571 | gpmc_context.cs_context[i].config2 = | ||
572 | gpmc_cs_read_reg(i, GPMC_CS_CONFIG2); | ||
573 | gpmc_context.cs_context[i].config3 = | ||
574 | gpmc_cs_read_reg(i, GPMC_CS_CONFIG3); | ||
575 | gpmc_context.cs_context[i].config4 = | ||
576 | gpmc_cs_read_reg(i, GPMC_CS_CONFIG4); | ||
577 | gpmc_context.cs_context[i].config5 = | ||
578 | gpmc_cs_read_reg(i, GPMC_CS_CONFIG5); | ||
579 | gpmc_context.cs_context[i].config6 = | ||
580 | gpmc_cs_read_reg(i, GPMC_CS_CONFIG6); | ||
581 | gpmc_context.cs_context[i].config7 = | ||
582 | gpmc_cs_read_reg(i, GPMC_CS_CONFIG7); | ||
583 | } | ||
584 | } | ||
585 | } | ||
586 | |||
587 | void omap3_gpmc_restore_context(void) | ||
588 | { | ||
589 | int i; | ||
590 | |||
591 | gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig); | ||
592 | gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable); | ||
593 | gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl); | ||
594 | gpmc_write_reg(GPMC_CONFIG, gpmc_context.config); | ||
595 | gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1); | ||
596 | gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2); | ||
597 | gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control); | ||
598 | for (i = 0; i < GPMC_CS_NUM; i++) { | ||
599 | if (gpmc_context.cs_context[i].is_valid) { | ||
600 | gpmc_cs_write_reg(i, GPMC_CS_CONFIG1, | ||
601 | gpmc_context.cs_context[i].config1); | ||
602 | gpmc_cs_write_reg(i, GPMC_CS_CONFIG2, | ||
603 | gpmc_context.cs_context[i].config2); | ||
604 | gpmc_cs_write_reg(i, GPMC_CS_CONFIG3, | ||
605 | gpmc_context.cs_context[i].config3); | ||
606 | gpmc_cs_write_reg(i, GPMC_CS_CONFIG4, | ||
607 | gpmc_context.cs_context[i].config4); | ||
608 | gpmc_cs_write_reg(i, GPMC_CS_CONFIG5, | ||
609 | gpmc_context.cs_context[i].config5); | ||
610 | gpmc_cs_write_reg(i, GPMC_CS_CONFIG6, | ||
611 | gpmc_context.cs_context[i].config6); | ||
612 | gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, | ||
613 | gpmc_context.cs_context[i].config7); | ||
614 | } | ||
615 | } | ||
616 | } | ||
617 | #endif /* CONFIG_ARCH_OMAP3 */ | ||