diff options
Diffstat (limited to 'arch/arm')
80 files changed, 10712 insertions, 2206 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3bfef0934c9d..3df7cbd924a1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -239,6 +239,8 @@ source "arch/arm/plat-omap/Kconfig" | |||
239 | 239 | ||
240 | source "arch/arm/mach-omap1/Kconfig" | 240 | source "arch/arm/mach-omap1/Kconfig" |
241 | 241 | ||
242 | source "arch/arm/mach-omap2/Kconfig" | ||
243 | |||
242 | source "arch/arm/mach-s3c2410/Kconfig" | 244 | source "arch/arm/mach-s3c2410/Kconfig" |
243 | 245 | ||
244 | source "arch/arm/mach-lh7a40x/Kconfig" | 246 | source "arch/arm/mach-lh7a40x/Kconfig" |
@@ -358,7 +360,7 @@ config HOTPLUG_CPU | |||
358 | 360 | ||
359 | config LOCAL_TIMERS | 361 | config LOCAL_TIMERS |
360 | bool "Use local timer interrupts" | 362 | bool "Use local timer interrupts" |
361 | depends on SMP && n | 363 | depends on SMP && REALVIEW_MPCORE |
362 | default y | 364 | default y |
363 | help | 365 | help |
364 | Enable support for local timers on SMP platforms, rather then the | 366 | Enable support for local timers on SMP platforms, rather then the |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 114cda7f1b73..81bd2193fe6d 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -93,6 +93,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000 | |||
93 | machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx | 93 | machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx |
94 | machine-$(CONFIG_ARCH_IXP2000) := ixp2000 | 94 | machine-$(CONFIG_ARCH_IXP2000) := ixp2000 |
95 | machine-$(CONFIG_ARCH_OMAP1) := omap1 | 95 | machine-$(CONFIG_ARCH_OMAP1) := omap1 |
96 | machine-$(CONFIG_ARCH_OMAP2) := omap2 | ||
96 | incdir-$(CONFIG_ARCH_OMAP) := omap | 97 | incdir-$(CONFIG_ARCH_OMAP) := omap |
97 | machine-$(CONFIG_ARCH_S3C2410) := s3c2410 | 98 | machine-$(CONFIG_ARCH_S3C2410) := s3c2410 |
98 | machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x | 99 | machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x |
diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig index 4198677cd394..529f0f72e1e9 100644 --- a/arch/arm/configs/omap_h2_1610_defconfig +++ b/arch/arm/configs/omap_h2_1610_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.13 | 3 | # Linux kernel version: 2.6.14 |
4 | # Mon Sep 5 18:07:12 2005 | 4 | # Wed Nov 9 18:53:40 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -22,6 +22,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 | |||
22 | # General setup | 22 | # General setup |
23 | # | 23 | # |
24 | CONFIG_LOCALVERSION="" | 24 | CONFIG_LOCALVERSION="" |
25 | CONFIG_LOCALVERSION_AUTO=y | ||
25 | CONFIG_SWAP=y | 26 | CONFIG_SWAP=y |
26 | CONFIG_SYSVIPC=y | 27 | CONFIG_SYSVIPC=y |
27 | # CONFIG_POSIX_MQUEUE is not set | 28 | # CONFIG_POSIX_MQUEUE is not set |
@@ -31,6 +32,7 @@ CONFIG_SYSCTL=y | |||
31 | # CONFIG_HOTPLUG is not set | 32 | # CONFIG_HOTPLUG is not set |
32 | CONFIG_KOBJECT_UEVENT=y | 33 | CONFIG_KOBJECT_UEVENT=y |
33 | # CONFIG_IKCONFIG is not set | 34 | # CONFIG_IKCONFIG is not set |
35 | CONFIG_INITRAMFS_SOURCE="" | ||
34 | # CONFIG_EMBEDDED is not set | 36 | # CONFIG_EMBEDDED is not set |
35 | CONFIG_KALLSYMS=y | 37 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 38 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
@@ -60,6 +62,23 @@ CONFIG_OBSOLETE_MODPARM=y | |||
60 | # CONFIG_KMOD is not set | 62 | # CONFIG_KMOD is not set |
61 | 63 | ||
62 | # | 64 | # |
65 | # Block layer | ||
66 | # | ||
67 | |||
68 | # | ||
69 | # IO Schedulers | ||
70 | # | ||
71 | CONFIG_IOSCHED_NOOP=y | ||
72 | CONFIG_IOSCHED_AS=y | ||
73 | CONFIG_IOSCHED_DEADLINE=y | ||
74 | CONFIG_IOSCHED_CFQ=y | ||
75 | CONFIG_DEFAULT_AS=y | ||
76 | # CONFIG_DEFAULT_DEADLINE is not set | ||
77 | # CONFIG_DEFAULT_CFQ is not set | ||
78 | # CONFIG_DEFAULT_NOOP is not set | ||
79 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
80 | |||
81 | # | ||
63 | # System Type | 82 | # System Type |
64 | # | 83 | # |
65 | # CONFIG_ARCH_CLPS7500 is not set | 84 | # CONFIG_ARCH_CLPS7500 is not set |
@@ -81,6 +100,7 @@ CONFIG_OBSOLETE_MODPARM=y | |||
81 | # CONFIG_ARCH_LH7A40X is not set | 100 | # CONFIG_ARCH_LH7A40X is not set |
82 | CONFIG_ARCH_OMAP=y | 101 | CONFIG_ARCH_OMAP=y |
83 | # CONFIG_ARCH_VERSATILE is not set | 102 | # CONFIG_ARCH_VERSATILE is not set |
103 | # CONFIG_ARCH_REALVIEW is not set | ||
84 | # CONFIG_ARCH_IMX is not set | 104 | # CONFIG_ARCH_IMX is not set |
85 | # CONFIG_ARCH_H720X is not set | 105 | # CONFIG_ARCH_H720X is not set |
86 | # CONFIG_ARCH_AAEC2000 is not set | 106 | # CONFIG_ARCH_AAEC2000 is not set |
@@ -112,7 +132,7 @@ CONFIG_OMAP_SERIAL_WAKE=y | |||
112 | # OMAP Core Type | 132 | # OMAP Core Type |
113 | # | 133 | # |
114 | # CONFIG_ARCH_OMAP730 is not set | 134 | # CONFIG_ARCH_OMAP730 is not set |
115 | # CONFIG_ARCH_OMAP1510 is not set | 135 | # CONFIG_ARCH_OMAP15XX is not set |
116 | CONFIG_ARCH_OMAP16XX=y | 136 | CONFIG_ARCH_OMAP16XX=y |
117 | 137 | ||
118 | # | 138 | # |
@@ -177,6 +197,8 @@ CONFIG_FLATMEM_MANUAL=y | |||
177 | # CONFIG_SPARSEMEM_MANUAL is not set | 197 | # CONFIG_SPARSEMEM_MANUAL is not set |
178 | CONFIG_FLATMEM=y | 198 | CONFIG_FLATMEM=y |
179 | CONFIG_FLAT_NODE_MEM_MAP=y | 199 | CONFIG_FLAT_NODE_MEM_MAP=y |
200 | # CONFIG_SPARSEMEM_STATIC is not set | ||
201 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
180 | # CONFIG_LEDS is not set | 202 | # CONFIG_LEDS is not set |
181 | CONFIG_ALIGNMENT_TRAP=y | 203 | CONFIG_ALIGNMENT_TRAP=y |
182 | 204 | ||
@@ -258,14 +280,19 @@ CONFIG_IP_PNP_BOOTP=y | |||
258 | # CONFIG_INET_ESP is not set | 280 | # CONFIG_INET_ESP is not set |
259 | # CONFIG_INET_IPCOMP is not set | 281 | # CONFIG_INET_IPCOMP is not set |
260 | # CONFIG_INET_TUNNEL is not set | 282 | # CONFIG_INET_TUNNEL is not set |
261 | CONFIG_IP_TCPDIAG=y | 283 | CONFIG_INET_DIAG=y |
262 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 284 | CONFIG_INET_TCP_DIAG=y |
263 | # CONFIG_TCP_CONG_ADVANCED is not set | 285 | # CONFIG_TCP_CONG_ADVANCED is not set |
264 | CONFIG_TCP_CONG_BIC=y | 286 | CONFIG_TCP_CONG_BIC=y |
265 | # CONFIG_IPV6 is not set | 287 | # CONFIG_IPV6 is not set |
266 | # CONFIG_NETFILTER is not set | 288 | # CONFIG_NETFILTER is not set |
267 | 289 | ||
268 | # | 290 | # |
291 | # DCCP Configuration (EXPERIMENTAL) | ||
292 | # | ||
293 | # CONFIG_IP_DCCP is not set | ||
294 | |||
295 | # | ||
269 | # SCTP Configuration (EXPERIMENTAL) | 296 | # SCTP Configuration (EXPERIMENTAL) |
270 | # | 297 | # |
271 | # CONFIG_IP_SCTP is not set | 298 | # CONFIG_IP_SCTP is not set |
@@ -281,6 +308,10 @@ CONFIG_TCP_CONG_BIC=y | |||
281 | # CONFIG_NET_DIVERT is not set | 308 | # CONFIG_NET_DIVERT is not set |
282 | # CONFIG_ECONET is not set | 309 | # CONFIG_ECONET is not set |
283 | # CONFIG_WAN_ROUTER is not set | 310 | # CONFIG_WAN_ROUTER is not set |
311 | |||
312 | # | ||
313 | # QoS and/or fair queueing | ||
314 | # | ||
284 | # CONFIG_NET_SCHED is not set | 315 | # CONFIG_NET_SCHED is not set |
285 | # CONFIG_NET_CLS_ROUTE is not set | 316 | # CONFIG_NET_CLS_ROUTE is not set |
286 | 317 | ||
@@ -291,6 +322,7 @@ CONFIG_TCP_CONG_BIC=y | |||
291 | # CONFIG_HAMRADIO is not set | 322 | # CONFIG_HAMRADIO is not set |
292 | # CONFIG_IRDA is not set | 323 | # CONFIG_IRDA is not set |
293 | # CONFIG_BT is not set | 324 | # CONFIG_BT is not set |
325 | # CONFIG_IEEE80211 is not set | ||
294 | 326 | ||
295 | # | 327 | # |
296 | # Device Drivers | 328 | # Device Drivers |
@@ -328,21 +360,13 @@ CONFIG_BLK_DEV_RAM=y | |||
328 | CONFIG_BLK_DEV_RAM_COUNT=16 | 360 | CONFIG_BLK_DEV_RAM_COUNT=16 |
329 | CONFIG_BLK_DEV_RAM_SIZE=8192 | 361 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
330 | CONFIG_BLK_DEV_INITRD=y | 362 | CONFIG_BLK_DEV_INITRD=y |
331 | CONFIG_INITRAMFS_SOURCE="" | ||
332 | # CONFIG_CDROM_PKTCDVD is not set | 363 | # CONFIG_CDROM_PKTCDVD is not set |
333 | |||
334 | # | ||
335 | # IO Schedulers | ||
336 | # | ||
337 | CONFIG_IOSCHED_NOOP=y | ||
338 | CONFIG_IOSCHED_AS=y | ||
339 | CONFIG_IOSCHED_DEADLINE=y | ||
340 | CONFIG_IOSCHED_CFQ=y | ||
341 | CONFIG_ATA_OVER_ETH=m | 364 | CONFIG_ATA_OVER_ETH=m |
342 | 365 | ||
343 | # | 366 | # |
344 | # SCSI device support | 367 | # SCSI device support |
345 | # | 368 | # |
369 | # CONFIG_RAID_ATTRS is not set | ||
346 | CONFIG_SCSI=y | 370 | CONFIG_SCSI=y |
347 | CONFIG_SCSI_PROC_FS=y | 371 | CONFIG_SCSI_PROC_FS=y |
348 | 372 | ||
@@ -369,10 +393,12 @@ CONFIG_SCSI_PROC_FS=y | |||
369 | # CONFIG_SCSI_SPI_ATTRS is not set | 393 | # CONFIG_SCSI_SPI_ATTRS is not set |
370 | # CONFIG_SCSI_FC_ATTRS is not set | 394 | # CONFIG_SCSI_FC_ATTRS is not set |
371 | # CONFIG_SCSI_ISCSI_ATTRS is not set | 395 | # CONFIG_SCSI_ISCSI_ATTRS is not set |
396 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
372 | 397 | ||
373 | # | 398 | # |
374 | # SCSI low-level drivers | 399 | # SCSI low-level drivers |
375 | # | 400 | # |
401 | # CONFIG_ISCSI_TCP is not set | ||
376 | # CONFIG_SCSI_SATA is not set | 402 | # CONFIG_SCSI_SATA is not set |
377 | # CONFIG_SCSI_DEBUG is not set | 403 | # CONFIG_SCSI_DEBUG is not set |
378 | 404 | ||
@@ -404,6 +430,11 @@ CONFIG_NETDEVICES=y | |||
404 | # CONFIG_TUN is not set | 430 | # CONFIG_TUN is not set |
405 | 431 | ||
406 | # | 432 | # |
433 | # PHY device support | ||
434 | # | ||
435 | # CONFIG_PHYLIB is not set | ||
436 | |||
437 | # | ||
407 | # Ethernet (10 or 100Mbit) | 438 | # Ethernet (10 or 100Mbit) |
408 | # | 439 | # |
409 | CONFIG_NET_ETHERNET=y | 440 | CONFIG_NET_ETHERNET=y |
@@ -439,6 +470,7 @@ CONFIG_PPP=y | |||
439 | # CONFIG_PPP_SYNC_TTY is not set | 470 | # CONFIG_PPP_SYNC_TTY is not set |
440 | # CONFIG_PPP_DEFLATE is not set | 471 | # CONFIG_PPP_DEFLATE is not set |
441 | # CONFIG_PPP_BSDCOMP is not set | 472 | # CONFIG_PPP_BSDCOMP is not set |
473 | # CONFIG_PPP_MPPE is not set | ||
442 | # CONFIG_PPPOE is not set | 474 | # CONFIG_PPPOE is not set |
443 | CONFIG_SLIP=y | 475 | CONFIG_SLIP=y |
444 | CONFIG_SLIP_COMPRESSED=y | 476 | CONFIG_SLIP_COMPRESSED=y |
@@ -541,18 +573,18 @@ CONFIG_WATCHDOG_NOWAYOUT=y | |||
541 | # | 573 | # |
542 | # TPM devices | 574 | # TPM devices |
543 | # | 575 | # |
576 | # CONFIG_TELCLOCK is not set | ||
544 | 577 | ||
545 | # | 578 | # |
546 | # I2C support | 579 | # I2C support |
547 | # | 580 | # |
548 | # CONFIG_I2C is not set | 581 | # CONFIG_I2C is not set |
549 | # CONFIG_I2C_SENSOR is not set | ||
550 | CONFIG_ISP1301_OMAP=y | ||
551 | 582 | ||
552 | # | 583 | # |
553 | # Hardware Monitoring support | 584 | # Hardware Monitoring support |
554 | # | 585 | # |
555 | CONFIG_HWMON=y | 586 | CONFIG_HWMON=y |
587 | # CONFIG_HWMON_VID is not set | ||
556 | # CONFIG_HWMON_DEBUG_CHIP is not set | 588 | # CONFIG_HWMON_DEBUG_CHIP is not set |
557 | 589 | ||
558 | # | 590 | # |
@@ -560,6 +592,10 @@ CONFIG_HWMON=y | |||
560 | # | 592 | # |
561 | 593 | ||
562 | # | 594 | # |
595 | # Multimedia Capabilities Port drivers | ||
596 | # | ||
597 | |||
598 | # | ||
563 | # Multimedia devices | 599 | # Multimedia devices |
564 | # | 600 | # |
565 | # CONFIG_VIDEO_DEV is not set | 601 | # CONFIG_VIDEO_DEV is not set |
@@ -576,7 +612,6 @@ CONFIG_FB=y | |||
576 | # CONFIG_FB_CFB_FILLRECT is not set | 612 | # CONFIG_FB_CFB_FILLRECT is not set |
577 | # CONFIG_FB_CFB_COPYAREA is not set | 613 | # CONFIG_FB_CFB_COPYAREA is not set |
578 | # CONFIG_FB_CFB_IMAGEBLIT is not set | 614 | # CONFIG_FB_CFB_IMAGEBLIT is not set |
579 | # CONFIG_FB_SOFT_CURSOR is not set | ||
580 | # CONFIG_FB_MACMODES is not set | 615 | # CONFIG_FB_MACMODES is not set |
581 | CONFIG_FB_MODE_HELPERS=y | 616 | CONFIG_FB_MODE_HELPERS=y |
582 | # CONFIG_FB_TILEBLITTING is not set | 617 | # CONFIG_FB_TILEBLITTING is not set |
@@ -589,6 +624,7 @@ CONFIG_FB_MODE_HELPERS=y | |||
589 | # CONFIG_VGA_CONSOLE is not set | 624 | # CONFIG_VGA_CONSOLE is not set |
590 | CONFIG_DUMMY_CONSOLE=y | 625 | CONFIG_DUMMY_CONSOLE=y |
591 | CONFIG_FRAMEBUFFER_CONSOLE=y | 626 | CONFIG_FRAMEBUFFER_CONSOLE=y |
627 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | ||
592 | CONFIG_FONTS=y | 628 | CONFIG_FONTS=y |
593 | CONFIG_FONT_8x8=y | 629 | CONFIG_FONT_8x8=y |
594 | CONFIG_FONT_8x16=y | 630 | CONFIG_FONT_8x16=y |
@@ -600,6 +636,7 @@ CONFIG_FONT_8x16=y | |||
600 | # CONFIG_FONT_SUN8x16 is not set | 636 | # CONFIG_FONT_SUN8x16 is not set |
601 | # CONFIG_FONT_SUN12x22 is not set | 637 | # CONFIG_FONT_SUN12x22 is not set |
602 | # CONFIG_FONT_10x18 is not set | 638 | # CONFIG_FONT_10x18 is not set |
639 | # CONFIG_FONT_RL is not set | ||
603 | 640 | ||
604 | # | 641 | # |
605 | # Logo configuration | 642 | # Logo configuration |
@@ -624,10 +661,10 @@ CONFIG_SOUND=y | |||
624 | # Open Sound System | 661 | # Open Sound System |
625 | # | 662 | # |
626 | CONFIG_SOUND_PRIME=y | 663 | CONFIG_SOUND_PRIME=y |
664 | # CONFIG_OBSOLETE_OSS_DRIVER is not set | ||
627 | # CONFIG_SOUND_MSNDCLAS is not set | 665 | # CONFIG_SOUND_MSNDCLAS is not set |
628 | # CONFIG_SOUND_MSNDPIN is not set | 666 | # CONFIG_SOUND_MSNDPIN is not set |
629 | # CONFIG_SOUND_OSS is not set | 667 | # CONFIG_SOUND_OSS is not set |
630 | # CONFIG_SOUND_AD1980 is not set | ||
631 | 668 | ||
632 | # | 669 | # |
633 | # USB support | 670 | # USB support |
@@ -637,22 +674,21 @@ CONFIG_USB_ARCH_HAS_OHCI=y | |||
637 | # CONFIG_USB is not set | 674 | # CONFIG_USB is not set |
638 | 675 | ||
639 | # | 676 | # |
677 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
678 | # | ||
679 | |||
680 | # | ||
640 | # USB Gadget Support | 681 | # USB Gadget Support |
641 | # | 682 | # |
642 | CONFIG_USB_GADGET=y | 683 | # CONFIG_USB_GADGET is not set |
643 | # CONFIG_USB_GADGET_DEBUG_FILES is not set | ||
644 | CONFIG_USB_GADGET_SELECTED=y | ||
645 | # CONFIG_USB_GADGET_NET2280 is not set | 684 | # CONFIG_USB_GADGET_NET2280 is not set |
646 | # CONFIG_USB_GADGET_PXA2XX is not set | 685 | # CONFIG_USB_GADGET_PXA2XX is not set |
647 | # CONFIG_USB_GADGET_GOKU is not set | 686 | # CONFIG_USB_GADGET_GOKU is not set |
648 | # CONFIG_USB_GADGET_LH7A40X is not set | 687 | # CONFIG_USB_GADGET_LH7A40X is not set |
649 | CONFIG_USB_GADGET_OMAP=y | 688 | # CONFIG_USB_GADGET_OMAP is not set |
650 | CONFIG_USB_OMAP=y | ||
651 | # CONFIG_USB_GADGET_DUMMY_HCD is not set | 689 | # CONFIG_USB_GADGET_DUMMY_HCD is not set |
652 | # CONFIG_USB_GADGET_DUALSPEED is not set | ||
653 | # CONFIG_USB_ZERO is not set | 690 | # CONFIG_USB_ZERO is not set |
654 | CONFIG_USB_ETH=y | 691 | # CONFIG_USB_ETH is not set |
655 | CONFIG_USB_ETH_RNDIS=y | ||
656 | # CONFIG_USB_GADGETFS is not set | 692 | # CONFIG_USB_GADGETFS is not set |
657 | # CONFIG_USB_FILE_STORAGE is not set | 693 | # CONFIG_USB_FILE_STORAGE is not set |
658 | # CONFIG_USB_G_SERIAL is not set | 694 | # CONFIG_USB_G_SERIAL is not set |
@@ -673,10 +709,6 @@ CONFIG_EXT2_FS=y | |||
673 | # CONFIG_REISERFS_FS is not set | 709 | # CONFIG_REISERFS_FS is not set |
674 | # CONFIG_JFS_FS is not set | 710 | # CONFIG_JFS_FS is not set |
675 | # CONFIG_FS_POSIX_ACL is not set | 711 | # CONFIG_FS_POSIX_ACL is not set |
676 | |||
677 | # | ||
678 | # XFS support | ||
679 | # | ||
680 | # CONFIG_XFS_FS is not set | 712 | # CONFIG_XFS_FS is not set |
681 | # CONFIG_MINIX_FS is not set | 713 | # CONFIG_MINIX_FS is not set |
682 | CONFIG_ROMFS_FS=y | 714 | CONFIG_ROMFS_FS=y |
@@ -685,6 +717,7 @@ CONFIG_INOTIFY=y | |||
685 | CONFIG_DNOTIFY=y | 717 | CONFIG_DNOTIFY=y |
686 | # CONFIG_AUTOFS_FS is not set | 718 | # CONFIG_AUTOFS_FS is not set |
687 | # CONFIG_AUTOFS4_FS is not set | 719 | # CONFIG_AUTOFS4_FS is not set |
720 | # CONFIG_FUSE_FS is not set | ||
688 | 721 | ||
689 | # | 722 | # |
690 | # CD-ROM/DVD Filesystems | 723 | # CD-ROM/DVD Filesystems |
@@ -706,10 +739,10 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437 | |||
706 | # | 739 | # |
707 | CONFIG_PROC_FS=y | 740 | CONFIG_PROC_FS=y |
708 | CONFIG_SYSFS=y | 741 | CONFIG_SYSFS=y |
709 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
710 | # CONFIG_TMPFS is not set | 742 | # CONFIG_TMPFS is not set |
711 | # CONFIG_HUGETLB_PAGE is not set | 743 | # CONFIG_HUGETLB_PAGE is not set |
712 | CONFIG_RAMFS=y | 744 | CONFIG_RAMFS=y |
745 | # CONFIG_RELAYFS_FS is not set | ||
713 | 746 | ||
714 | # | 747 | # |
715 | # Miscellaneous filesystems | 748 | # Miscellaneous filesystems |
@@ -750,6 +783,7 @@ CONFIG_RPCSEC_GSS_KRB5=y | |||
750 | # CONFIG_NCP_FS is not set | 783 | # CONFIG_NCP_FS is not set |
751 | # CONFIG_CODA_FS is not set | 784 | # CONFIG_CODA_FS is not set |
752 | # CONFIG_AFS_FS is not set | 785 | # CONFIG_AFS_FS is not set |
786 | # CONFIG_9P_FS is not set | ||
753 | 787 | ||
754 | # | 788 | # |
755 | # Partition Types | 789 | # Partition Types |
@@ -859,6 +893,7 @@ CONFIG_CRYPTO_DES=y | |||
859 | # Library routines | 893 | # Library routines |
860 | # | 894 | # |
861 | # CONFIG_CRC_CCITT is not set | 895 | # CONFIG_CRC_CCITT is not set |
896 | # CONFIG_CRC16 is not set | ||
862 | CONFIG_CRC32=y | 897 | CONFIG_CRC32=y |
863 | # CONFIG_LIBCRC32C is not set | 898 | # CONFIG_LIBCRC32C is not set |
864 | CONFIG_ZLIB_INFLATE=y | 899 | CONFIG_ZLIB_INFLATE=y |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index ba298277becd..30494aab829a 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -86,12 +86,16 @@ EXPORT_SYMBOL(pm_power_off); | |||
86 | */ | 86 | */ |
87 | void default_idle(void) | 87 | void default_idle(void) |
88 | { | 88 | { |
89 | local_irq_disable(); | 89 | if (hlt_counter) |
90 | if (!need_resched() && !hlt_counter) { | 90 | cpu_relax(); |
91 | timer_dyn_reprogram(); | 91 | else { |
92 | arch_idle(); | 92 | local_irq_disable(); |
93 | if (!need_resched()) { | ||
94 | timer_dyn_reprogram(); | ||
95 | arch_idle(); | ||
96 | } | ||
97 | local_irq_enable(); | ||
93 | } | 98 | } |
94 | local_irq_enable(); | ||
95 | } | 99 | } |
96 | 100 | ||
97 | /* | 101 | /* |
@@ -116,13 +120,13 @@ void cpu_idle(void) | |||
116 | 120 | ||
117 | if (!idle) | 121 | if (!idle) |
118 | idle = default_idle; | 122 | idle = default_idle; |
119 | preempt_disable(); | ||
120 | leds_event(led_idle_start); | 123 | leds_event(led_idle_start); |
121 | while (!need_resched()) | 124 | while (!need_resched()) |
122 | idle(); | 125 | idle(); |
123 | leds_event(led_idle_end); | 126 | leds_event(led_idle_end); |
124 | preempt_enable(); | 127 | preempt_enable_no_resched(); |
125 | schedule(); | 128 | schedule(); |
129 | preempt_disable(); | ||
126 | } | 130 | } |
127 | } | 131 | } |
128 | 132 | ||
@@ -355,7 +359,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start, | |||
355 | struct thread_info *thread = p->thread_info; | 359 | struct thread_info *thread = p->thread_info; |
356 | struct pt_regs *childregs; | 360 | struct pt_regs *childregs; |
357 | 361 | ||
358 | childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1; | 362 | childregs = (void *)thread + THREAD_START_SP - sizeof(*regs); |
359 | *childregs = *regs; | 363 | *childregs = *regs; |
360 | childregs->ARM_r0 = 0; | 364 | childregs->ARM_r0 = 0; |
361 | childregs->ARM_sp = stack_start; | 365 | childregs->ARM_sp = stack_start; |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 77e2e9ca89fa..e55ea952f7aa 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -256,7 +256,9 @@ void __cpuexit cpu_die(void) | |||
256 | asmlinkage void __cpuinit secondary_start_kernel(void) | 256 | asmlinkage void __cpuinit secondary_start_kernel(void) |
257 | { | 257 | { |
258 | struct mm_struct *mm = &init_mm; | 258 | struct mm_struct *mm = &init_mm; |
259 | unsigned int cpu = smp_processor_id(); | 259 | unsigned int cpu; |
260 | |||
261 | cpu = smp_processor_id(); | ||
260 | 262 | ||
261 | printk("CPU%u: Booted secondary processor\n", cpu); | 263 | printk("CPU%u: Booted secondary processor\n", cpu); |
262 | 264 | ||
@@ -273,6 +275,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) | |||
273 | local_flush_tlb_all(); | 275 | local_flush_tlb_all(); |
274 | 276 | ||
275 | cpu_init(); | 277 | cpu_init(); |
278 | preempt_disable(); | ||
276 | 279 | ||
277 | /* | 280 | /* |
278 | * Give the platform a chance to do its own initialisation. | 281 | * Give the platform a chance to do its own initialisation. |
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index f35d91fbe117..b8c14e936697 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h | |||
@@ -34,7 +34,7 @@ | |||
34 | and r2, r0, #7 | 34 | and r2, r0, #7 |
35 | mov r3, #1 | 35 | mov r3, #1 |
36 | mov r3, r3, lsl r2 | 36 | mov r3, r3, lsl r2 |
37 | save_and_disable_irqs ip, r2 | 37 | save_and_disable_irqs ip |
38 | ldrb r2, [r1, r0, lsr #3] | 38 | ldrb r2, [r1, r0, lsr #3] |
39 | \instr r2, r2, r3 | 39 | \instr r2, r2, r3 |
40 | strb r2, [r1, r0, lsr #3] | 40 | strb r2, [r1, r0, lsr #3] |
@@ -54,7 +54,7 @@ | |||
54 | add r1, r1, r0, lsr #3 | 54 | add r1, r1, r0, lsr #3 |
55 | and r3, r0, #7 | 55 | and r3, r0, #7 |
56 | mov r0, #1 | 56 | mov r0, #1 |
57 | save_and_disable_irqs ip, r2 | 57 | save_and_disable_irqs ip |
58 | ldrb r2, [r1] | 58 | ldrb r2, [r1] |
59 | tst r2, r0, lsl r3 | 59 | tst r2, r0, lsl r3 |
60 | \instr r2, r2, r0, lsl r3 | 60 | \instr r2, r2, r0, lsl r3 |
diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S index cb5e3708f118..fe797cf320bb 100644 --- a/arch/arm/lib/csumpartial.S +++ b/arch/arm/lib/csumpartial.S | |||
@@ -39,6 +39,7 @@ td3 .req lr | |||
39 | 39 | ||
40 | /* we must have at least one byte. */ | 40 | /* we must have at least one byte. */ |
41 | tst buf, #1 @ odd address? | 41 | tst buf, #1 @ odd address? |
42 | movne sum, sum, ror #8 | ||
42 | ldrneb td0, [buf], #1 | 43 | ldrneb td0, [buf], #1 |
43 | subne len, len, #1 | 44 | subne len, len, #1 |
44 | adcnes sum, sum, td0, put_byte_1 | 45 | adcnes sum, sum, td0, put_byte_1 |
@@ -103,6 +104,9 @@ ENTRY(csum_partial) | |||
103 | cmp len, #8 @ Ensure that we have at least | 104 | cmp len, #8 @ Ensure that we have at least |
104 | blo .less8 @ 8 bytes to copy. | 105 | blo .less8 @ 8 bytes to copy. |
105 | 106 | ||
107 | tst buf, #1 | ||
108 | movne sum, sum, ror #8 | ||
109 | |||
106 | adds sum, sum, #0 @ C = 0 | 110 | adds sum, sum, #0 @ C = 0 |
107 | tst buf, #3 @ Test destination alignment | 111 | tst buf, #3 @ Test destination alignment |
108 | blne .not_aligned @ aligh destination, return here | 112 | blne .not_aligned @ aligh destination, return here |
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 89762a26495c..385285851cb5 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig | |||
@@ -8,6 +8,16 @@ menu "Intel IXP4xx Implementation Options" | |||
8 | 8 | ||
9 | comment "IXP4xx Platforms" | 9 | comment "IXP4xx Platforms" |
10 | 10 | ||
11 | # This entry is placed on top because otherwise it would have | ||
12 | # been shown as a submenu. | ||
13 | config MACH_NSLU2 | ||
14 | bool | ||
15 | prompt "NSLU2" if !(MACH_IXDP465 || MACH_IXDPG425 || ARCH_IXDP425 || ARCH_ADI_COYOTE || ARCH_AVILA || ARCH_IXCDP1100 || ARCH_PRPMC1100 || MACH_GTWX5715) | ||
16 | help | ||
17 | Say 'Y' here if you want your kernel to support Linksys's | ||
18 | NSLU2 NAS device. For more information on this platform, | ||
19 | see http://www.nslu2-linux.org | ||
20 | |||
11 | config ARCH_AVILA | 21 | config ARCH_AVILA |
12 | bool "Avila" | 22 | bool "Avila" |
13 | help | 23 | help |
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile index ddecbda4a633..7a15629c18d0 100644 --- a/arch/arm/mach-ixp4xx/Makefile +++ b/arch/arm/mach-ixp4xx/Makefile | |||
@@ -8,4 +8,5 @@ obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o | |||
8 | obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o | 8 | obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o |
9 | obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o | 9 | obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o |
10 | obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o | 10 | obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o |
11 | obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o | ||
11 | 12 | ||
diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c new file mode 100644 index 000000000000..a575f2e0b2c8 --- /dev/null +++ b/arch/arm/mach-ixp4xx/nslu2-pci.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-ixp4xx/nslu2-pci.c | ||
3 | * | ||
4 | * NSLU2 board-level PCI initialization | ||
5 | * | ||
6 | * based on ixdp425-pci.c: | ||
7 | * Copyright (C) 2002 Intel Corporation. | ||
8 | * Copyright (C) 2003-2004 MontaVista Software, Inc. | ||
9 | * | ||
10 | * Maintainer: http://www.nslu2-linux.org/ | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/config.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/init.h> | ||
21 | |||
22 | #include <asm/mach/pci.h> | ||
23 | #include <asm/mach-types.h> | ||
24 | |||
25 | void __init nslu2_pci_preinit(void) | ||
26 | { | ||
27 | set_irq_type(IRQ_NSLU2_PCI_INTA, IRQT_LOW); | ||
28 | set_irq_type(IRQ_NSLU2_PCI_INTB, IRQT_LOW); | ||
29 | set_irq_type(IRQ_NSLU2_PCI_INTC, IRQT_LOW); | ||
30 | |||
31 | gpio_line_isr_clear(NSLU2_PCI_INTA_PIN); | ||
32 | gpio_line_isr_clear(NSLU2_PCI_INTB_PIN); | ||
33 | gpio_line_isr_clear(NSLU2_PCI_INTC_PIN); | ||
34 | |||
35 | /* INTD is not configured as GPIO is used | ||
36 | * for the power input button. | ||
37 | */ | ||
38 | |||
39 | ixp4xx_pci_preinit(); | ||
40 | } | ||
41 | |||
42 | static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
43 | { | ||
44 | static int pci_irq_table[NSLU2_PCI_IRQ_LINES] = { | ||
45 | IRQ_NSLU2_PCI_INTA, | ||
46 | IRQ_NSLU2_PCI_INTB, | ||
47 | IRQ_NSLU2_PCI_INTC, | ||
48 | }; | ||
49 | |||
50 | int irq = -1; | ||
51 | |||
52 | if (slot >= 1 && slot <= NSLU2_PCI_MAX_DEV && | ||
53 | pin >= 1 && pin <= NSLU2_PCI_IRQ_LINES) { | ||
54 | irq = pci_irq_table[(slot + pin - 2) % NSLU2_PCI_IRQ_LINES]; | ||
55 | } | ||
56 | |||
57 | return irq; | ||
58 | } | ||
59 | |||
60 | struct hw_pci __initdata nslu2_pci = { | ||
61 | .nr_controllers = 1, | ||
62 | .preinit = nslu2_pci_preinit, | ||
63 | .swizzle = pci_std_swizzle, | ||
64 | .setup = ixp4xx_setup, | ||
65 | .scan = ixp4xx_scan_bus, | ||
66 | .map_irq = nslu2_map_irq, | ||
67 | }; | ||
68 | |||
69 | int __init nslu2_pci_init(void) /* monkey see, monkey do */ | ||
70 | { | ||
71 | if (machine_is_nslu2()) | ||
72 | pci_common_init(&nslu2_pci); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | subsys_initcall(nslu2_pci_init); | ||
diff --git a/arch/arm/mach-ixp4xx/nslu2-power.c b/arch/arm/mach-ixp4xx/nslu2-power.c new file mode 100644 index 000000000000..18fbc8c0fb30 --- /dev/null +++ b/arch/arm/mach-ixp4xx/nslu2-power.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-ixp4xx/nslu2-power.c | ||
3 | * | ||
4 | * NSLU2 Power/Reset driver | ||
5 | * | ||
6 | * Copyright (C) 2005 Tower Technologies | ||
7 | * | ||
8 | * based on nslu2-io.c | ||
9 | * Copyright (C) 2004 Karen Spearel | ||
10 | * | ||
11 | * Author: Alessandro Zummo <a.zummo@towertech.it> | ||
12 | * Maintainers: http://www.nslu2-linux.org/ | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License version 2 as | ||
16 | * published by the Free Software Foundation. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/reboot.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | |||
24 | #include <asm/mach-types.h> | ||
25 | |||
26 | extern void ctrl_alt_del(void); | ||
27 | |||
28 | static irqreturn_t nslu2_power_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
29 | { | ||
30 | /* Signal init to do the ctrlaltdel action, this will bypass init if | ||
31 | * it hasn't started and do a kernel_restart. | ||
32 | */ | ||
33 | ctrl_alt_del(); | ||
34 | |||
35 | return IRQ_HANDLED; | ||
36 | } | ||
37 | |||
38 | static irqreturn_t nslu2_reset_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
39 | { | ||
40 | /* This is the paper-clip reset, it shuts the machine down directly. | ||
41 | */ | ||
42 | machine_power_off(); | ||
43 | |||
44 | return IRQ_HANDLED; | ||
45 | } | ||
46 | |||
47 | static int __init nslu2_power_init(void) | ||
48 | { | ||
49 | if (!(machine_is_nslu2())) | ||
50 | return 0; | ||
51 | |||
52 | *IXP4XX_GPIO_GPISR = 0x20400000; /* read the 2 irqs to clr */ | ||
53 | |||
54 | set_irq_type(NSLU2_RB_IRQ, IRQT_LOW); | ||
55 | set_irq_type(NSLU2_PB_IRQ, IRQT_HIGH); | ||
56 | |||
57 | gpio_line_isr_clear(NSLU2_RB_GPIO); | ||
58 | gpio_line_isr_clear(NSLU2_PB_GPIO); | ||
59 | |||
60 | if (request_irq(NSLU2_RB_IRQ, &nslu2_reset_handler, | ||
61 | SA_INTERRUPT, "NSLU2 reset button", NULL) < 0) { | ||
62 | |||
63 | printk(KERN_DEBUG "Reset Button IRQ %d not available\n", | ||
64 | NSLU2_RB_IRQ); | ||
65 | |||
66 | return -EIO; | ||
67 | } | ||
68 | |||
69 | if (request_irq(NSLU2_PB_IRQ, &nslu2_power_handler, | ||
70 | SA_INTERRUPT, "NSLU2 power button", NULL) < 0) { | ||
71 | |||
72 | printk(KERN_DEBUG "Power Button IRQ %d not available\n", | ||
73 | NSLU2_PB_IRQ); | ||
74 | |||
75 | return -EIO; | ||
76 | } | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static void __exit nslu2_power_exit(void) | ||
82 | { | ||
83 | free_irq(NSLU2_RB_IRQ, NULL); | ||
84 | free_irq(NSLU2_PB_IRQ, NULL); | ||
85 | } | ||
86 | |||
87 | module_init(nslu2_power_init); | ||
88 | module_exit(nslu2_power_exit); | ||
89 | |||
90 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | ||
91 | MODULE_DESCRIPTION("NSLU2 Power/Reset driver"); | ||
92 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c new file mode 100644 index 000000000000..289e94cb65c2 --- /dev/null +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-ixp4xx/nslu2-setup.c | ||
3 | * | ||
4 | * NSLU2 board-setup | ||
5 | * | ||
6 | * based ixdp425-setup.c: | ||
7 | * Copyright (C) 2003-2004 MontaVista Software, Inc. | ||
8 | * | ||
9 | * Author: Mark Rakes <mrakes at mac.com> | ||
10 | * Maintainers: http://www.nslu2-linux.org/ | ||
11 | * | ||
12 | * Fixed missing init_time in MACHINE_START kas11 10/22/04 | ||
13 | * Changed to conform to new style __init ixdp425 kas11 10/22/04 | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/serial.h> | ||
18 | #include <linux/serial_8250.h> | ||
19 | |||
20 | #include <asm/mach-types.h> | ||
21 | #include <asm/mach/arch.h> | ||
22 | #include <asm/mach/flash.h> | ||
23 | |||
24 | static struct flash_platform_data nslu2_flash_data = { | ||
25 | .map_name = "cfi_probe", | ||
26 | .width = 2, | ||
27 | }; | ||
28 | |||
29 | static struct resource nslu2_flash_resource = { | ||
30 | .start = NSLU2_FLASH_BASE, | ||
31 | .end = NSLU2_FLASH_BASE + NSLU2_FLASH_SIZE, | ||
32 | .flags = IORESOURCE_MEM, | ||
33 | }; | ||
34 | |||
35 | static struct platform_device nslu2_flash = { | ||
36 | .name = "IXP4XX-Flash", | ||
37 | .id = 0, | ||
38 | .dev.platform_data = &nslu2_flash_data, | ||
39 | .num_resources = 1, | ||
40 | .resource = &nslu2_flash_resource, | ||
41 | }; | ||
42 | |||
43 | static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = { | ||
44 | .sda_pin = NSLU2_SDA_PIN, | ||
45 | .scl_pin = NSLU2_SCL_PIN, | ||
46 | }; | ||
47 | |||
48 | static struct platform_device nslu2_i2c_controller = { | ||
49 | .name = "IXP4XX-I2C", | ||
50 | .id = 0, | ||
51 | .dev.platform_data = &nslu2_i2c_gpio_pins, | ||
52 | .num_resources = 0, | ||
53 | }; | ||
54 | |||
55 | static struct resource nslu2_uart_resources[] = { | ||
56 | { | ||
57 | .start = IXP4XX_UART1_BASE_PHYS, | ||
58 | .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, | ||
59 | .flags = IORESOURCE_MEM, | ||
60 | }, | ||
61 | { | ||
62 | .start = IXP4XX_UART2_BASE_PHYS, | ||
63 | .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, | ||
64 | .flags = IORESOURCE_MEM, | ||
65 | } | ||
66 | }; | ||
67 | |||
68 | static struct plat_serial8250_port nslu2_uart_data[] = { | ||
69 | { | ||
70 | .mapbase = IXP4XX_UART1_BASE_PHYS, | ||
71 | .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, | ||
72 | .irq = IRQ_IXP4XX_UART1, | ||
73 | .flags = UPF_BOOT_AUTOCONF, | ||
74 | .iotype = UPIO_MEM, | ||
75 | .regshift = 2, | ||
76 | .uartclk = IXP4XX_UART_XTAL, | ||
77 | }, | ||
78 | { | ||
79 | .mapbase = IXP4XX_UART2_BASE_PHYS, | ||
80 | .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, | ||
81 | .irq = IRQ_IXP4XX_UART2, | ||
82 | .flags = UPF_BOOT_AUTOCONF, | ||
83 | .iotype = UPIO_MEM, | ||
84 | .regshift = 2, | ||
85 | .uartclk = IXP4XX_UART_XTAL, | ||
86 | }, | ||
87 | { } | ||
88 | }; | ||
89 | |||
90 | static struct platform_device nslu2_uart = { | ||
91 | .name = "serial8250", | ||
92 | .id = PLAT8250_DEV_PLATFORM, | ||
93 | .dev.platform_data = nslu2_uart_data, | ||
94 | .num_resources = 2, | ||
95 | .resource = nslu2_uart_resources, | ||
96 | }; | ||
97 | |||
98 | static struct platform_device *nslu2_devices[] __initdata = { | ||
99 | &nslu2_i2c_controller, | ||
100 | &nslu2_flash, | ||
101 | &nslu2_uart, | ||
102 | }; | ||
103 | |||
104 | static void nslu2_power_off(void) | ||
105 | { | ||
106 | /* This causes the box to drop the power and go dead. */ | ||
107 | |||
108 | /* enable the pwr cntl gpio */ | ||
109 | gpio_line_config(NSLU2_PO_GPIO, IXP4XX_GPIO_OUT); | ||
110 | |||
111 | /* do the deed */ | ||
112 | gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH); | ||
113 | } | ||
114 | |||
115 | static void __init nslu2_init(void) | ||
116 | { | ||
117 | ixp4xx_sys_init(); | ||
118 | |||
119 | pm_power_off = nslu2_power_off; | ||
120 | |||
121 | platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices)); | ||
122 | } | ||
123 | |||
124 | MACHINE_START(NSLU2, "Linksys NSLU2") | ||
125 | /* Maintainer: www.nslu2-linux.org */ | ||
126 | .phys_ram = PHYS_OFFSET, | ||
127 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | ||
128 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, | ||
129 | .boot_params = 0x00000100, | ||
130 | .map_io = ixp4xx_map_io, | ||
131 | .init_irq = ixp4xx_init_irq, | ||
132 | .timer = &ixp4xx_timer, | ||
133 | .init_machine = nslu2_init, | ||
134 | MACHINE_END | ||
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index 27fc2e8e5fca..86a0f0d14345 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig | |||
@@ -6,10 +6,10 @@ config ARCH_OMAP730 | |||
6 | bool "OMAP730 Based System" | 6 | bool "OMAP730 Based System" |
7 | select ARCH_OMAP_OTG | 7 | select ARCH_OMAP_OTG |
8 | 8 | ||
9 | config ARCH_OMAP1510 | 9 | config ARCH_OMAP15XX |
10 | depends on ARCH_OMAP1 | 10 | depends on ARCH_OMAP1 |
11 | default y | 11 | default y |
12 | bool "OMAP1510 Based System" | 12 | bool "OMAP15xx Based System" |
13 | 13 | ||
14 | config ARCH_OMAP16XX | 14 | config ARCH_OMAP16XX |
15 | depends on ARCH_OMAP1 | 15 | depends on ARCH_OMAP1 |
@@ -21,7 +21,7 @@ comment "OMAP Board Type" | |||
21 | 21 | ||
22 | config MACH_OMAP_INNOVATOR | 22 | config MACH_OMAP_INNOVATOR |
23 | bool "TI Innovator" | 23 | bool "TI Innovator" |
24 | depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX) | 24 | depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX) |
25 | help | 25 | help |
26 | TI OMAP 1510 or 1610 Innovator board support. Say Y here if you | 26 | TI OMAP 1510 or 1610 Innovator board support. Say Y here if you |
27 | have such a board. | 27 | have such a board. |
@@ -64,20 +64,30 @@ config MACH_OMAP_PERSEUS2 | |||
64 | 64 | ||
65 | config MACH_VOICEBLUE | 65 | config MACH_VOICEBLUE |
66 | bool "Voiceblue" | 66 | bool "Voiceblue" |
67 | depends on ARCH_OMAP1 && ARCH_OMAP1510 | 67 | depends on ARCH_OMAP1 && ARCH_OMAP15XX |
68 | help | 68 | help |
69 | Support for Voiceblue GSM/VoIP gateway. Say Y here if you have | 69 | Support for Voiceblue GSM/VoIP gateway. Say Y here if you have |
70 | such a board. | 70 | such a board. |
71 | 71 | ||
72 | config MACH_NETSTAR | 72 | config MACH_NETSTAR |
73 | bool "NetStar" | 73 | bool "NetStar" |
74 | depends on ARCH_OMAP1 && ARCH_OMAP1510 | 74 | depends on ARCH_OMAP1 && ARCH_OMAP15XX |
75 | help | 75 | help |
76 | Support for NetStar PBX. Say Y here if you have such a board. | 76 | Support for NetStar PBX. Say Y here if you have such a board. |
77 | 77 | ||
78 | config MACH_OMAP_PALMTE | ||
79 | bool "Palm Tungsten E" | ||
80 | depends on ARCH_OMAP1 && ARCH_OMAP15XX | ||
81 | help | ||
82 | Support for the Palm Tungsten E PDA. Currently only the LCD panel | ||
83 | is supported. To boot the kernel, you'll need a PalmOS compatible | ||
84 | bootloader; check out http://palmtelinux.sourceforge.net for more | ||
85 | informations. | ||
86 | Say Y here if you have such a PDA, say NO otherwise. | ||
87 | |||
78 | config MACH_OMAP_GENERIC | 88 | config MACH_OMAP_GENERIC |
79 | bool "Generic OMAP board" | 89 | bool "Generic OMAP board" |
80 | depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX) | 90 | depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX) |
81 | help | 91 | help |
82 | Support for generic OMAP-1510, 1610 or 1710 board with | 92 | Support for generic OMAP-1510, 1610 or 1710 board with |
83 | no FPGA. Can be used as template for porting Linux to | 93 | no FPGA. Can be used as template for porting Linux to |
@@ -121,32 +131,32 @@ config OMAP_ARM_182MHZ | |||
121 | 131 | ||
122 | config OMAP_ARM_168MHZ | 132 | config OMAP_ARM_168MHZ |
123 | bool "OMAP ARM 168 MHz CPU" | 133 | bool "OMAP ARM 168 MHz CPU" |
124 | depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) | 134 | depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730) |
125 | help | 135 | help |
126 | Enable 168MHz clock for OMAP CPU. If unsure, say N. | 136 | Enable 168MHz clock for OMAP CPU. If unsure, say N. |
127 | 137 | ||
128 | config OMAP_ARM_150MHZ | 138 | config OMAP_ARM_150MHZ |
129 | bool "OMAP ARM 150 MHz CPU" | 139 | bool "OMAP ARM 150 MHz CPU" |
130 | depends on ARCH_OMAP1 && ARCH_OMAP1510 | 140 | depends on ARCH_OMAP1 && ARCH_OMAP15XX |
131 | help | 141 | help |
132 | Enable 150MHz clock for OMAP CPU. If unsure, say N. | 142 | Enable 150MHz clock for OMAP CPU. If unsure, say N. |
133 | 143 | ||
134 | config OMAP_ARM_120MHZ | 144 | config OMAP_ARM_120MHZ |
135 | bool "OMAP ARM 120 MHz CPU" | 145 | bool "OMAP ARM 120 MHz CPU" |
136 | depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) | 146 | depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730) |
137 | help | 147 | help |
138 | Enable 120MHz clock for OMAP CPU. If unsure, say N. | 148 | Enable 120MHz clock for OMAP CPU. If unsure, say N. |
139 | 149 | ||
140 | config OMAP_ARM_60MHZ | 150 | config OMAP_ARM_60MHZ |
141 | bool "OMAP ARM 60 MHz CPU" | 151 | bool "OMAP ARM 60 MHz CPU" |
142 | depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) | 152 | depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730) |
143 | default y | 153 | default y |
144 | help | 154 | help |
145 | Enable 60MHz clock for OMAP CPU. If unsure, say Y. | 155 | Enable 60MHz clock for OMAP CPU. If unsure, say Y. |
146 | 156 | ||
147 | config OMAP_ARM_30MHZ | 157 | config OMAP_ARM_30MHZ |
148 | bool "OMAP ARM 30 MHz CPU" | 158 | bool "OMAP ARM 30 MHz CPU" |
149 | depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730) | 159 | depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730) |
150 | help | 160 | help |
151 | Enable 30MHz clock for OMAP CPU. If unsure, say N. | 161 | Enable 30MHz clock for OMAP CPU. If unsure, say N. |
152 | 162 | ||
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index 181a93deaaee..b0b00156faae 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := io.o id.o irq.o time.o serial.o devices.o | 6 | obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o |
7 | led-y := leds.o | 7 | led-y := leds.o |
8 | 8 | ||
9 | # Specific board support | 9 | # Specific board support |
@@ -15,8 +15,9 @@ obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o | |||
15 | obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o | 15 | obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o |
16 | obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o | 16 | obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o |
17 | obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o | 17 | obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o |
18 | obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o | ||
18 | 19 | ||
19 | ifeq ($(CONFIG_ARCH_OMAP1510),y) | 20 | ifeq ($(CONFIG_ARCH_OMAP15XX),y) |
20 | # Innovator-1510 FPGA | 21 | # Innovator-1510 FPGA |
21 | obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o | 22 | obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o |
22 | endif | 23 | endif |
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c index c209c7172a9a..4b292e93fbe2 100644 --- a/arch/arm/mach-omap1/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/device.h> | 18 | #include <linux/platform_device.h> |
19 | 19 | ||
20 | #include <asm/hardware.h> | 20 | #include <asm/hardware.h> |
21 | #include <asm/mach-types.h> | 21 | #include <asm/mach-types.h> |
@@ -28,8 +28,6 @@ | |||
28 | #include <asm/arch/board.h> | 28 | #include <asm/arch/board.h> |
29 | #include <asm/arch/common.h> | 29 | #include <asm/arch/common.h> |
30 | 30 | ||
31 | static int __initdata generic_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; | ||
32 | |||
33 | static void __init omap_generic_init_irq(void) | 31 | static void __init omap_generic_init_irq(void) |
34 | { | 32 | { |
35 | omap_init_irq(); | 33 | omap_init_irq(); |
@@ -37,7 +35,7 @@ static void __init omap_generic_init_irq(void) | |||
37 | 35 | ||
38 | /* assume no Mini-AB port */ | 36 | /* assume no Mini-AB port */ |
39 | 37 | ||
40 | #ifdef CONFIG_ARCH_OMAP1510 | 38 | #ifdef CONFIG_ARCH_OMAP15XX |
41 | static struct omap_usb_config generic1510_usb_config __initdata = { | 39 | static struct omap_usb_config generic1510_usb_config __initdata = { |
42 | .register_host = 1, | 40 | .register_host = 1, |
43 | .register_dev = 1, | 41 | .register_dev = 1, |
@@ -76,21 +74,19 @@ static struct omap_mmc_config generic_mmc_config __initdata = { | |||
76 | 74 | ||
77 | #endif | 75 | #endif |
78 | 76 | ||
77 | static struct omap_uart_config generic_uart_config __initdata = { | ||
78 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
79 | }; | ||
80 | |||
79 | static struct omap_board_config_kernel generic_config[] = { | 81 | static struct omap_board_config_kernel generic_config[] = { |
80 | { OMAP_TAG_USB, NULL }, | 82 | { OMAP_TAG_USB, NULL }, |
81 | { OMAP_TAG_MMC, &generic_mmc_config }, | 83 | { OMAP_TAG_MMC, &generic_mmc_config }, |
84 | { OMAP_TAG_UART, &generic_uart_config }, | ||
82 | }; | 85 | }; |
83 | 86 | ||
84 | static void __init omap_generic_init(void) | 87 | static void __init omap_generic_init(void) |
85 | { | 88 | { |
86 | const struct omap_uart_config *uart_conf; | 89 | #ifdef CONFIG_ARCH_OMAP15XX |
87 | |||
88 | /* | ||
89 | * Make sure the serial ports are muxed on at this point. | ||
90 | * You have to mux them off in device drivers later on | ||
91 | * if not needed. | ||
92 | */ | ||
93 | #ifdef CONFIG_ARCH_OMAP1510 | ||
94 | if (cpu_is_omap1510()) { | 90 | if (cpu_is_omap1510()) { |
95 | generic_config[0].data = &generic1510_usb_config; | 91 | generic_config[0].data = &generic1510_usb_config; |
96 | } | 92 | } |
@@ -101,20 +97,9 @@ static void __init omap_generic_init(void) | |||
101 | } | 97 | } |
102 | #endif | 98 | #endif |
103 | 99 | ||
104 | uart_conf = omap_get_config(OMAP_TAG_UART, struct omap_uart_config); | ||
105 | if (uart_conf != NULL) { | ||
106 | unsigned int enabled_ports, i; | ||
107 | |||
108 | enabled_ports = uart_conf->enabled_uarts; | ||
109 | for (i = 0; i < 3; i++) { | ||
110 | if (!(enabled_ports & (1 << i))) | ||
111 | generic_serial_ports[i] = 0; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | omap_board_config = generic_config; | 100 | omap_board_config = generic_config; |
116 | omap_board_config_size = ARRAY_SIZE(generic_config); | 101 | omap_board_config_size = ARRAY_SIZE(generic_config); |
117 | omap_serial_init(generic_serial_ports); | 102 | omap_serial_init(); |
118 | } | 103 | } |
119 | 104 | ||
120 | static void __init omap_generic_map_io(void) | 105 | static void __init omap_generic_map_io(void) |
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 4ee6bd8a50b8..a07e2c9307fa 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c | |||
@@ -40,8 +40,6 @@ | |||
40 | 40 | ||
41 | extern int omap_gpio_init(void); | 41 | extern int omap_gpio_init(void); |
42 | 42 | ||
43 | static int __initdata h2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; | ||
44 | |||
45 | static struct mtd_partition h2_partitions[] = { | 43 | static struct mtd_partition h2_partitions[] = { |
46 | /* bootloader (U-Boot, etc) in first sector */ | 44 | /* bootloader (U-Boot, etc) in first sector */ |
47 | { | 45 | { |
@@ -160,9 +158,20 @@ static struct omap_mmc_config h2_mmc_config __initdata = { | |||
160 | }, | 158 | }, |
161 | }; | 159 | }; |
162 | 160 | ||
161 | static struct omap_uart_config h2_uart_config __initdata = { | ||
162 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
163 | }; | ||
164 | |||
165 | static struct omap_lcd_config h2_lcd_config __initdata = { | ||
166 | .panel_name = "h2", | ||
167 | .ctrl_name = "internal", | ||
168 | }; | ||
169 | |||
163 | static struct omap_board_config_kernel h2_config[] = { | 170 | static struct omap_board_config_kernel h2_config[] = { |
164 | { OMAP_TAG_USB, &h2_usb_config }, | 171 | { OMAP_TAG_USB, &h2_usb_config }, |
165 | { OMAP_TAG_MMC, &h2_mmc_config }, | 172 | { OMAP_TAG_MMC, &h2_mmc_config }, |
173 | { OMAP_TAG_UART, &h2_uart_config }, | ||
174 | { OMAP_TAG_LCD, &h2_lcd_config }, | ||
166 | }; | 175 | }; |
167 | 176 | ||
168 | static void __init h2_init(void) | 177 | static void __init h2_init(void) |
@@ -180,12 +189,12 @@ static void __init h2_init(void) | |||
180 | platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); | 189 | platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); |
181 | omap_board_config = h2_config; | 190 | omap_board_config = h2_config; |
182 | omap_board_config_size = ARRAY_SIZE(h2_config); | 191 | omap_board_config_size = ARRAY_SIZE(h2_config); |
192 | omap_serial_init(); | ||
183 | } | 193 | } |
184 | 194 | ||
185 | static void __init h2_map_io(void) | 195 | static void __init h2_map_io(void) |
186 | { | 196 | { |
187 | omap_map_common_io(); | 197 | omap_map_common_io(); |
188 | omap_serial_init(h2_serial_ports); | ||
189 | } | 198 | } |
190 | 199 | ||
191 | MACHINE_START(OMAP_H2, "TI-H2") | 200 | MACHINE_START(OMAP_H2, "TI-H2") |
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index fc824361430d..668e278433c2 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c | |||
@@ -41,8 +41,6 @@ | |||
41 | 41 | ||
42 | extern int omap_gpio_init(void); | 42 | extern int omap_gpio_init(void); |
43 | 43 | ||
44 | static int __initdata h3_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; | ||
45 | |||
46 | static struct mtd_partition h3_partitions[] = { | 44 | static struct mtd_partition h3_partitions[] = { |
47 | /* bootloader (U-Boot, etc) in first sector */ | 45 | /* bootloader (U-Boot, etc) in first sector */ |
48 | { | 46 | { |
@@ -168,9 +166,20 @@ static struct omap_mmc_config h3_mmc_config __initdata = { | |||
168 | }, | 166 | }, |
169 | }; | 167 | }; |
170 | 168 | ||
169 | static struct omap_uart_config h3_uart_config __initdata = { | ||
170 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
171 | }; | ||
172 | |||
173 | static struct omap_lcd_config h3_lcd_config __initdata = { | ||
174 | .panel_name = "h3", | ||
175 | .ctrl_name = "internal", | ||
176 | }; | ||
177 | |||
171 | static struct omap_board_config_kernel h3_config[] = { | 178 | static struct omap_board_config_kernel h3_config[] = { |
172 | { OMAP_TAG_USB, &h3_usb_config }, | 179 | { OMAP_TAG_USB, &h3_usb_config }, |
173 | { OMAP_TAG_MMC, &h3_mmc_config }, | 180 | { OMAP_TAG_MMC, &h3_mmc_config }, |
181 | { OMAP_TAG_UART, &h3_uart_config }, | ||
182 | { OMAP_TAG_LCD, &h3_lcd_config }, | ||
174 | }; | 183 | }; |
175 | 184 | ||
176 | static void __init h3_init(void) | 185 | static void __init h3_init(void) |
@@ -180,6 +189,7 @@ static void __init h3_init(void) | |||
180 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); | 189 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); |
181 | omap_board_config = h3_config; | 190 | omap_board_config = h3_config; |
182 | omap_board_config_size = ARRAY_SIZE(h3_config); | 191 | omap_board_config_size = ARRAY_SIZE(h3_config); |
192 | omap_serial_init(); | ||
183 | } | 193 | } |
184 | 194 | ||
185 | static void __init h3_init_smc91x(void) | 195 | static void __init h3_init_smc91x(void) |
@@ -201,7 +211,6 @@ void h3_init_irq(void) | |||
201 | static void __init h3_map_io(void) | 211 | static void __init h3_map_io(void) |
202 | { | 212 | { |
203 | omap_map_common_io(); | 213 | omap_map_common_io(); |
204 | omap_serial_init(h3_serial_ports); | ||
205 | } | 214 | } |
206 | 215 | ||
207 | MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") | 216 | MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") |
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index a2eac853b2da..95f1ff36cdcb 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c | |||
@@ -36,8 +36,6 @@ | |||
36 | #include <asm/arch/usb.h> | 36 | #include <asm/arch/usb.h> |
37 | #include <asm/arch/common.h> | 37 | #include <asm/arch/common.h> |
38 | 38 | ||
39 | static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; | ||
40 | |||
41 | static struct mtd_partition innovator_partitions[] = { | 39 | static struct mtd_partition innovator_partitions[] = { |
42 | /* bootloader (U-Boot, etc) in first sector */ | 40 | /* bootloader (U-Boot, etc) in first sector */ |
43 | { | 41 | { |
@@ -99,7 +97,7 @@ static struct platform_device innovator_flash_device = { | |||
99 | .resource = &innovator_flash_resource, | 97 | .resource = &innovator_flash_resource, |
100 | }; | 98 | }; |
101 | 99 | ||
102 | #ifdef CONFIG_ARCH_OMAP1510 | 100 | #ifdef CONFIG_ARCH_OMAP15XX |
103 | 101 | ||
104 | /* Only FPGA needs to be mapped here. All others are done with ioremap */ | 102 | /* Only FPGA needs to be mapped here. All others are done with ioremap */ |
105 | static struct map_desc innovator1510_io_desc[] __initdata = { | 103 | static struct map_desc innovator1510_io_desc[] __initdata = { |
@@ -136,7 +134,7 @@ static struct platform_device *innovator1510_devices[] __initdata = { | |||
136 | &innovator1510_smc91x_device, | 134 | &innovator1510_smc91x_device, |
137 | }; | 135 | }; |
138 | 136 | ||
139 | #endif /* CONFIG_ARCH_OMAP1510 */ | 137 | #endif /* CONFIG_ARCH_OMAP15XX */ |
140 | 138 | ||
141 | #ifdef CONFIG_ARCH_OMAP16XX | 139 | #ifdef CONFIG_ARCH_OMAP16XX |
142 | 140 | ||
@@ -185,7 +183,7 @@ void innovator_init_irq(void) | |||
185 | { | 183 | { |
186 | omap_init_irq(); | 184 | omap_init_irq(); |
187 | omap_gpio_init(); | 185 | omap_gpio_init(); |
188 | #ifdef CONFIG_ARCH_OMAP1510 | 186 | #ifdef CONFIG_ARCH_OMAP15XX |
189 | if (cpu_is_omap1510()) { | 187 | if (cpu_is_omap1510()) { |
190 | omap1510_fpga_init_irq(); | 188 | omap1510_fpga_init_irq(); |
191 | } | 189 | } |
@@ -193,7 +191,7 @@ void innovator_init_irq(void) | |||
193 | innovator_init_smc91x(); | 191 | innovator_init_smc91x(); |
194 | } | 192 | } |
195 | 193 | ||
196 | #ifdef CONFIG_ARCH_OMAP1510 | 194 | #ifdef CONFIG_ARCH_OMAP15XX |
197 | static struct omap_usb_config innovator1510_usb_config __initdata = { | 195 | static struct omap_usb_config innovator1510_usb_config __initdata = { |
198 | /* for bundled non-standard host and peripheral cables */ | 196 | /* for bundled non-standard host and peripheral cables */ |
199 | .hmc_mode = 4, | 197 | .hmc_mode = 4, |
@@ -205,6 +203,11 @@ static struct omap_usb_config innovator1510_usb_config __initdata = { | |||
205 | .register_dev = 1, | 203 | .register_dev = 1, |
206 | .pins[0] = 2, | 204 | .pins[0] = 2, |
207 | }; | 205 | }; |
206 | |||
207 | static struct omap_lcd_config innovator1510_lcd_config __initdata = { | ||
208 | .panel_name = "inn1510", | ||
209 | .ctrl_name = "internal", | ||
210 | }; | ||
208 | #endif | 211 | #endif |
209 | 212 | ||
210 | #ifdef CONFIG_ARCH_OMAP16XX | 213 | #ifdef CONFIG_ARCH_OMAP16XX |
@@ -222,6 +225,11 @@ static struct omap_usb_config h2_usb_config __initdata = { | |||
222 | 225 | ||
223 | .pins[1] = 3, | 226 | .pins[1] = 3, |
224 | }; | 227 | }; |
228 | |||
229 | static struct omap_lcd_config innovator1610_lcd_config __initdata = { | ||
230 | .panel_name = "inn1610", | ||
231 | .ctrl_name = "internal", | ||
232 | }; | ||
225 | #endif | 233 | #endif |
226 | 234 | ||
227 | static struct omap_mmc_config innovator_mmc_config __initdata = { | 235 | static struct omap_mmc_config innovator_mmc_config __initdata = { |
@@ -234,14 +242,20 @@ static struct omap_mmc_config innovator_mmc_config __initdata = { | |||
234 | }, | 242 | }, |
235 | }; | 243 | }; |
236 | 244 | ||
245 | static struct omap_uart_config innovator_uart_config __initdata = { | ||
246 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
247 | }; | ||
248 | |||
237 | static struct omap_board_config_kernel innovator_config[] = { | 249 | static struct omap_board_config_kernel innovator_config[] = { |
238 | { OMAP_TAG_USB, NULL }, | 250 | { OMAP_TAG_USB, NULL }, |
251 | { OMAP_TAG_LCD, NULL }, | ||
239 | { OMAP_TAG_MMC, &innovator_mmc_config }, | 252 | { OMAP_TAG_MMC, &innovator_mmc_config }, |
253 | { OMAP_TAG_UART, &innovator_uart_config }, | ||
240 | }; | 254 | }; |
241 | 255 | ||
242 | static void __init innovator_init(void) | 256 | static void __init innovator_init(void) |
243 | { | 257 | { |
244 | #ifdef CONFIG_ARCH_OMAP1510 | 258 | #ifdef CONFIG_ARCH_OMAP15XX |
245 | if (cpu_is_omap1510()) { | 259 | if (cpu_is_omap1510()) { |
246 | platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices)); | 260 | platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices)); |
247 | } | 261 | } |
@@ -252,23 +266,28 @@ static void __init innovator_init(void) | |||
252 | } | 266 | } |
253 | #endif | 267 | #endif |
254 | 268 | ||
255 | #ifdef CONFIG_ARCH_OMAP1510 | 269 | #ifdef CONFIG_ARCH_OMAP15XX |
256 | if (cpu_is_omap1510()) | 270 | if (cpu_is_omap1510()) { |
257 | innovator_config[0].data = &innovator1510_usb_config; | 271 | innovator_config[0].data = &innovator1510_usb_config; |
272 | innovator_config[1].data = &innovator1510_lcd_config; | ||
273 | } | ||
258 | #endif | 274 | #endif |
259 | #ifdef CONFIG_ARCH_OMAP16XX | 275 | #ifdef CONFIG_ARCH_OMAP16XX |
260 | if (cpu_is_omap1610()) | 276 | if (cpu_is_omap1610()) { |
261 | innovator_config[0].data = &h2_usb_config; | 277 | innovator_config[0].data = &h2_usb_config; |
278 | innovator_config[1].data = &innovator1610_lcd_config; | ||
279 | } | ||
262 | #endif | 280 | #endif |
263 | omap_board_config = innovator_config; | 281 | omap_board_config = innovator_config; |
264 | omap_board_config_size = ARRAY_SIZE(innovator_config); | 282 | omap_board_config_size = ARRAY_SIZE(innovator_config); |
283 | omap_serial_init(); | ||
265 | } | 284 | } |
266 | 285 | ||
267 | static void __init innovator_map_io(void) | 286 | static void __init innovator_map_io(void) |
268 | { | 287 | { |
269 | omap_map_common_io(); | 288 | omap_map_common_io(); |
270 | 289 | ||
271 | #ifdef CONFIG_ARCH_OMAP1510 | 290 | #ifdef CONFIG_ARCH_OMAP15XX |
272 | if (cpu_is_omap1510()) { | 291 | if (cpu_is_omap1510()) { |
273 | iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc)); | 292 | iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc)); |
274 | udelay(10); /* Delay needed for FPGA */ | 293 | udelay(10); /* Delay needed for FPGA */ |
@@ -280,7 +299,6 @@ static void __init innovator_map_io(void) | |||
280 | fpga_read(OMAP1510_FPGA_BOARD_REV)); | 299 | fpga_read(OMAP1510_FPGA_BOARD_REV)); |
281 | } | 300 | } |
282 | #endif | 301 | #endif |
283 | omap_serial_init(innovator_serial_ports); | ||
284 | } | 302 | } |
285 | 303 | ||
286 | MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") | 304 | MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") |
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c index c851c2e4dfcb..0448fa7de8a4 100644 --- a/arch/arm/mach-omap1/board-netstar.c +++ b/arch/arm/mach-omap1/board-netstar.c | |||
@@ -55,6 +55,14 @@ static struct platform_device *netstar_devices[] __initdata = { | |||
55 | &netstar_smc91x_device, | 55 | &netstar_smc91x_device, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | static struct omap_uart_config netstar_uart_config __initdata = { | ||
59 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
60 | }; | ||
61 | |||
62 | static struct omap_board_config_kernel netstar_config[] = { | ||
63 | { OMAP_TAG_UART, &netstar_uart_config }, | ||
64 | }; | ||
65 | |||
58 | static void __init netstar_init_irq(void) | 66 | static void __init netstar_init_irq(void) |
59 | { | 67 | { |
60 | omap_init_irq(); | 68 | omap_init_irq(); |
@@ -92,14 +100,15 @@ static void __init netstar_init(void) | |||
92 | /* Switch off red LED */ | 100 | /* Switch off red LED */ |
93 | omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ | 101 | omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ |
94 | omap_writeb(0x80, OMAP_LPG1_LCR); | 102 | omap_writeb(0x80, OMAP_LPG1_LCR); |
95 | } | ||
96 | 103 | ||
97 | static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; | 104 | omap_board_config = netstar_config; |
105 | omap_board_config_size = ARRAY_SIZE(netstar_config); | ||
106 | omap_serial_init(); | ||
107 | } | ||
98 | 108 | ||
99 | static void __init netstar_map_io(void) | 109 | static void __init netstar_map_io(void) |
100 | { | 110 | { |
101 | omap_map_common_io(); | 111 | omap_map_common_io(); |
102 | omap_serial_init(omap_serial_ports); | ||
103 | } | 112 | } |
104 | 113 | ||
105 | #define MACHINE_PANICED 1 | 114 | #define MACHINE_PANICED 1 |
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index a88524e7c315..e990e1bc1669 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c | |||
@@ -46,8 +46,6 @@ | |||
46 | #include <asm/arch/tc.h> | 46 | #include <asm/arch/tc.h> |
47 | #include <asm/arch/common.h> | 47 | #include <asm/arch/common.h> |
48 | 48 | ||
49 | static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0}; | ||
50 | |||
51 | static struct mtd_partition osk_partitions[] = { | 49 | static struct mtd_partition osk_partitions[] = { |
52 | /* bootloader (U-Boot, etc) in first sector */ | 50 | /* bootloader (U-Boot, etc) in first sector */ |
53 | { | 51 | { |
@@ -155,7 +153,7 @@ static void __init osk_init_smc91x(void) | |||
155 | } | 153 | } |
156 | 154 | ||
157 | /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */ | 155 | /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */ |
158 | EMIFS_CCS(1) |= 0x2; | 156 | EMIFS_CCS(1) |= 0x3; |
159 | } | 157 | } |
160 | 158 | ||
161 | static void __init osk_init_cf(void) | 159 | static void __init osk_init_cf(void) |
@@ -193,8 +191,19 @@ static struct omap_usb_config osk_usb_config __initdata = { | |||
193 | .pins[0] = 2, | 191 | .pins[0] = 2, |
194 | }; | 192 | }; |
195 | 193 | ||
194 | static struct omap_uart_config osk_uart_config __initdata = { | ||
195 | .enabled_uarts = (1 << 0), | ||
196 | }; | ||
197 | |||
198 | static struct omap_lcd_config osk_lcd_config __initdata = { | ||
199 | .panel_name = "osk", | ||
200 | .ctrl_name = "internal", | ||
201 | }; | ||
202 | |||
196 | static struct omap_board_config_kernel osk_config[] = { | 203 | static struct omap_board_config_kernel osk_config[] = { |
197 | { OMAP_TAG_USB, &osk_usb_config }, | 204 | { OMAP_TAG_USB, &osk_usb_config }, |
205 | { OMAP_TAG_UART, &osk_uart_config }, | ||
206 | { OMAP_TAG_LCD, &osk_lcd_config }, | ||
198 | }; | 207 | }; |
199 | 208 | ||
200 | #ifdef CONFIG_OMAP_OSK_MISTRAL | 209 | #ifdef CONFIG_OMAP_OSK_MISTRAL |
@@ -254,13 +263,13 @@ static void __init osk_init(void) | |||
254 | omap_board_config_size = ARRAY_SIZE(osk_config); | 263 | omap_board_config_size = ARRAY_SIZE(osk_config); |
255 | USB_TRANSCEIVER_CTRL_REG |= (3 << 1); | 264 | USB_TRANSCEIVER_CTRL_REG |= (3 << 1); |
256 | 265 | ||
266 | omap_serial_init(); | ||
257 | osk_mistral_init(); | 267 | osk_mistral_init(); |
258 | } | 268 | } |
259 | 269 | ||
260 | static void __init osk_map_io(void) | 270 | static void __init osk_map_io(void) |
261 | { | 271 | { |
262 | omap_map_common_io(); | 272 | omap_map_common_io(); |
263 | omap_serial_init(osk_serial_ports); | ||
264 | } | 273 | } |
265 | 274 | ||
266 | MACHINE_START(OMAP_OSK, "TI-OSK") | 275 | MACHINE_START(OMAP_OSK, "TI-OSK") |
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c new file mode 100644 index 000000000000..540b20d78cca --- /dev/null +++ b/arch/arm/mach-omap1/board-palmte.c | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap1/board-palmte.c | ||
3 | * | ||
4 | * Modified from board-generic.c | ||
5 | * | ||
6 | * Support for the Palm Tungsten E PDA. | ||
7 | * | ||
8 | * Original version : Laurent Gonzalez | ||
9 | * | ||
10 | * Maintainters : http://palmtelinux.sf.net | ||
11 | * palmtelinux-developpers@lists.sf.net | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 as | ||
15 | * published by the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/notifier.h> | ||
22 | |||
23 | #include <asm/hardware.h> | ||
24 | #include <asm/mach-types.h> | ||
25 | #include <asm/mach/arch.h> | ||
26 | #include <asm/mach/map.h> | ||
27 | |||
28 | #include <asm/arch/gpio.h> | ||
29 | #include <asm/arch/mux.h> | ||
30 | #include <asm/arch/usb.h> | ||
31 | #include <asm/arch/board.h> | ||
32 | #include <asm/arch/common.h> | ||
33 | #include <asm/hardware/clock.h> | ||
34 | |||
35 | static void __init omap_generic_init_irq(void) | ||
36 | { | ||
37 | omap_init_irq(); | ||
38 | } | ||
39 | |||
40 | static struct omap_usb_config palmte_usb_config __initdata = { | ||
41 | .register_dev = 1, | ||
42 | .hmc_mode = 0, | ||
43 | .pins[0] = 3, | ||
44 | }; | ||
45 | |||
46 | static struct omap_mmc_config palmte_mmc_config __initdata = { | ||
47 | .mmc [0] = { | ||
48 | .enabled = 1, | ||
49 | .wire4 = 1, | ||
50 | .wp_pin = OMAP_MPUIO(3), | ||
51 | .power_pin = -1, | ||
52 | .switch_pin = -1, | ||
53 | }, | ||
54 | }; | ||
55 | |||
56 | static struct omap_lcd_config palmte_lcd_config __initdata = { | ||
57 | .panel_name = "palmte", | ||
58 | .ctrl_name = "internal", | ||
59 | }; | ||
60 | |||
61 | static struct omap_board_config_kernel palmte_config[] = { | ||
62 | { OMAP_TAG_USB, &palmte_usb_config }, | ||
63 | { OMAP_TAG_MMC, &palmte_mmc_config }, | ||
64 | { OMAP_TAG_LCD, &palmte_lcd_config }, | ||
65 | }; | ||
66 | |||
67 | static void __init omap_generic_init(void) | ||
68 | { | ||
69 | omap_board_config = palmte_config; | ||
70 | omap_board_config_size = ARRAY_SIZE(palmte_config); | ||
71 | } | ||
72 | |||
73 | static void __init omap_generic_map_io(void) | ||
74 | { | ||
75 | omap_map_common_io(); | ||
76 | } | ||
77 | |||
78 | MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") | ||
79 | .phys_ram = 0x10000000, | ||
80 | .phys_io = 0xfff00000, | ||
81 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | ||
82 | .boot_params = 0x10000100, | ||
83 | .map_io = omap_generic_map_io, | ||
84 | .init_irq = omap_generic_init_irq, | ||
85 | .init_machine = omap_generic_init, | ||
86 | .timer = &omap_timer, | ||
87 | MACHINE_END | ||
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 354b157acb3a..bd900b7ab33c 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/arch/mux.h> | 29 | #include <asm/arch/mux.h> |
30 | #include <asm/arch/fpga.h> | 30 | #include <asm/arch/fpga.h> |
31 | #include <asm/arch/common.h> | 31 | #include <asm/arch/common.h> |
32 | #include <asm/arch/board.h> | ||
32 | 33 | ||
33 | static struct resource smc91x_resources[] = { | 34 | static struct resource smc91x_resources[] = { |
34 | [0] = { | 35 | [0] = { |
@@ -43,8 +44,6 @@ static struct resource smc91x_resources[] = { | |||
43 | }, | 44 | }, |
44 | }; | 45 | }; |
45 | 46 | ||
46 | static int __initdata p2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 0}; | ||
47 | |||
48 | static struct mtd_partition p2_partitions[] = { | 47 | static struct mtd_partition p2_partitions[] = { |
49 | /* bootloader (U-Boot, etc) in first sector */ | 48 | /* bootloader (U-Boot, etc) in first sector */ |
50 | { | 49 | { |
@@ -111,9 +110,27 @@ static struct platform_device *devices[] __initdata = { | |||
111 | &smc91x_device, | 110 | &smc91x_device, |
112 | }; | 111 | }; |
113 | 112 | ||
113 | static struct omap_uart_config perseus2_uart_config __initdata = { | ||
114 | .enabled_uarts = ((1 << 0) | (1 << 1)), | ||
115 | }; | ||
116 | |||
117 | static struct omap_lcd_config perseus2_lcd_config __initdata = { | ||
118 | .panel_name = "p2", | ||
119 | .ctrl_name = "internal", | ||
120 | }; | ||
121 | |||
122 | static struct omap_board_config_kernel perseus2_config[] = { | ||
123 | { OMAP_TAG_UART, &perseus2_uart_config }, | ||
124 | { OMAP_TAG_LCD, &perseus2_lcd_config }, | ||
125 | }; | ||
126 | |||
114 | static void __init omap_perseus2_init(void) | 127 | static void __init omap_perseus2_init(void) |
115 | { | 128 | { |
116 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); | 129 | (void) platform_add_devices(devices, ARRAY_SIZE(devices)); |
130 | |||
131 | omap_board_config = perseus2_config; | ||
132 | omap_board_config_size = ARRAY_SIZE(perseus2_config); | ||
133 | omap_serial_init(); | ||
117 | } | 134 | } |
118 | 135 | ||
119 | static void __init perseus2_init_smc91x(void) | 136 | static void __init perseus2_init_smc91x(void) |
@@ -131,7 +148,6 @@ void omap_perseus2_init_irq(void) | |||
131 | omap_gpio_init(); | 148 | omap_gpio_init(); |
132 | perseus2_init_smc91x(); | 149 | perseus2_init_smc91x(); |
133 | } | 150 | } |
134 | |||
135 | /* Only FPGA needs to be mapped here. All others are done with ioremap */ | 151 | /* Only FPGA needs to be mapped here. All others are done with ioremap */ |
136 | static struct map_desc omap_perseus2_io_desc[] __initdata = { | 152 | static struct map_desc omap_perseus2_io_desc[] __initdata = { |
137 | { | 153 | { |
@@ -179,7 +195,6 @@ static void __init omap_perseus2_map_io(void) | |||
179 | * It is used as the Ethernet controller interrupt | 195 | * It is used as the Ethernet controller interrupt |
180 | */ | 196 | */ |
181 | omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9); | 197 | omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9); |
182 | omap_serial_init(p2_serial_ports); | ||
183 | } | 198 | } |
184 | 199 | ||
185 | MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") | 200 | MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") |
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 3f018b296861..6f9a6220e78a 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c | |||
@@ -150,9 +150,14 @@ static struct omap_mmc_config voiceblue_mmc_config __initdata = { | |||
150 | }, | 150 | }, |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static struct omap_uart_config voiceblue_uart_config __initdata = { | ||
154 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
155 | }; | ||
156 | |||
153 | static struct omap_board_config_kernel voiceblue_config[] = { | 157 | static struct omap_board_config_kernel voiceblue_config[] = { |
154 | { OMAP_TAG_USB, &voiceblue_usb_config }, | 158 | { OMAP_TAG_USB, &voiceblue_usb_config }, |
155 | { OMAP_TAG_MMC, &voiceblue_mmc_config }, | 159 | { OMAP_TAG_MMC, &voiceblue_mmc_config }, |
160 | { OMAP_TAG_UART, &voiceblue_uart_config }, | ||
156 | }; | 161 | }; |
157 | 162 | ||
158 | static void __init voiceblue_init_irq(void) | 163 | static void __init voiceblue_init_irq(void) |
@@ -191,6 +196,7 @@ static void __init voiceblue_init(void) | |||
191 | platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); | 196 | platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); |
192 | omap_board_config = voiceblue_config; | 197 | omap_board_config = voiceblue_config; |
193 | omap_board_config_size = ARRAY_SIZE(voiceblue_config); | 198 | omap_board_config_size = ARRAY_SIZE(voiceblue_config); |
199 | omap_serial_init(); | ||
194 | 200 | ||
195 | /* There is a good chance board is going up, so enable power LED | 201 | /* There is a good chance board is going up, so enable power LED |
196 | * (it is connected through invertor) */ | 202 | * (it is connected through invertor) */ |
@@ -198,12 +204,9 @@ static void __init voiceblue_init(void) | |||
198 | omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ | 204 | omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ |
199 | } | 205 | } |
200 | 206 | ||
201 | static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; | ||
202 | |||
203 | static void __init voiceblue_map_io(void) | 207 | static void __init voiceblue_map_io(void) |
204 | { | 208 | { |
205 | omap_map_common_io(); | 209 | omap_map_common_io(); |
206 | omap_serial_init(omap_serial_ports); | ||
207 | } | 210 | } |
208 | 211 | ||
209 | #define MACHINE_PANICED 1 | 212 | #define MACHINE_PANICED 1 |
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c new file mode 100644 index 000000000000..4277eee44ed5 --- /dev/null +++ b/arch/arm/mach-omap1/clock.c | |||
@@ -0,0 +1,792 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap1/clock.c | ||
3 | * | ||
4 | * Copyright (C) 2004 - 2005 Nokia corporation | ||
5 | * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> | ||
6 | * | ||
7 | * Modified to use omap shared clock framework by | ||
8 | * Tony Lindgren <tony@atomide.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/err.h> | ||
19 | |||
20 | #include <asm/io.h> | ||
21 | #include <asm/hardware/clock.h> | ||
22 | |||
23 | #include <asm/arch/usb.h> | ||
24 | #include <asm/arch/clock.h> | ||
25 | #include <asm/arch/sram.h> | ||
26 | |||
27 | #include "clock.h" | ||
28 | |||
29 | __u32 arm_idlect1_mask; | ||
30 | |||
31 | /*------------------------------------------------------------------------- | ||
32 | * Omap1 specific clock functions | ||
33 | *-------------------------------------------------------------------------*/ | ||
34 | |||
35 | static void omap1_watchdog_recalc(struct clk * clk) | ||
36 | { | ||
37 | clk->rate = clk->parent->rate / 14; | ||
38 | } | ||
39 | |||
40 | static void omap1_uart_recalc(struct clk * clk) | ||
41 | { | ||
42 | unsigned int val = omap_readl(clk->enable_reg); | ||
43 | if (val & clk->enable_bit) | ||
44 | clk->rate = 48000000; | ||
45 | else | ||
46 | clk->rate = 12000000; | ||
47 | } | ||
48 | |||
49 | static int omap1_clk_enable_dsp_domain(struct clk *clk) | ||
50 | { | ||
51 | int retval; | ||
52 | |||
53 | retval = omap1_clk_use(&api_ck.clk); | ||
54 | if (!retval) { | ||
55 | retval = omap1_clk_enable(clk); | ||
56 | omap1_clk_unuse(&api_ck.clk); | ||
57 | } | ||
58 | |||
59 | return retval; | ||
60 | } | ||
61 | |||
62 | static void omap1_clk_disable_dsp_domain(struct clk *clk) | ||
63 | { | ||
64 | if (omap1_clk_use(&api_ck.clk) == 0) { | ||
65 | omap1_clk_disable(clk); | ||
66 | omap1_clk_unuse(&api_ck.clk); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | static int omap1_clk_enable_uart_functional(struct clk *clk) | ||
71 | { | ||
72 | int ret; | ||
73 | struct uart_clk *uclk; | ||
74 | |||
75 | ret = omap1_clk_enable(clk); | ||
76 | if (ret == 0) { | ||
77 | /* Set smart idle acknowledgement mode */ | ||
78 | uclk = (struct uart_clk *)clk; | ||
79 | omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8, | ||
80 | uclk->sysc_addr); | ||
81 | } | ||
82 | |||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | static void omap1_clk_disable_uart_functional(struct clk *clk) | ||
87 | { | ||
88 | struct uart_clk *uclk; | ||
89 | |||
90 | /* Set force idle acknowledgement mode */ | ||
91 | uclk = (struct uart_clk *)clk; | ||
92 | omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr); | ||
93 | |||
94 | omap1_clk_disable(clk); | ||
95 | } | ||
96 | |||
97 | static void omap1_clk_allow_idle(struct clk *clk) | ||
98 | { | ||
99 | struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk; | ||
100 | |||
101 | if (!(clk->flags & CLOCK_IDLE_CONTROL)) | ||
102 | return; | ||
103 | |||
104 | if (iclk->no_idle_count > 0 && !(--iclk->no_idle_count)) | ||
105 | arm_idlect1_mask |= 1 << iclk->idlect_shift; | ||
106 | } | ||
107 | |||
108 | static void omap1_clk_deny_idle(struct clk *clk) | ||
109 | { | ||
110 | struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk; | ||
111 | |||
112 | if (!(clk->flags & CLOCK_IDLE_CONTROL)) | ||
113 | return; | ||
114 | |||
115 | if (iclk->no_idle_count++ == 0) | ||
116 | arm_idlect1_mask &= ~(1 << iclk->idlect_shift); | ||
117 | } | ||
118 | |||
119 | static __u16 verify_ckctl_value(__u16 newval) | ||
120 | { | ||
121 | /* This function checks for following limitations set | ||
122 | * by the hardware (all conditions must be true): | ||
123 | * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2 | ||
124 | * ARM_CK >= TC_CK | ||
125 | * DSP_CK >= TC_CK | ||
126 | * DSPMMU_CK >= TC_CK | ||
127 | * | ||
128 | * In addition following rules are enforced: | ||
129 | * LCD_CK <= TC_CK | ||
130 | * ARMPER_CK <= TC_CK | ||
131 | * | ||
132 | * However, maximum frequencies are not checked for! | ||
133 | */ | ||
134 | __u8 per_exp; | ||
135 | __u8 lcd_exp; | ||
136 | __u8 arm_exp; | ||
137 | __u8 dsp_exp; | ||
138 | __u8 tc_exp; | ||
139 | __u8 dspmmu_exp; | ||
140 | |||
141 | per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3; | ||
142 | lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3; | ||
143 | arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3; | ||
144 | dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3; | ||
145 | tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3; | ||
146 | dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3; | ||
147 | |||
148 | if (dspmmu_exp < dsp_exp) | ||
149 | dspmmu_exp = dsp_exp; | ||
150 | if (dspmmu_exp > dsp_exp+1) | ||
151 | dspmmu_exp = dsp_exp+1; | ||
152 | if (tc_exp < arm_exp) | ||
153 | tc_exp = arm_exp; | ||
154 | if (tc_exp < dspmmu_exp) | ||
155 | tc_exp = dspmmu_exp; | ||
156 | if (tc_exp > lcd_exp) | ||
157 | lcd_exp = tc_exp; | ||
158 | if (tc_exp > per_exp) | ||
159 | per_exp = tc_exp; | ||
160 | |||
161 | newval &= 0xf000; | ||
162 | newval |= per_exp << CKCTL_PERDIV_OFFSET; | ||
163 | newval |= lcd_exp << CKCTL_LCDDIV_OFFSET; | ||
164 | newval |= arm_exp << CKCTL_ARMDIV_OFFSET; | ||
165 | newval |= dsp_exp << CKCTL_DSPDIV_OFFSET; | ||
166 | newval |= tc_exp << CKCTL_TCDIV_OFFSET; | ||
167 | newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET; | ||
168 | |||
169 | return newval; | ||
170 | } | ||
171 | |||
172 | static int calc_dsor_exp(struct clk *clk, unsigned long rate) | ||
173 | { | ||
174 | /* Note: If target frequency is too low, this function will return 4, | ||
175 | * which is invalid value. Caller must check for this value and act | ||
176 | * accordingly. | ||
177 | * | ||
178 | * Note: This function does not check for following limitations set | ||
179 | * by the hardware (all conditions must be true): | ||
180 | * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2 | ||
181 | * ARM_CK >= TC_CK | ||
182 | * DSP_CK >= TC_CK | ||
183 | * DSPMMU_CK >= TC_CK | ||
184 | */ | ||
185 | unsigned long realrate; | ||
186 | struct clk * parent; | ||
187 | unsigned dsor_exp; | ||
188 | |||
189 | if (unlikely(!(clk->flags & RATE_CKCTL))) | ||
190 | return -EINVAL; | ||
191 | |||
192 | parent = clk->parent; | ||
193 | if (unlikely(parent == 0)) | ||
194 | return -EIO; | ||
195 | |||
196 | realrate = parent->rate; | ||
197 | for (dsor_exp=0; dsor_exp<4; dsor_exp++) { | ||
198 | if (realrate <= rate) | ||
199 | break; | ||
200 | |||
201 | realrate /= 2; | ||
202 | } | ||
203 | |||
204 | return dsor_exp; | ||
205 | } | ||
206 | |||
207 | static void omap1_ckctl_recalc(struct clk * clk) | ||
208 | { | ||
209 | int dsor; | ||
210 | |||
211 | /* Calculate divisor encoded as 2-bit exponent */ | ||
212 | dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); | ||
213 | |||
214 | if (unlikely(clk->rate == clk->parent->rate / dsor)) | ||
215 | return; /* No change, quick exit */ | ||
216 | clk->rate = clk->parent->rate / dsor; | ||
217 | |||
218 | if (unlikely(clk->flags & RATE_PROPAGATES)) | ||
219 | propagate_rate(clk); | ||
220 | } | ||
221 | |||
222 | static void omap1_ckctl_recalc_dsp_domain(struct clk * clk) | ||
223 | { | ||
224 | int dsor; | ||
225 | |||
226 | /* Calculate divisor encoded as 2-bit exponent | ||
227 | * | ||
228 | * The clock control bits are in DSP domain, | ||
229 | * so api_ck is needed for access. | ||
230 | * Note that DSP_CKCTL virt addr = phys addr, so | ||
231 | * we must use __raw_readw() instead of omap_readw(). | ||
232 | */ | ||
233 | omap1_clk_use(&api_ck.clk); | ||
234 | dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset)); | ||
235 | omap1_clk_unuse(&api_ck.clk); | ||
236 | |||
237 | if (unlikely(clk->rate == clk->parent->rate / dsor)) | ||
238 | return; /* No change, quick exit */ | ||
239 | clk->rate = clk->parent->rate / dsor; | ||
240 | |||
241 | if (unlikely(clk->flags & RATE_PROPAGATES)) | ||
242 | propagate_rate(clk); | ||
243 | } | ||
244 | |||
245 | /* MPU virtual clock functions */ | ||
246 | static int omap1_select_table_rate(struct clk * clk, unsigned long rate) | ||
247 | { | ||
248 | /* Find the highest supported frequency <= rate and switch to it */ | ||
249 | struct mpu_rate * ptr; | ||
250 | |||
251 | if (clk != &virtual_ck_mpu) | ||
252 | return -EINVAL; | ||
253 | |||
254 | for (ptr = rate_table; ptr->rate; ptr++) { | ||
255 | if (ptr->xtal != ck_ref.rate) | ||
256 | continue; | ||
257 | |||
258 | /* DPLL1 cannot be reprogrammed without risking system crash */ | ||
259 | if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate) | ||
260 | continue; | ||
261 | |||
262 | /* Can check only after xtal frequency check */ | ||
263 | if (ptr->rate <= rate) | ||
264 | break; | ||
265 | } | ||
266 | |||
267 | if (!ptr->rate) | ||
268 | return -EINVAL; | ||
269 | |||
270 | /* | ||
271 | * In most cases we should not need to reprogram DPLL. | ||
272 | * Reprogramming the DPLL is tricky, it must be done from SRAM. | ||
273 | */ | ||
274 | omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); | ||
275 | |||
276 | ck_dpll1.rate = ptr->pll_rate; | ||
277 | propagate_rate(&ck_dpll1); | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) | ||
282 | { | ||
283 | int ret = -EINVAL; | ||
284 | int dsor_exp; | ||
285 | __u16 regval; | ||
286 | |||
287 | if (clk->flags & RATE_CKCTL) { | ||
288 | dsor_exp = calc_dsor_exp(clk, rate); | ||
289 | if (dsor_exp > 3) | ||
290 | dsor_exp = -EINVAL; | ||
291 | if (dsor_exp < 0) | ||
292 | return dsor_exp; | ||
293 | |||
294 | regval = __raw_readw(DSP_CKCTL); | ||
295 | regval &= ~(3 << clk->rate_offset); | ||
296 | regval |= dsor_exp << clk->rate_offset; | ||
297 | __raw_writew(regval, DSP_CKCTL); | ||
298 | clk->rate = clk->parent->rate / (1 << dsor_exp); | ||
299 | ret = 0; | ||
300 | } | ||
301 | |||
302 | if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) | ||
303 | propagate_rate(clk); | ||
304 | |||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate) | ||
309 | { | ||
310 | /* Find the highest supported frequency <= rate */ | ||
311 | struct mpu_rate * ptr; | ||
312 | long highest_rate; | ||
313 | |||
314 | if (clk != &virtual_ck_mpu) | ||
315 | return -EINVAL; | ||
316 | |||
317 | highest_rate = -EINVAL; | ||
318 | |||
319 | for (ptr = rate_table; ptr->rate; ptr++) { | ||
320 | if (ptr->xtal != ck_ref.rate) | ||
321 | continue; | ||
322 | |||
323 | highest_rate = ptr->rate; | ||
324 | |||
325 | /* Can check only after xtal frequency check */ | ||
326 | if (ptr->rate <= rate) | ||
327 | break; | ||
328 | } | ||
329 | |||
330 | return highest_rate; | ||
331 | } | ||
332 | |||
333 | static unsigned calc_ext_dsor(unsigned long rate) | ||
334 | { | ||
335 | unsigned dsor; | ||
336 | |||
337 | /* MCLK and BCLK divisor selection is not linear: | ||
338 | * freq = 96MHz / dsor | ||
339 | * | ||
340 | * RATIO_SEL range: dsor <-> RATIO_SEL | ||
341 | * 0..6: (RATIO_SEL+2) <-> (dsor-2) | ||
342 | * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6) | ||
343 | * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9 | ||
344 | * can not be used. | ||
345 | */ | ||
346 | for (dsor = 2; dsor < 96; ++dsor) { | ||
347 | if ((dsor & 1) && dsor > 8) | ||
348 | continue; | ||
349 | if (rate >= 96000000 / dsor) | ||
350 | break; | ||
351 | } | ||
352 | return dsor; | ||
353 | } | ||
354 | |||
355 | /* Only needed on 1510 */ | ||
356 | static int omap1_set_uart_rate(struct clk * clk, unsigned long rate) | ||
357 | { | ||
358 | unsigned int val; | ||
359 | |||
360 | val = omap_readl(clk->enable_reg); | ||
361 | if (rate == 12000000) | ||
362 | val &= ~(1 << clk->enable_bit); | ||
363 | else if (rate == 48000000) | ||
364 | val |= (1 << clk->enable_bit); | ||
365 | else | ||
366 | return -EINVAL; | ||
367 | omap_writel(val, clk->enable_reg); | ||
368 | clk->rate = rate; | ||
369 | |||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | /* External clock (MCLK & BCLK) functions */ | ||
374 | static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate) | ||
375 | { | ||
376 | unsigned dsor; | ||
377 | __u16 ratio_bits; | ||
378 | |||
379 | dsor = calc_ext_dsor(rate); | ||
380 | clk->rate = 96000000 / dsor; | ||
381 | if (dsor > 8) | ||
382 | ratio_bits = ((dsor - 8) / 2 + 6) << 2; | ||
383 | else | ||
384 | ratio_bits = (dsor - 2) << 2; | ||
385 | |||
386 | ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd; | ||
387 | omap_writew(ratio_bits, clk->enable_reg); | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate) | ||
393 | { | ||
394 | return 96000000 / calc_ext_dsor(rate); | ||
395 | } | ||
396 | |||
397 | static void omap1_init_ext_clk(struct clk * clk) | ||
398 | { | ||
399 | unsigned dsor; | ||
400 | __u16 ratio_bits; | ||
401 | |||
402 | /* Determine current rate and ensure clock is based on 96MHz APLL */ | ||
403 | ratio_bits = omap_readw(clk->enable_reg) & ~1; | ||
404 | omap_writew(ratio_bits, clk->enable_reg); | ||
405 | |||
406 | ratio_bits = (ratio_bits & 0xfc) >> 2; | ||
407 | if (ratio_bits > 6) | ||
408 | dsor = (ratio_bits - 6) * 2 + 8; | ||
409 | else | ||
410 | dsor = ratio_bits + 2; | ||
411 | |||
412 | clk-> rate = 96000000 / dsor; | ||
413 | } | ||
414 | |||
415 | static int omap1_clk_use(struct clk *clk) | ||
416 | { | ||
417 | int ret = 0; | ||
418 | if (clk->usecount++ == 0) { | ||
419 | if (likely(clk->parent)) { | ||
420 | ret = omap1_clk_use(clk->parent); | ||
421 | |||
422 | if (unlikely(ret != 0)) { | ||
423 | clk->usecount--; | ||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | if (clk->flags & CLOCK_NO_IDLE_PARENT) | ||
428 | if (!cpu_is_omap24xx()) | ||
429 | omap1_clk_deny_idle(clk->parent); | ||
430 | } | ||
431 | |||
432 | ret = clk->enable(clk); | ||
433 | |||
434 | if (unlikely(ret != 0) && clk->parent) { | ||
435 | omap1_clk_unuse(clk->parent); | ||
436 | clk->usecount--; | ||
437 | } | ||
438 | } | ||
439 | |||
440 | return ret; | ||
441 | } | ||
442 | |||
443 | static void omap1_clk_unuse(struct clk *clk) | ||
444 | { | ||
445 | if (clk->usecount > 0 && !(--clk->usecount)) { | ||
446 | clk->disable(clk); | ||
447 | if (likely(clk->parent)) { | ||
448 | omap1_clk_unuse(clk->parent); | ||
449 | if (clk->flags & CLOCK_NO_IDLE_PARENT) | ||
450 | if (!cpu_is_omap24xx()) | ||
451 | omap1_clk_allow_idle(clk->parent); | ||
452 | } | ||
453 | } | ||
454 | } | ||
455 | |||
456 | static int omap1_clk_enable(struct clk *clk) | ||
457 | { | ||
458 | __u16 regval16; | ||
459 | __u32 regval32; | ||
460 | |||
461 | if (clk->flags & ALWAYS_ENABLED) | ||
462 | return 0; | ||
463 | |||
464 | if (unlikely(clk->enable_reg == 0)) { | ||
465 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", | ||
466 | clk->name); | ||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | if (clk->flags & ENABLE_REG_32BIT) { | ||
471 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | ||
472 | regval32 = __raw_readl(clk->enable_reg); | ||
473 | regval32 |= (1 << clk->enable_bit); | ||
474 | __raw_writel(regval32, clk->enable_reg); | ||
475 | } else { | ||
476 | regval32 = omap_readl(clk->enable_reg); | ||
477 | regval32 |= (1 << clk->enable_bit); | ||
478 | omap_writel(regval32, clk->enable_reg); | ||
479 | } | ||
480 | } else { | ||
481 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | ||
482 | regval16 = __raw_readw(clk->enable_reg); | ||
483 | regval16 |= (1 << clk->enable_bit); | ||
484 | __raw_writew(regval16, clk->enable_reg); | ||
485 | } else { | ||
486 | regval16 = omap_readw(clk->enable_reg); | ||
487 | regval16 |= (1 << clk->enable_bit); | ||
488 | omap_writew(regval16, clk->enable_reg); | ||
489 | } | ||
490 | } | ||
491 | |||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | static void omap1_clk_disable(struct clk *clk) | ||
496 | { | ||
497 | __u16 regval16; | ||
498 | __u32 regval32; | ||
499 | |||
500 | if (clk->enable_reg == 0) | ||
501 | return; | ||
502 | |||
503 | if (clk->flags & ENABLE_REG_32BIT) { | ||
504 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | ||
505 | regval32 = __raw_readl(clk->enable_reg); | ||
506 | regval32 &= ~(1 << clk->enable_bit); | ||
507 | __raw_writel(regval32, clk->enable_reg); | ||
508 | } else { | ||
509 | regval32 = omap_readl(clk->enable_reg); | ||
510 | regval32 &= ~(1 << clk->enable_bit); | ||
511 | omap_writel(regval32, clk->enable_reg); | ||
512 | } | ||
513 | } else { | ||
514 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | ||
515 | regval16 = __raw_readw(clk->enable_reg); | ||
516 | regval16 &= ~(1 << clk->enable_bit); | ||
517 | __raw_writew(regval16, clk->enable_reg); | ||
518 | } else { | ||
519 | regval16 = omap_readw(clk->enable_reg); | ||
520 | regval16 &= ~(1 << clk->enable_bit); | ||
521 | omap_writew(regval16, clk->enable_reg); | ||
522 | } | ||
523 | } | ||
524 | } | ||
525 | |||
526 | static long omap1_clk_round_rate(struct clk *clk, unsigned long rate) | ||
527 | { | ||
528 | int dsor_exp; | ||
529 | |||
530 | if (clk->flags & RATE_FIXED) | ||
531 | return clk->rate; | ||
532 | |||
533 | if (clk->flags & RATE_CKCTL) { | ||
534 | dsor_exp = calc_dsor_exp(clk, rate); | ||
535 | if (dsor_exp < 0) | ||
536 | return dsor_exp; | ||
537 | if (dsor_exp > 3) | ||
538 | dsor_exp = 3; | ||
539 | return clk->parent->rate / (1 << dsor_exp); | ||
540 | } | ||
541 | |||
542 | if(clk->round_rate != 0) | ||
543 | return clk->round_rate(clk, rate); | ||
544 | |||
545 | return clk->rate; | ||
546 | } | ||
547 | |||
548 | static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) | ||
549 | { | ||
550 | int ret = -EINVAL; | ||
551 | int dsor_exp; | ||
552 | __u16 regval; | ||
553 | |||
554 | if (clk->set_rate) | ||
555 | ret = clk->set_rate(clk, rate); | ||
556 | else if (clk->flags & RATE_CKCTL) { | ||
557 | dsor_exp = calc_dsor_exp(clk, rate); | ||
558 | if (dsor_exp > 3) | ||
559 | dsor_exp = -EINVAL; | ||
560 | if (dsor_exp < 0) | ||
561 | return dsor_exp; | ||
562 | |||
563 | regval = omap_readw(ARM_CKCTL); | ||
564 | regval &= ~(3 << clk->rate_offset); | ||
565 | regval |= dsor_exp << clk->rate_offset; | ||
566 | regval = verify_ckctl_value(regval); | ||
567 | omap_writew(regval, ARM_CKCTL); | ||
568 | clk->rate = clk->parent->rate / (1 << dsor_exp); | ||
569 | ret = 0; | ||
570 | } | ||
571 | |||
572 | if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) | ||
573 | propagate_rate(clk); | ||
574 | |||
575 | return ret; | ||
576 | } | ||
577 | |||
578 | /*------------------------------------------------------------------------- | ||
579 | * Omap1 clock reset and init functions | ||
580 | *-------------------------------------------------------------------------*/ | ||
581 | |||
582 | #ifdef CONFIG_OMAP_RESET_CLOCKS | ||
583 | /* | ||
584 | * Resets some clocks that may be left on from bootloader, | ||
585 | * but leaves serial clocks on. See also omap_late_clk_reset(). | ||
586 | */ | ||
587 | static inline void omap1_early_clk_reset(void) | ||
588 | { | ||
589 | //omap_writel(0x3 << 29, MOD_CONF_CTRL_0); | ||
590 | } | ||
591 | |||
592 | static int __init omap1_late_clk_reset(void) | ||
593 | { | ||
594 | /* Turn off all unused clocks */ | ||
595 | struct clk *p; | ||
596 | __u32 regval32; | ||
597 | |||
598 | /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ | ||
599 | regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4); | ||
600 | omap_writew(regval32, SOFT_REQ_REG); | ||
601 | omap_writew(0, SOFT_REQ_REG2); | ||
602 | |||
603 | list_for_each_entry(p, &clocks, node) { | ||
604 | if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) || | ||
605 | p->enable_reg == 0) | ||
606 | continue; | ||
607 | |||
608 | /* Clocks in the DSP domain need api_ck. Just assume bootloader | ||
609 | * has not enabled any DSP clocks */ | ||
610 | if ((u32)p->enable_reg == DSP_IDLECT2) { | ||
611 | printk(KERN_INFO "Skipping reset check for DSP domain " | ||
612 | "clock \"%s\"\n", p->name); | ||
613 | continue; | ||
614 | } | ||
615 | |||
616 | /* Is the clock already disabled? */ | ||
617 | if (p->flags & ENABLE_REG_32BIT) { | ||
618 | if (p->flags & VIRTUAL_IO_ADDRESS) | ||
619 | regval32 = __raw_readl(p->enable_reg); | ||
620 | else | ||
621 | regval32 = omap_readl(p->enable_reg); | ||
622 | } else { | ||
623 | if (p->flags & VIRTUAL_IO_ADDRESS) | ||
624 | regval32 = __raw_readw(p->enable_reg); | ||
625 | else | ||
626 | regval32 = omap_readw(p->enable_reg); | ||
627 | } | ||
628 | |||
629 | if ((regval32 & (1 << p->enable_bit)) == 0) | ||
630 | continue; | ||
631 | |||
632 | /* FIXME: This clock seems to be necessary but no-one | ||
633 | * has asked for its activation. */ | ||
634 | if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera | ||
635 | || p == &ck_dpll1out.clk // FIX: SoSSI, SSR | ||
636 | || p == &arm_gpio_ck // FIX: GPIO code for 1510 | ||
637 | ) { | ||
638 | printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", | ||
639 | p->name); | ||
640 | continue; | ||
641 | } | ||
642 | |||
643 | printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); | ||
644 | p->disable(p); | ||
645 | printk(" done\n"); | ||
646 | } | ||
647 | |||
648 | return 0; | ||
649 | } | ||
650 | late_initcall(omap1_late_clk_reset); | ||
651 | |||
652 | #else | ||
653 | #define omap1_early_clk_reset() {} | ||
654 | #endif | ||
655 | |||
656 | static struct clk_functions omap1_clk_functions = { | ||
657 | .clk_use = omap1_clk_use, | ||
658 | .clk_unuse = omap1_clk_unuse, | ||
659 | .clk_round_rate = omap1_clk_round_rate, | ||
660 | .clk_set_rate = omap1_clk_set_rate, | ||
661 | }; | ||
662 | |||
663 | int __init omap1_clk_init(void) | ||
664 | { | ||
665 | struct clk ** clkp; | ||
666 | const struct omap_clock_config *info; | ||
667 | int crystal_type = 0; /* Default 12 MHz */ | ||
668 | |||
669 | omap1_early_clk_reset(); | ||
670 | clk_init(&omap1_clk_functions); | ||
671 | |||
672 | /* By default all idlect1 clocks are allowed to idle */ | ||
673 | arm_idlect1_mask = ~0; | ||
674 | |||
675 | for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) { | ||
676 | if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) { | ||
677 | clk_register(*clkp); | ||
678 | continue; | ||
679 | } | ||
680 | |||
681 | if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) { | ||
682 | clk_register(*clkp); | ||
683 | continue; | ||
684 | } | ||
685 | |||
686 | if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) { | ||
687 | clk_register(*clkp); | ||
688 | continue; | ||
689 | } | ||
690 | } | ||
691 | |||
692 | info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); | ||
693 | if (info != NULL) { | ||
694 | if (!cpu_is_omap1510()) | ||
695 | crystal_type = info->system_clock_type; | ||
696 | } | ||
697 | |||
698 | #if defined(CONFIG_ARCH_OMAP730) | ||
699 | ck_ref.rate = 13000000; | ||
700 | #elif defined(CONFIG_ARCH_OMAP16XX) | ||
701 | if (crystal_type == 2) | ||
702 | ck_ref.rate = 19200000; | ||
703 | #endif | ||
704 | |||
705 | printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n", | ||
706 | omap_readw(ARM_SYSST), omap_readw(DPLL_CTL), | ||
707 | omap_readw(ARM_CKCTL)); | ||
708 | |||
709 | /* We want to be in syncronous scalable mode */ | ||
710 | omap_writew(0x1000, ARM_SYSST); | ||
711 | |||
712 | #ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER | ||
713 | /* Use values set by bootloader. Determine PLL rate and recalculate | ||
714 | * dependent clocks as if kernel had changed PLL or divisors. | ||
715 | */ | ||
716 | { | ||
717 | unsigned pll_ctl_val = omap_readw(DPLL_CTL); | ||
718 | |||
719 | ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */ | ||
720 | if (pll_ctl_val & 0x10) { | ||
721 | /* PLL enabled, apply multiplier and divisor */ | ||
722 | if (pll_ctl_val & 0xf80) | ||
723 | ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7; | ||
724 | ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1; | ||
725 | } else { | ||
726 | /* PLL disabled, apply bypass divisor */ | ||
727 | switch (pll_ctl_val & 0xc) { | ||
728 | case 0: | ||
729 | break; | ||
730 | case 0x4: | ||
731 | ck_dpll1.rate /= 2; | ||
732 | break; | ||
733 | default: | ||
734 | ck_dpll1.rate /= 4; | ||
735 | break; | ||
736 | } | ||
737 | } | ||
738 | } | ||
739 | propagate_rate(&ck_dpll1); | ||
740 | #else | ||
741 | /* Find the highest supported frequency and enable it */ | ||
742 | if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { | ||
743 | printk(KERN_ERR "System frequencies not set. Check your config.\n"); | ||
744 | /* Guess sane values (60MHz) */ | ||
745 | omap_writew(0x2290, DPLL_CTL); | ||
746 | omap_writew(0x1005, ARM_CKCTL); | ||
747 | ck_dpll1.rate = 60000000; | ||
748 | propagate_rate(&ck_dpll1); | ||
749 | } | ||
750 | #endif | ||
751 | /* Cache rates for clocks connected to ck_ref (not dpll1) */ | ||
752 | propagate_rate(&ck_ref); | ||
753 | printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): " | ||
754 | "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n", | ||
755 | ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, | ||
756 | ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, | ||
757 | arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); | ||
758 | |||
759 | #ifdef CONFIG_MACH_OMAP_PERSEUS2 | ||
760 | /* Select slicer output as OMAP input clock */ | ||
761 | omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); | ||
762 | #endif | ||
763 | |||
764 | /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ | ||
765 | omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL); | ||
766 | |||
767 | /* Put DSP/MPUI into reset until needed */ | ||
768 | omap_writew(0, ARM_RSTCT1); | ||
769 | omap_writew(1, ARM_RSTCT2); | ||
770 | omap_writew(0x400, ARM_IDLECT1); | ||
771 | |||
772 | /* | ||
773 | * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8) | ||
774 | * of the ARM_IDLECT2 register must be set to zero. The power-on | ||
775 | * default value of this bit is one. | ||
776 | */ | ||
777 | omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */ | ||
778 | |||
779 | /* | ||
780 | * Only enable those clocks we will need, let the drivers | ||
781 | * enable other clocks as necessary | ||
782 | */ | ||
783 | clk_use(&armper_ck.clk); | ||
784 | clk_use(&armxor_ck.clk); | ||
785 | clk_use(&armtim_ck.clk); /* This should be done by timer code */ | ||
786 | |||
787 | if (cpu_is_omap1510()) | ||
788 | clk_enable(&arm_gpio_ck); | ||
789 | |||
790 | return 0; | ||
791 | } | ||
792 | |||
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h new file mode 100644 index 000000000000..f3bdfb50e01a --- /dev/null +++ b/arch/arm/mach-omap1/clock.h | |||
@@ -0,0 +1,768 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap1/clock.h | ||
3 | * | ||
4 | * Copyright (C) 2004 - 2005 Nokia corporation | ||
5 | * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> | ||
6 | * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H | ||
14 | #define __ARCH_ARM_MACH_OMAP1_CLOCK_H | ||
15 | |||
16 | static int omap1_clk_enable(struct clk * clk); | ||
17 | static void omap1_clk_disable(struct clk * clk); | ||
18 | static void omap1_ckctl_recalc(struct clk * clk); | ||
19 | static void omap1_watchdog_recalc(struct clk * clk); | ||
20 | static void omap1_ckctl_recalc_dsp_domain(struct clk * clk); | ||
21 | static int omap1_clk_enable_dsp_domain(struct clk * clk); | ||
22 | static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate); | ||
23 | static void omap1_clk_disable_dsp_domain(struct clk * clk); | ||
24 | static int omap1_set_uart_rate(struct clk * clk, unsigned long rate); | ||
25 | static void omap1_uart_recalc(struct clk * clk); | ||
26 | static int omap1_clk_enable_uart_functional(struct clk * clk); | ||
27 | static void omap1_clk_disable_uart_functional(struct clk * clk); | ||
28 | static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate); | ||
29 | static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate); | ||
30 | static void omap1_init_ext_clk(struct clk * clk); | ||
31 | static int omap1_select_table_rate(struct clk * clk, unsigned long rate); | ||
32 | static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate); | ||
33 | static int omap1_clk_use(struct clk *clk); | ||
34 | static void omap1_clk_unuse(struct clk *clk); | ||
35 | |||
36 | struct mpu_rate { | ||
37 | unsigned long rate; | ||
38 | unsigned long xtal; | ||
39 | unsigned long pll_rate; | ||
40 | __u16 ckctl_val; | ||
41 | __u16 dpllctl_val; | ||
42 | }; | ||
43 | |||
44 | struct uart_clk { | ||
45 | struct clk clk; | ||
46 | unsigned long sysc_addr; | ||
47 | }; | ||
48 | |||
49 | /* Provide a method for preventing idling some ARM IDLECT clocks */ | ||
50 | struct arm_idlect1_clk { | ||
51 | struct clk clk; | ||
52 | unsigned long no_idle_count; | ||
53 | __u8 idlect_shift; | ||
54 | }; | ||
55 | |||
56 | /* ARM_CKCTL bit shifts */ | ||
57 | #define CKCTL_PERDIV_OFFSET 0 | ||
58 | #define CKCTL_LCDDIV_OFFSET 2 | ||
59 | #define CKCTL_ARMDIV_OFFSET 4 | ||
60 | #define CKCTL_DSPDIV_OFFSET 6 | ||
61 | #define CKCTL_TCDIV_OFFSET 8 | ||
62 | #define CKCTL_DSPMMUDIV_OFFSET 10 | ||
63 | /*#define ARM_TIMXO 12*/ | ||
64 | #define EN_DSPCK 13 | ||
65 | /*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */ | ||
66 | /* DSP_CKCTL bit shifts */ | ||
67 | #define CKCTL_DSPPERDIV_OFFSET 0 | ||
68 | |||
69 | /* ARM_IDLECT2 bit shifts */ | ||
70 | #define EN_WDTCK 0 | ||
71 | #define EN_XORPCK 1 | ||
72 | #define EN_PERCK 2 | ||
73 | #define EN_LCDCK 3 | ||
74 | #define EN_LBCK 4 /* Not on 1610/1710 */ | ||
75 | /*#define EN_HSABCK 5*/ | ||
76 | #define EN_APICK 6 | ||
77 | #define EN_TIMCK 7 | ||
78 | #define DMACK_REQ 8 | ||
79 | #define EN_GPIOCK 9 /* Not on 1610/1710 */ | ||
80 | /*#define EN_LBFREECK 10*/ | ||
81 | #define EN_CKOUT_ARM 11 | ||
82 | |||
83 | /* ARM_IDLECT3 bit shifts */ | ||
84 | #define EN_OCPI_CK 0 | ||
85 | #define EN_TC1_CK 2 | ||
86 | #define EN_TC2_CK 4 | ||
87 | |||
88 | /* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */ | ||
89 | #define EN_DSPTIMCK 5 | ||
90 | |||
91 | /* Various register defines for clock controls scattered around OMAP chip */ | ||
92 | #define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ | ||
93 | #define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ | ||
94 | #define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ | ||
95 | #define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */ | ||
96 | #define SWD_CLK_DIV_CTRL_SEL 0xfffe0874 | ||
97 | #define COM_CLK_DIV_CTRL_SEL 0xfffe0878 | ||
98 | #define SOFT_REQ_REG 0xfffe0834 | ||
99 | #define SOFT_REQ_REG2 0xfffe0880 | ||
100 | |||
101 | /*------------------------------------------------------------------------- | ||
102 | * Omap1 MPU rate table | ||
103 | *-------------------------------------------------------------------------*/ | ||
104 | static struct mpu_rate rate_table[] = { | ||
105 | /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL | ||
106 | * NOTE: Comment order here is different from bits in CKCTL value: | ||
107 | * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv | ||
108 | */ | ||
109 | #if defined(CONFIG_OMAP_ARM_216MHZ) | ||
110 | { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */ | ||
111 | #endif | ||
112 | #if defined(CONFIG_OMAP_ARM_195MHZ) | ||
113 | { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */ | ||
114 | #endif | ||
115 | #if defined(CONFIG_OMAP_ARM_192MHZ) | ||
116 | { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */ | ||
117 | { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */ | ||
118 | { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */ | ||
119 | { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */ | ||
120 | { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */ | ||
121 | #endif | ||
122 | #if defined(CONFIG_OMAP_ARM_182MHZ) | ||
123 | { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */ | ||
124 | #endif | ||
125 | #if defined(CONFIG_OMAP_ARM_168MHZ) | ||
126 | { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */ | ||
127 | #endif | ||
128 | #if defined(CONFIG_OMAP_ARM_150MHZ) | ||
129 | { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */ | ||
130 | #endif | ||
131 | #if defined(CONFIG_OMAP_ARM_120MHZ) | ||
132 | { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */ | ||
133 | #endif | ||
134 | #if defined(CONFIG_OMAP_ARM_96MHZ) | ||
135 | { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */ | ||
136 | #endif | ||
137 | #if defined(CONFIG_OMAP_ARM_60MHZ) | ||
138 | { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */ | ||
139 | #endif | ||
140 | #if defined(CONFIG_OMAP_ARM_30MHZ) | ||
141 | { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */ | ||
142 | #endif | ||
143 | { 0, 0, 0, 0, 0 }, | ||
144 | }; | ||
145 | |||
146 | /*------------------------------------------------------------------------- | ||
147 | * Omap1 clocks | ||
148 | *-------------------------------------------------------------------------*/ | ||
149 | |||
150 | static struct clk ck_ref = { | ||
151 | .name = "ck_ref", | ||
152 | .rate = 12000000, | ||
153 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
154 | ALWAYS_ENABLED, | ||
155 | .enable = &omap1_clk_enable, | ||
156 | .disable = &omap1_clk_disable, | ||
157 | }; | ||
158 | |||
159 | static struct clk ck_dpll1 = { | ||
160 | .name = "ck_dpll1", | ||
161 | .parent = &ck_ref, | ||
162 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
163 | RATE_PROPAGATES | ALWAYS_ENABLED, | ||
164 | .enable = &omap1_clk_enable, | ||
165 | .disable = &omap1_clk_disable, | ||
166 | }; | ||
167 | |||
168 | static struct arm_idlect1_clk ck_dpll1out = { | ||
169 | .clk = { | ||
170 | .name = "ck_dpll1out", | ||
171 | .parent = &ck_dpll1, | ||
172 | .flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL, | ||
173 | .enable_reg = (void __iomem *)ARM_IDLECT2, | ||
174 | .enable_bit = EN_CKOUT_ARM, | ||
175 | .recalc = &followparent_recalc, | ||
176 | .enable = &omap1_clk_enable, | ||
177 | .disable = &omap1_clk_disable, | ||
178 | }, | ||
179 | .idlect_shift = 12, | ||
180 | }; | ||
181 | |||
182 | static struct clk arm_ck = { | ||
183 | .name = "arm_ck", | ||
184 | .parent = &ck_dpll1, | ||
185 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
186 | RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, | ||
187 | .rate_offset = CKCTL_ARMDIV_OFFSET, | ||
188 | .recalc = &omap1_ckctl_recalc, | ||
189 | .enable = &omap1_clk_enable, | ||
190 | .disable = &omap1_clk_disable, | ||
191 | }; | ||
192 | |||
193 | static struct arm_idlect1_clk armper_ck = { | ||
194 | .clk = { | ||
195 | .name = "armper_ck", | ||
196 | .parent = &ck_dpll1, | ||
197 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
198 | RATE_CKCTL | CLOCK_IDLE_CONTROL, | ||
199 | .enable_reg = (void __iomem *)ARM_IDLECT2, | ||
200 | .enable_bit = EN_PERCK, | ||
201 | .rate_offset = CKCTL_PERDIV_OFFSET, | ||
202 | .recalc = &omap1_ckctl_recalc, | ||
203 | .enable = &omap1_clk_enable, | ||
204 | .disable = &omap1_clk_disable, | ||
205 | }, | ||
206 | .idlect_shift = 2, | ||
207 | }; | ||
208 | |||
209 | static struct clk arm_gpio_ck = { | ||
210 | .name = "arm_gpio_ck", | ||
211 | .parent = &ck_dpll1, | ||
212 | .flags = CLOCK_IN_OMAP1510, | ||
213 | .enable_reg = (void __iomem *)ARM_IDLECT2, | ||
214 | .enable_bit = EN_GPIOCK, | ||
215 | .recalc = &followparent_recalc, | ||
216 | .enable = &omap1_clk_enable, | ||
217 | .disable = &omap1_clk_disable, | ||
218 | }; | ||
219 | |||
220 | static struct arm_idlect1_clk armxor_ck = { | ||
221 | .clk = { | ||
222 | .name = "armxor_ck", | ||
223 | .parent = &ck_ref, | ||
224 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
225 | CLOCK_IDLE_CONTROL, | ||
226 | .enable_reg = (void __iomem *)ARM_IDLECT2, | ||
227 | .enable_bit = EN_XORPCK, | ||
228 | .recalc = &followparent_recalc, | ||
229 | .enable = &omap1_clk_enable, | ||
230 | .disable = &omap1_clk_disable, | ||
231 | }, | ||
232 | .idlect_shift = 1, | ||
233 | }; | ||
234 | |||
235 | static struct arm_idlect1_clk armtim_ck = { | ||
236 | .clk = { | ||
237 | .name = "armtim_ck", | ||
238 | .parent = &ck_ref, | ||
239 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
240 | CLOCK_IDLE_CONTROL, | ||
241 | .enable_reg = (void __iomem *)ARM_IDLECT2, | ||
242 | .enable_bit = EN_TIMCK, | ||
243 | .recalc = &followparent_recalc, | ||
244 | .enable = &omap1_clk_enable, | ||
245 | .disable = &omap1_clk_disable, | ||
246 | }, | ||
247 | .idlect_shift = 9, | ||
248 | }; | ||
249 | |||
250 | static struct arm_idlect1_clk armwdt_ck = { | ||
251 | .clk = { | ||
252 | .name = "armwdt_ck", | ||
253 | .parent = &ck_ref, | ||
254 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
255 | CLOCK_IDLE_CONTROL, | ||
256 | .enable_reg = (void __iomem *)ARM_IDLECT2, | ||
257 | .enable_bit = EN_WDTCK, | ||
258 | .recalc = &omap1_watchdog_recalc, | ||
259 | .enable = &omap1_clk_enable, | ||
260 | .disable = &omap1_clk_disable, | ||
261 | }, | ||
262 | .idlect_shift = 0, | ||
263 | }; | ||
264 | |||
265 | static struct clk arminth_ck16xx = { | ||
266 | .name = "arminth_ck", | ||
267 | .parent = &arm_ck, | ||
268 | .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, | ||
269 | .recalc = &followparent_recalc, | ||
270 | /* Note: On 16xx the frequency can be divided by 2 by programming | ||
271 | * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 | ||
272 | * | ||
273 | * 1510 version is in TC clocks. | ||
274 | */ | ||
275 | .enable = &omap1_clk_enable, | ||
276 | .disable = &omap1_clk_disable, | ||
277 | }; | ||
278 | |||
279 | static struct clk dsp_ck = { | ||
280 | .name = "dsp_ck", | ||
281 | .parent = &ck_dpll1, | ||
282 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
283 | RATE_CKCTL, | ||
284 | .enable_reg = (void __iomem *)ARM_CKCTL, | ||
285 | .enable_bit = EN_DSPCK, | ||
286 | .rate_offset = CKCTL_DSPDIV_OFFSET, | ||
287 | .recalc = &omap1_ckctl_recalc, | ||
288 | .enable = &omap1_clk_enable, | ||
289 | .disable = &omap1_clk_disable, | ||
290 | }; | ||
291 | |||
292 | static struct clk dspmmu_ck = { | ||
293 | .name = "dspmmu_ck", | ||
294 | .parent = &ck_dpll1, | ||
295 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
296 | RATE_CKCTL | ALWAYS_ENABLED, | ||
297 | .rate_offset = CKCTL_DSPMMUDIV_OFFSET, | ||
298 | .recalc = &omap1_ckctl_recalc, | ||
299 | .enable = &omap1_clk_enable, | ||
300 | .disable = &omap1_clk_disable, | ||
301 | }; | ||
302 | |||
303 | static struct clk dspper_ck = { | ||
304 | .name = "dspper_ck", | ||
305 | .parent = &ck_dpll1, | ||
306 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
307 | RATE_CKCTL | VIRTUAL_IO_ADDRESS, | ||
308 | .enable_reg = (void __iomem *)DSP_IDLECT2, | ||
309 | .enable_bit = EN_PERCK, | ||
310 | .rate_offset = CKCTL_PERDIV_OFFSET, | ||
311 | .recalc = &omap1_ckctl_recalc_dsp_domain, | ||
312 | .set_rate = &omap1_clk_set_rate_dsp_domain, | ||
313 | .enable = &omap1_clk_enable_dsp_domain, | ||
314 | .disable = &omap1_clk_disable_dsp_domain, | ||
315 | }; | ||
316 | |||
317 | static struct clk dspxor_ck = { | ||
318 | .name = "dspxor_ck", | ||
319 | .parent = &ck_ref, | ||
320 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
321 | VIRTUAL_IO_ADDRESS, | ||
322 | .enable_reg = (void __iomem *)DSP_IDLECT2, | ||
323 | .enable_bit = EN_XORPCK, | ||
324 | .recalc = &followparent_recalc, | ||
325 | .enable = &omap1_clk_enable_dsp_domain, | ||
326 | .disable = &omap1_clk_disable_dsp_domain, | ||
327 | }; | ||
328 | |||
329 | static struct clk dsptim_ck = { | ||
330 | .name = "dsptim_ck", | ||
331 | .parent = &ck_ref, | ||
332 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
333 | VIRTUAL_IO_ADDRESS, | ||
334 | .enable_reg = (void __iomem *)DSP_IDLECT2, | ||
335 | .enable_bit = EN_DSPTIMCK, | ||
336 | .recalc = &followparent_recalc, | ||
337 | .enable = &omap1_clk_enable_dsp_domain, | ||
338 | .disable = &omap1_clk_disable_dsp_domain, | ||
339 | }; | ||
340 | |||
341 | /* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */ | ||
342 | static struct arm_idlect1_clk tc_ck = { | ||
343 | .clk = { | ||
344 | .name = "tc_ck", | ||
345 | .parent = &ck_dpll1, | ||
346 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
347 | CLOCK_IN_OMAP730 | RATE_CKCTL | | ||
348 | RATE_PROPAGATES | ALWAYS_ENABLED | | ||
349 | CLOCK_IDLE_CONTROL, | ||
350 | .rate_offset = CKCTL_TCDIV_OFFSET, | ||
351 | .recalc = &omap1_ckctl_recalc, | ||
352 | .enable = &omap1_clk_enable, | ||
353 | .disable = &omap1_clk_disable, | ||
354 | }, | ||
355 | .idlect_shift = 6, | ||
356 | }; | ||
357 | |||
358 | static struct clk arminth_ck1510 = { | ||
359 | .name = "arminth_ck", | ||
360 | .parent = &tc_ck.clk, | ||
361 | .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, | ||
362 | .recalc = &followparent_recalc, | ||
363 | /* Note: On 1510 the frequency follows TC_CK | ||
364 | * | ||
365 | * 16xx version is in MPU clocks. | ||
366 | */ | ||
367 | .enable = &omap1_clk_enable, | ||
368 | .disable = &omap1_clk_disable, | ||
369 | }; | ||
370 | |||
371 | static struct clk tipb_ck = { | ||
372 | /* No-idle controlled by "tc_ck" */ | ||
373 | .name = "tibp_ck", | ||
374 | .parent = &tc_ck.clk, | ||
375 | .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, | ||
376 | .recalc = &followparent_recalc, | ||
377 | .enable = &omap1_clk_enable, | ||
378 | .disable = &omap1_clk_disable, | ||
379 | }; | ||
380 | |||
381 | static struct clk l3_ocpi_ck = { | ||
382 | /* No-idle controlled by "tc_ck" */ | ||
383 | .name = "l3_ocpi_ck", | ||
384 | .parent = &tc_ck.clk, | ||
385 | .flags = CLOCK_IN_OMAP16XX, | ||
386 | .enable_reg = (void __iomem *)ARM_IDLECT3, | ||
387 | .enable_bit = EN_OCPI_CK, | ||
388 | .recalc = &followparent_recalc, | ||
389 | .enable = &omap1_clk_enable, | ||
390 | .disable = &omap1_clk_disable, | ||
391 | }; | ||
392 | |||
393 | static struct clk tc1_ck = { | ||
394 | .name = "tc1_ck", | ||
395 | .parent = &tc_ck.clk, | ||
396 | .flags = CLOCK_IN_OMAP16XX, | ||
397 | .enable_reg = (void __iomem *)ARM_IDLECT3, | ||
398 | .enable_bit = EN_TC1_CK, | ||
399 | .recalc = &followparent_recalc, | ||
400 | .enable = &omap1_clk_enable, | ||
401 | .disable = &omap1_clk_disable, | ||
402 | }; | ||
403 | |||
404 | static struct clk tc2_ck = { | ||
405 | .name = "tc2_ck", | ||
406 | .parent = &tc_ck.clk, | ||
407 | .flags = CLOCK_IN_OMAP16XX, | ||
408 | .enable_reg = (void __iomem *)ARM_IDLECT3, | ||
409 | .enable_bit = EN_TC2_CK, | ||
410 | .recalc = &followparent_recalc, | ||
411 | .enable = &omap1_clk_enable, | ||
412 | .disable = &omap1_clk_disable, | ||
413 | }; | ||
414 | |||
415 | static struct clk dma_ck = { | ||
416 | /* No-idle controlled by "tc_ck" */ | ||
417 | .name = "dma_ck", | ||
418 | .parent = &tc_ck.clk, | ||
419 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
420 | ALWAYS_ENABLED, | ||
421 | .recalc = &followparent_recalc, | ||
422 | .enable = &omap1_clk_enable, | ||
423 | .disable = &omap1_clk_disable, | ||
424 | }; | ||
425 | |||
426 | static struct clk dma_lcdfree_ck = { | ||
427 | .name = "dma_lcdfree_ck", | ||
428 | .parent = &tc_ck.clk, | ||
429 | .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, | ||
430 | .recalc = &followparent_recalc, | ||
431 | .enable = &omap1_clk_enable, | ||
432 | .disable = &omap1_clk_disable, | ||
433 | }; | ||
434 | |||
435 | static struct arm_idlect1_clk api_ck = { | ||
436 | .clk = { | ||
437 | .name = "api_ck", | ||
438 | .parent = &tc_ck.clk, | ||
439 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
440 | CLOCK_IDLE_CONTROL, | ||
441 | .enable_reg = (void __iomem *)ARM_IDLECT2, | ||
442 | .enable_bit = EN_APICK, | ||
443 | .recalc = &followparent_recalc, | ||
444 | .enable = &omap1_clk_enable, | ||
445 | .disable = &omap1_clk_disable, | ||
446 | }, | ||
447 | .idlect_shift = 8, | ||
448 | }; | ||
449 | |||
450 | static struct arm_idlect1_clk lb_ck = { | ||
451 | .clk = { | ||
452 | .name = "lb_ck", | ||
453 | .parent = &tc_ck.clk, | ||
454 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL, | ||
455 | .enable_reg = (void __iomem *)ARM_IDLECT2, | ||
456 | .enable_bit = EN_LBCK, | ||
457 | .recalc = &followparent_recalc, | ||
458 | .enable = &omap1_clk_enable, | ||
459 | .disable = &omap1_clk_disable, | ||
460 | }, | ||
461 | .idlect_shift = 4, | ||
462 | }; | ||
463 | |||
464 | static struct clk rhea1_ck = { | ||
465 | .name = "rhea1_ck", | ||
466 | .parent = &tc_ck.clk, | ||
467 | .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, | ||
468 | .recalc = &followparent_recalc, | ||
469 | .enable = &omap1_clk_enable, | ||
470 | .disable = &omap1_clk_disable, | ||
471 | }; | ||
472 | |||
473 | static struct clk rhea2_ck = { | ||
474 | .name = "rhea2_ck", | ||
475 | .parent = &tc_ck.clk, | ||
476 | .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, | ||
477 | .recalc = &followparent_recalc, | ||
478 | .enable = &omap1_clk_enable, | ||
479 | .disable = &omap1_clk_disable, | ||
480 | }; | ||
481 | |||
482 | static struct clk lcd_ck_16xx = { | ||
483 | .name = "lcd_ck", | ||
484 | .parent = &ck_dpll1, | ||
485 | .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL, | ||
486 | .enable_reg = (void __iomem *)ARM_IDLECT2, | ||
487 | .enable_bit = EN_LCDCK, | ||
488 | .rate_offset = CKCTL_LCDDIV_OFFSET, | ||
489 | .recalc = &omap1_ckctl_recalc, | ||
490 | .enable = &omap1_clk_enable, | ||
491 | .disable = &omap1_clk_disable, | ||
492 | }; | ||
493 | |||
494 | static struct arm_idlect1_clk lcd_ck_1510 = { | ||
495 | .clk = { | ||
496 | .name = "lcd_ck", | ||
497 | .parent = &ck_dpll1, | ||
498 | .flags = CLOCK_IN_OMAP1510 | RATE_CKCTL | | ||
499 | CLOCK_IDLE_CONTROL, | ||
500 | .enable_reg = (void __iomem *)ARM_IDLECT2, | ||
501 | .enable_bit = EN_LCDCK, | ||
502 | .rate_offset = CKCTL_LCDDIV_OFFSET, | ||
503 | .recalc = &omap1_ckctl_recalc, | ||
504 | .enable = &omap1_clk_enable, | ||
505 | .disable = &omap1_clk_disable, | ||
506 | }, | ||
507 | .idlect_shift = 3, | ||
508 | }; | ||
509 | |||
510 | static struct clk uart1_1510 = { | ||
511 | .name = "uart1_ck", | ||
512 | /* Direct from ULPD, no real parent */ | ||
513 | .parent = &armper_ck.clk, | ||
514 | .rate = 12000000, | ||
515 | .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | | ||
516 | ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, | ||
517 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | ||
518 | .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ | ||
519 | .set_rate = &omap1_set_uart_rate, | ||
520 | .recalc = &omap1_uart_recalc, | ||
521 | .enable = &omap1_clk_enable, | ||
522 | .disable = &omap1_clk_disable, | ||
523 | }; | ||
524 | |||
525 | static struct uart_clk uart1_16xx = { | ||
526 | .clk = { | ||
527 | .name = "uart1_ck", | ||
528 | /* Direct from ULPD, no real parent */ | ||
529 | .parent = &armper_ck.clk, | ||
530 | .rate = 48000000, | ||
531 | .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | | ||
532 | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, | ||
533 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | ||
534 | .enable_bit = 29, | ||
535 | .enable = &omap1_clk_enable_uart_functional, | ||
536 | .disable = &omap1_clk_disable_uart_functional, | ||
537 | }, | ||
538 | .sysc_addr = 0xfffb0054, | ||
539 | }; | ||
540 | |||
541 | static struct clk uart2_ck = { | ||
542 | .name = "uart2_ck", | ||
543 | /* Direct from ULPD, no real parent */ | ||
544 | .parent = &armper_ck.clk, | ||
545 | .rate = 12000000, | ||
546 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
547 | ENABLE_REG_32BIT | ALWAYS_ENABLED | | ||
548 | CLOCK_NO_IDLE_PARENT, | ||
549 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | ||
550 | .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ | ||
551 | .set_rate = &omap1_set_uart_rate, | ||
552 | .recalc = &omap1_uart_recalc, | ||
553 | .enable = &omap1_clk_enable, | ||
554 | .disable = &omap1_clk_disable, | ||
555 | }; | ||
556 | |||
557 | static struct clk uart3_1510 = { | ||
558 | .name = "uart3_ck", | ||
559 | /* Direct from ULPD, no real parent */ | ||
560 | .parent = &armper_ck.clk, | ||
561 | .rate = 12000000, | ||
562 | .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | | ||
563 | ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, | ||
564 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | ||
565 | .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ | ||
566 | .set_rate = &omap1_set_uart_rate, | ||
567 | .recalc = &omap1_uart_recalc, | ||
568 | .enable = &omap1_clk_enable, | ||
569 | .disable = &omap1_clk_disable, | ||
570 | }; | ||
571 | |||
572 | static struct uart_clk uart3_16xx = { | ||
573 | .clk = { | ||
574 | .name = "uart3_ck", | ||
575 | /* Direct from ULPD, no real parent */ | ||
576 | .parent = &armper_ck.clk, | ||
577 | .rate = 48000000, | ||
578 | .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | | ||
579 | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, | ||
580 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | ||
581 | .enable_bit = 31, | ||
582 | .enable = &omap1_clk_enable_uart_functional, | ||
583 | .disable = &omap1_clk_disable_uart_functional, | ||
584 | }, | ||
585 | .sysc_addr = 0xfffb9854, | ||
586 | }; | ||
587 | |||
588 | static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */ | ||
589 | .name = "usb_clko", | ||
590 | /* Direct from ULPD, no parent */ | ||
591 | .rate = 6000000, | ||
592 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
593 | RATE_FIXED | ENABLE_REG_32BIT, | ||
594 | .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL, | ||
595 | .enable_bit = USB_MCLK_EN_BIT, | ||
596 | .enable = &omap1_clk_enable, | ||
597 | .disable = &omap1_clk_disable, | ||
598 | }; | ||
599 | |||
600 | static struct clk usb_hhc_ck1510 = { | ||
601 | .name = "usb_hhc_ck", | ||
602 | /* Direct from ULPD, no parent */ | ||
603 | .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ | ||
604 | .flags = CLOCK_IN_OMAP1510 | | ||
605 | RATE_FIXED | ENABLE_REG_32BIT, | ||
606 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | ||
607 | .enable_bit = USB_HOST_HHC_UHOST_EN, | ||
608 | .enable = &omap1_clk_enable, | ||
609 | .disable = &omap1_clk_disable, | ||
610 | }; | ||
611 | |||
612 | static struct clk usb_hhc_ck16xx = { | ||
613 | .name = "usb_hhc_ck", | ||
614 | /* Direct from ULPD, no parent */ | ||
615 | .rate = 48000000, | ||
616 | /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ | ||
617 | .flags = CLOCK_IN_OMAP16XX | | ||
618 | RATE_FIXED | ENABLE_REG_32BIT, | ||
619 | .enable_reg = (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */, | ||
620 | .enable_bit = 8 /* UHOST_EN */, | ||
621 | .enable = &omap1_clk_enable, | ||
622 | .disable = &omap1_clk_disable, | ||
623 | }; | ||
624 | |||
625 | static struct clk usb_dc_ck = { | ||
626 | .name = "usb_dc_ck", | ||
627 | /* Direct from ULPD, no parent */ | ||
628 | .rate = 48000000, | ||
629 | .flags = CLOCK_IN_OMAP16XX | RATE_FIXED, | ||
630 | .enable_reg = (void __iomem *)SOFT_REQ_REG, | ||
631 | .enable_bit = 4, | ||
632 | .enable = &omap1_clk_enable, | ||
633 | .disable = &omap1_clk_disable, | ||
634 | }; | ||
635 | |||
636 | static struct clk mclk_1510 = { | ||
637 | .name = "mclk", | ||
638 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | ||
639 | .rate = 12000000, | ||
640 | .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, | ||
641 | .enable = &omap1_clk_enable, | ||
642 | .disable = &omap1_clk_disable, | ||
643 | }; | ||
644 | |||
645 | static struct clk mclk_16xx = { | ||
646 | .name = "mclk", | ||
647 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | ||
648 | .flags = CLOCK_IN_OMAP16XX, | ||
649 | .enable_reg = (void __iomem *)COM_CLK_DIV_CTRL_SEL, | ||
650 | .enable_bit = COM_ULPD_PLL_CLK_REQ, | ||
651 | .set_rate = &omap1_set_ext_clk_rate, | ||
652 | .round_rate = &omap1_round_ext_clk_rate, | ||
653 | .init = &omap1_init_ext_clk, | ||
654 | .enable = &omap1_clk_enable, | ||
655 | .disable = &omap1_clk_disable, | ||
656 | }; | ||
657 | |||
658 | static struct clk bclk_1510 = { | ||
659 | .name = "bclk", | ||
660 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | ||
661 | .rate = 12000000, | ||
662 | .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, | ||
663 | .enable = &omap1_clk_enable, | ||
664 | .disable = &omap1_clk_disable, | ||
665 | }; | ||
666 | |||
667 | static struct clk bclk_16xx = { | ||
668 | .name = "bclk", | ||
669 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | ||
670 | .flags = CLOCK_IN_OMAP16XX, | ||
671 | .enable_reg = (void __iomem *)SWD_CLK_DIV_CTRL_SEL, | ||
672 | .enable_bit = SWD_ULPD_PLL_CLK_REQ, | ||
673 | .set_rate = &omap1_set_ext_clk_rate, | ||
674 | .round_rate = &omap1_round_ext_clk_rate, | ||
675 | .init = &omap1_init_ext_clk, | ||
676 | .enable = &omap1_clk_enable, | ||
677 | .disable = &omap1_clk_disable, | ||
678 | }; | ||
679 | |||
680 | static struct clk mmc1_ck = { | ||
681 | .name = "mmc1_ck", | ||
682 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ | ||
683 | .parent = &armper_ck.clk, | ||
684 | .rate = 48000000, | ||
685 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
686 | RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, | ||
687 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | ||
688 | .enable_bit = 23, | ||
689 | .enable = &omap1_clk_enable, | ||
690 | .disable = &omap1_clk_disable, | ||
691 | }; | ||
692 | |||
693 | static struct clk mmc2_ck = { | ||
694 | .name = "mmc2_ck", | ||
695 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ | ||
696 | .parent = &armper_ck.clk, | ||
697 | .rate = 48000000, | ||
698 | .flags = CLOCK_IN_OMAP16XX | | ||
699 | RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, | ||
700 | .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, | ||
701 | .enable_bit = 20, | ||
702 | .enable = &omap1_clk_enable, | ||
703 | .disable = &omap1_clk_disable, | ||
704 | }; | ||
705 | |||
706 | static struct clk virtual_ck_mpu = { | ||
707 | .name = "mpu", | ||
708 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
709 | VIRTUAL_CLOCK | ALWAYS_ENABLED, | ||
710 | .parent = &arm_ck, /* Is smarter alias for */ | ||
711 | .recalc = &followparent_recalc, | ||
712 | .set_rate = &omap1_select_table_rate, | ||
713 | .round_rate = &omap1_round_to_table_rate, | ||
714 | .enable = &omap1_clk_enable, | ||
715 | .disable = &omap1_clk_disable, | ||
716 | }; | ||
717 | |||
718 | static struct clk * onchip_clks[] = { | ||
719 | /* non-ULPD clocks */ | ||
720 | &ck_ref, | ||
721 | &ck_dpll1, | ||
722 | /* CK_GEN1 clocks */ | ||
723 | &ck_dpll1out.clk, | ||
724 | &arm_ck, | ||
725 | &armper_ck.clk, | ||
726 | &arm_gpio_ck, | ||
727 | &armxor_ck.clk, | ||
728 | &armtim_ck.clk, | ||
729 | &armwdt_ck.clk, | ||
730 | &arminth_ck1510, &arminth_ck16xx, | ||
731 | /* CK_GEN2 clocks */ | ||
732 | &dsp_ck, | ||
733 | &dspmmu_ck, | ||
734 | &dspper_ck, | ||
735 | &dspxor_ck, | ||
736 | &dsptim_ck, | ||
737 | /* CK_GEN3 clocks */ | ||
738 | &tc_ck.clk, | ||
739 | &tipb_ck, | ||
740 | &l3_ocpi_ck, | ||
741 | &tc1_ck, | ||
742 | &tc2_ck, | ||
743 | &dma_ck, | ||
744 | &dma_lcdfree_ck, | ||
745 | &api_ck.clk, | ||
746 | &lb_ck.clk, | ||
747 | &rhea1_ck, | ||
748 | &rhea2_ck, | ||
749 | &lcd_ck_16xx, | ||
750 | &lcd_ck_1510.clk, | ||
751 | /* ULPD clocks */ | ||
752 | &uart1_1510, | ||
753 | &uart1_16xx.clk, | ||
754 | &uart2_ck, | ||
755 | &uart3_1510, | ||
756 | &uart3_16xx.clk, | ||
757 | &usb_clko, | ||
758 | &usb_hhc_ck1510, &usb_hhc_ck16xx, | ||
759 | &usb_dc_ck, | ||
760 | &mclk_1510, &mclk_16xx, | ||
761 | &bclk_1510, &bclk_16xx, | ||
762 | &mmc1_ck, | ||
763 | &mmc2_ck, | ||
764 | /* Virtual clocks */ | ||
765 | &virtual_ck_mpu, | ||
766 | }; | ||
767 | |||
768 | #endif | ||
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 3c5d901efeaa..ecbc47514adc 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c | |||
@@ -25,56 +25,7 @@ | |||
25 | #include <asm/arch/mux.h> | 25 | #include <asm/arch/mux.h> |
26 | #include <asm/arch/gpio.h> | 26 | #include <asm/arch/gpio.h> |
27 | 27 | ||
28 | 28 | extern void omap_nop_release(struct device *dev); | |
29 | static void omap_nop_release(struct device *dev) | ||
30 | { | ||
31 | /* Nothing */ | ||
32 | } | ||
33 | |||
34 | /*-------------------------------------------------------------------------*/ | ||
35 | |||
36 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) | ||
37 | |||
38 | #define OMAP_I2C_BASE 0xfffb3800 | ||
39 | |||
40 | static struct resource i2c_resources[] = { | ||
41 | { | ||
42 | .start = OMAP_I2C_BASE, | ||
43 | .end = OMAP_I2C_BASE + 0x3f, | ||
44 | .flags = IORESOURCE_MEM, | ||
45 | }, | ||
46 | { | ||
47 | .start = INT_I2C, | ||
48 | .flags = IORESOURCE_IRQ, | ||
49 | }, | ||
50 | }; | ||
51 | |||
52 | /* DMA not used; works around erratum writing to non-empty i2c fifo */ | ||
53 | |||
54 | static struct platform_device omap_i2c_device = { | ||
55 | .name = "i2c_omap", | ||
56 | .id = -1, | ||
57 | .dev = { | ||
58 | .release = omap_nop_release, | ||
59 | }, | ||
60 | .num_resources = ARRAY_SIZE(i2c_resources), | ||
61 | .resource = i2c_resources, | ||
62 | }; | ||
63 | |||
64 | static void omap_init_i2c(void) | ||
65 | { | ||
66 | /* FIXME define and use a boot tag, in case of boards that | ||
67 | * either don't wire up I2C, or chips that mux it differently... | ||
68 | * it can include clocking and address info, maybe more. | ||
69 | */ | ||
70 | omap_cfg_reg(I2C_SCL); | ||
71 | omap_cfg_reg(I2C_SDA); | ||
72 | |||
73 | (void) platform_device_register(&omap_i2c_device); | ||
74 | } | ||
75 | #else | ||
76 | static inline void omap_init_i2c(void) {} | ||
77 | #endif | ||
78 | 29 | ||
79 | /*-------------------------------------------------------------------------*/ | 30 | /*-------------------------------------------------------------------------*/ |
80 | 31 | ||
@@ -110,137 +61,6 @@ static inline void omap_init_irda(void) {} | |||
110 | 61 | ||
111 | /*-------------------------------------------------------------------------*/ | 62 | /*-------------------------------------------------------------------------*/ |
112 | 63 | ||
113 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) | ||
114 | |||
115 | #define OMAP_MMC1_BASE 0xfffb7800 | ||
116 | #define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */ | ||
117 | |||
118 | static struct omap_mmc_conf mmc1_conf; | ||
119 | |||
120 | static u64 mmc1_dmamask = 0xffffffff; | ||
121 | |||
122 | static struct resource mmc1_resources[] = { | ||
123 | { | ||
124 | .start = IO_ADDRESS(OMAP_MMC1_BASE), | ||
125 | .end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f, | ||
126 | .flags = IORESOURCE_MEM, | ||
127 | }, | ||
128 | { | ||
129 | .start = INT_MMC, | ||
130 | .flags = IORESOURCE_IRQ, | ||
131 | }, | ||
132 | }; | ||
133 | |||
134 | static struct platform_device mmc_omap_device1 = { | ||
135 | .name = "mmci-omap", | ||
136 | .id = 1, | ||
137 | .dev = { | ||
138 | .release = omap_nop_release, | ||
139 | .dma_mask = &mmc1_dmamask, | ||
140 | .platform_data = &mmc1_conf, | ||
141 | }, | ||
142 | .num_resources = ARRAY_SIZE(mmc1_resources), | ||
143 | .resource = mmc1_resources, | ||
144 | }; | ||
145 | |||
146 | #ifdef CONFIG_ARCH_OMAP16XX | ||
147 | |||
148 | static struct omap_mmc_conf mmc2_conf; | ||
149 | |||
150 | static u64 mmc2_dmamask = 0xffffffff; | ||
151 | |||
152 | static struct resource mmc2_resources[] = { | ||
153 | { | ||
154 | .start = IO_ADDRESS(OMAP_MMC2_BASE), | ||
155 | .end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f, | ||
156 | .flags = IORESOURCE_MEM, | ||
157 | }, | ||
158 | { | ||
159 | .start = INT_1610_MMC2, | ||
160 | .flags = IORESOURCE_IRQ, | ||
161 | }, | ||
162 | }; | ||
163 | |||
164 | static struct platform_device mmc_omap_device2 = { | ||
165 | .name = "mmci-omap", | ||
166 | .id = 2, | ||
167 | .dev = { | ||
168 | .release = omap_nop_release, | ||
169 | .dma_mask = &mmc2_dmamask, | ||
170 | .platform_data = &mmc2_conf, | ||
171 | }, | ||
172 | .num_resources = ARRAY_SIZE(mmc2_resources), | ||
173 | .resource = mmc2_resources, | ||
174 | }; | ||
175 | #endif | ||
176 | |||
177 | static void __init omap_init_mmc(void) | ||
178 | { | ||
179 | const struct omap_mmc_config *mmc_conf; | ||
180 | const struct omap_mmc_conf *mmc; | ||
181 | |||
182 | /* NOTE: assumes MMC was never (wrongly) enabled */ | ||
183 | mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config); | ||
184 | if (!mmc_conf) | ||
185 | return; | ||
186 | |||
187 | /* block 1 is always available and has just one pinout option */ | ||
188 | mmc = &mmc_conf->mmc[0]; | ||
189 | if (mmc->enabled) { | ||
190 | omap_cfg_reg(MMC_CMD); | ||
191 | omap_cfg_reg(MMC_CLK); | ||
192 | omap_cfg_reg(MMC_DAT0); | ||
193 | if (cpu_is_omap1710()) { | ||
194 | omap_cfg_reg(M15_1710_MMC_CLKI); | ||
195 | omap_cfg_reg(P19_1710_MMC_CMDDIR); | ||
196 | omap_cfg_reg(P20_1710_MMC_DATDIR0); | ||
197 | } | ||
198 | if (mmc->wire4) { | ||
199 | omap_cfg_reg(MMC_DAT1); | ||
200 | /* NOTE: DAT2 can be on W10 (here) or M15 */ | ||
201 | if (!mmc->nomux) | ||
202 | omap_cfg_reg(MMC_DAT2); | ||
203 | omap_cfg_reg(MMC_DAT3); | ||
204 | } | ||
205 | mmc1_conf = *mmc; | ||
206 | (void) platform_device_register(&mmc_omap_device1); | ||
207 | } | ||
208 | |||
209 | #ifdef CONFIG_ARCH_OMAP16XX | ||
210 | /* block 2 is on newer chips, and has many pinout options */ | ||
211 | mmc = &mmc_conf->mmc[1]; | ||
212 | if (mmc->enabled) { | ||
213 | if (!mmc->nomux) { | ||
214 | omap_cfg_reg(Y8_1610_MMC2_CMD); | ||
215 | omap_cfg_reg(Y10_1610_MMC2_CLK); | ||
216 | omap_cfg_reg(R18_1610_MMC2_CLKIN); | ||
217 | omap_cfg_reg(W8_1610_MMC2_DAT0); | ||
218 | if (mmc->wire4) { | ||
219 | omap_cfg_reg(V8_1610_MMC2_DAT1); | ||
220 | omap_cfg_reg(W15_1610_MMC2_DAT2); | ||
221 | omap_cfg_reg(R10_1610_MMC2_DAT3); | ||
222 | } | ||
223 | |||
224 | /* These are needed for the level shifter */ | ||
225 | omap_cfg_reg(V9_1610_MMC2_CMDDIR); | ||
226 | omap_cfg_reg(V5_1610_MMC2_DATDIR0); | ||
227 | omap_cfg_reg(W19_1610_MMC2_DATDIR1); | ||
228 | } | ||
229 | |||
230 | /* Feedback clock must be set on OMAP-1710 MMC2 */ | ||
231 | if (cpu_is_omap1710()) | ||
232 | omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24), | ||
233 | MOD_CONF_CTRL_1); | ||
234 | mmc2_conf = *mmc; | ||
235 | (void) platform_device_register(&mmc_omap_device2); | ||
236 | } | ||
237 | #endif | ||
238 | return; | ||
239 | } | ||
240 | #else | ||
241 | static inline void omap_init_mmc(void) {} | ||
242 | #endif | ||
243 | |||
244 | #if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC) | 64 | #if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC) |
245 | 65 | ||
246 | #define OMAP_RTC_BASE 0xfffb4800 | 66 | #define OMAP_RTC_BASE 0xfffb4800 |
@@ -279,38 +99,6 @@ static void omap_init_rtc(void) | |||
279 | static inline void omap_init_rtc(void) {} | 99 | static inline void omap_init_rtc(void) {} |
280 | #endif | 100 | #endif |
281 | 101 | ||
282 | /*-------------------------------------------------------------------------*/ | ||
283 | |||
284 | #if defined(CONFIG_OMAP16XX_WATCHDOG) || defined(CONFIG_OMAP16XX_WATCHDOG_MODULE) | ||
285 | |||
286 | #define OMAP_WDT_BASE 0xfffeb000 | ||
287 | |||
288 | static struct resource wdt_resources[] = { | ||
289 | { | ||
290 | .start = OMAP_WDT_BASE, | ||
291 | .end = OMAP_WDT_BASE + 0x4f, | ||
292 | .flags = IORESOURCE_MEM, | ||
293 | }, | ||
294 | }; | ||
295 | |||
296 | static struct platform_device omap_wdt_device = { | ||
297 | .name = "omap1610_wdt", | ||
298 | .id = -1, | ||
299 | .dev = { | ||
300 | .release = omap_nop_release, | ||
301 | }, | ||
302 | .num_resources = ARRAY_SIZE(wdt_resources), | ||
303 | .resource = wdt_resources, | ||
304 | }; | ||
305 | |||
306 | static void omap_init_wdt(void) | ||
307 | { | ||
308 | (void) platform_device_register(&omap_wdt_device); | ||
309 | } | ||
310 | #else | ||
311 | static inline void omap_init_wdt(void) {} | ||
312 | #endif | ||
313 | |||
314 | 102 | ||
315 | /*-------------------------------------------------------------------------*/ | 103 | /*-------------------------------------------------------------------------*/ |
316 | 104 | ||
@@ -334,18 +122,15 @@ static inline void omap_init_wdt(void) {} | |||
334 | * may be handled by the boot loader, and drivers should expect it will | 122 | * may be handled by the boot loader, and drivers should expect it will |
335 | * normally have been done by the time they're probed. | 123 | * normally have been done by the time they're probed. |
336 | */ | 124 | */ |
337 | static int __init omap_init_devices(void) | 125 | static int __init omap1_init_devices(void) |
338 | { | 126 | { |
339 | /* please keep these calls, and their implementations above, | 127 | /* please keep these calls, and their implementations above, |
340 | * in alphabetical order so they're easier to sort through. | 128 | * in alphabetical order so they're easier to sort through. |
341 | */ | 129 | */ |
342 | omap_init_i2c(); | ||
343 | omap_init_irda(); | 130 | omap_init_irda(); |
344 | omap_init_mmc(); | ||
345 | omap_init_rtc(); | 131 | omap_init_rtc(); |
346 | omap_init_wdt(); | ||
347 | 132 | ||
348 | return 0; | 133 | return 0; |
349 | } | 134 | } |
350 | arch_initcall(omap_init_devices); | 135 | arch_initcall(omap1_init_devices); |
351 | 136 | ||
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c index 986c3b7e09bb..5c637c048368 100644 --- a/arch/arm/mach-omap1/id.c +++ b/arch/arm/mach-omap1/id.c | |||
@@ -18,6 +18,13 @@ | |||
18 | 18 | ||
19 | #include <asm/io.h> | 19 | #include <asm/io.h> |
20 | 20 | ||
21 | #define OMAP_DIE_ID_0 0xfffe1800 | ||
22 | #define OMAP_DIE_ID_1 0xfffe1804 | ||
23 | #define OMAP_PRODUCTION_ID_0 0xfffe2000 | ||
24 | #define OMAP_PRODUCTION_ID_1 0xfffe2004 | ||
25 | #define OMAP32_ID_0 0xfffed400 | ||
26 | #define OMAP32_ID_1 0xfffed404 | ||
27 | |||
21 | struct omap_id { | 28 | struct omap_id { |
22 | u16 jtag_id; /* Used to determine OMAP type */ | 29 | u16 jtag_id; /* Used to determine OMAP type */ |
23 | u8 die_rev; /* Processor revision */ | 30 | u8 die_rev; /* Processor revision */ |
@@ -27,6 +34,7 @@ struct omap_id { | |||
27 | 34 | ||
28 | /* Register values to detect the OMAP version */ | 35 | /* Register values to detect the OMAP version */ |
29 | static struct omap_id omap_ids[] __initdata = { | 36 | static struct omap_id omap_ids[] __initdata = { |
37 | { .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000}, | ||
30 | { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100}, | 38 | { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100}, |
31 | { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300}, | 39 | { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300}, |
32 | { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000}, | 40 | { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000}, |
@@ -164,6 +172,7 @@ void __init omap_check_revision(void) | |||
164 | case 0x07: | 172 | case 0x07: |
165 | system_rev |= 0x07; | 173 | system_rev |= 0x07; |
166 | break; | 174 | break; |
175 | case 0x03: | ||
167 | case 0x15: | 176 | case 0x15: |
168 | system_rev |= 0x15; | 177 | system_rev |= 0x15; |
169 | break; | 178 | break; |
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index 79fb86535ebc..a7a19f75b9e1 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c | |||
@@ -15,9 +15,10 @@ | |||
15 | 15 | ||
16 | #include <asm/mach/map.h> | 16 | #include <asm/mach/map.h> |
17 | #include <asm/io.h> | 17 | #include <asm/io.h> |
18 | #include <asm/arch/mux.h> | ||
18 | #include <asm/arch/tc.h> | 19 | #include <asm/arch/tc.h> |
19 | 20 | ||
20 | extern int clk_init(void); | 21 | extern int omap1_clk_init(void); |
21 | extern void omap_check_revision(void); | 22 | extern void omap_check_revision(void); |
22 | extern void omap_sram_init(void); | 23 | extern void omap_sram_init(void); |
23 | 24 | ||
@@ -50,7 +51,7 @@ static struct map_desc omap730_io_desc[] __initdata = { | |||
50 | }; | 51 | }; |
51 | #endif | 52 | #endif |
52 | 53 | ||
53 | #ifdef CONFIG_ARCH_OMAP1510 | 54 | #ifdef CONFIG_ARCH_OMAP15XX |
54 | static struct map_desc omap1510_io_desc[] __initdata = { | 55 | static struct map_desc omap1510_io_desc[] __initdata = { |
55 | { | 56 | { |
56 | .virtual = OMAP1510_DSP_BASE, | 57 | .virtual = OMAP1510_DSP_BASE, |
@@ -98,7 +99,7 @@ static void __init _omap_map_io(void) | |||
98 | iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc)); | 99 | iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc)); |
99 | } | 100 | } |
100 | #endif | 101 | #endif |
101 | #ifdef CONFIG_ARCH_OMAP1510 | 102 | #ifdef CONFIG_ARCH_OMAP15XX |
102 | if (cpu_is_omap1510()) { | 103 | if (cpu_is_omap1510()) { |
103 | iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); | 104 | iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); |
104 | } | 105 | } |
@@ -119,7 +120,7 @@ static void __init _omap_map_io(void) | |||
119 | 120 | ||
120 | /* Must init clocks early to assure that timer interrupt works | 121 | /* Must init clocks early to assure that timer interrupt works |
121 | */ | 122 | */ |
122 | clk_init(); | 123 | omap1_clk_init(); |
123 | } | 124 | } |
124 | 125 | ||
125 | /* | 126 | /* |
@@ -127,7 +128,9 @@ static void __init _omap_map_io(void) | |||
127 | */ | 128 | */ |
128 | void __init omap_map_common_io(void) | 129 | void __init omap_map_common_io(void) |
129 | { | 130 | { |
130 | if (!initialized) | 131 | if (!initialized) { |
131 | _omap_map_io(); | 132 | _omap_map_io(); |
133 | omap1_mux_init(); | ||
134 | } | ||
132 | } | 135 | } |
133 | 136 | ||
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index 192ce6055faa..ed65a7d2e941 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | #include <asm/mach/irq.h> | 48 | #include <asm/mach/irq.h> |
49 | #include <asm/arch/gpio.h> | 49 | #include <asm/arch/gpio.h> |
50 | #include <asm/arch/cpu.h> | ||
50 | 51 | ||
51 | #include <asm/io.h> | 52 | #include <asm/io.h> |
52 | 53 | ||
@@ -147,11 +148,15 @@ static struct omap_irq_bank omap730_irq_banks[] = { | |||
147 | }; | 148 | }; |
148 | #endif | 149 | #endif |
149 | 150 | ||
150 | #ifdef CONFIG_ARCH_OMAP1510 | 151 | #ifdef CONFIG_ARCH_OMAP15XX |
151 | static struct omap_irq_bank omap1510_irq_banks[] = { | 152 | static struct omap_irq_bank omap1510_irq_banks[] = { |
152 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, | 153 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, |
153 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, | 154 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, |
154 | }; | 155 | }; |
156 | static struct omap_irq_bank omap310_irq_banks[] = { | ||
157 | { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 }, | ||
158 | { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 }, | ||
159 | }; | ||
155 | #endif | 160 | #endif |
156 | 161 | ||
157 | #if defined(CONFIG_ARCH_OMAP16XX) | 162 | #if defined(CONFIG_ARCH_OMAP16XX) |
@@ -181,11 +186,15 @@ void __init omap_init_irq(void) | |||
181 | irq_bank_count = ARRAY_SIZE(omap730_irq_banks); | 186 | irq_bank_count = ARRAY_SIZE(omap730_irq_banks); |
182 | } | 187 | } |
183 | #endif | 188 | #endif |
184 | #ifdef CONFIG_ARCH_OMAP1510 | 189 | #ifdef CONFIG_ARCH_OMAP15XX |
185 | if (cpu_is_omap1510()) { | 190 | if (cpu_is_omap1510()) { |
186 | irq_banks = omap1510_irq_banks; | 191 | irq_banks = omap1510_irq_banks; |
187 | irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); | 192 | irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); |
188 | } | 193 | } |
194 | if (cpu_is_omap310()) { | ||
195 | irq_banks = omap310_irq_banks; | ||
196 | irq_bank_count = ARRAY_SIZE(omap310_irq_banks); | ||
197 | } | ||
189 | #endif | 198 | #endif |
190 | #if defined(CONFIG_ARCH_OMAP16XX) | 199 | #if defined(CONFIG_ARCH_OMAP16XX) |
191 | if (cpu_is_omap16xx()) { | 200 | if (cpu_is_omap16xx()) { |
@@ -226,9 +235,11 @@ void __init omap_init_irq(void) | |||
226 | } | 235 | } |
227 | 236 | ||
228 | /* Unmask level 2 handler */ | 237 | /* Unmask level 2 handler */ |
229 | if (cpu_is_omap730()) { | 238 | |
239 | if (cpu_is_omap730()) | ||
230 | omap_unmask_irq(INT_730_IH2_IRQ); | 240 | omap_unmask_irq(INT_730_IH2_IRQ); |
231 | } else { | 241 | else if (cpu_is_omap1510()) |
232 | omap_unmask_irq(INT_IH2_IRQ); | 242 | omap_unmask_irq(INT_1510_IH2_IRQ); |
233 | } | 243 | else if (cpu_is_omap16xx()) |
244 | omap_unmask_irq(INT_1610_IH2_IRQ); | ||
234 | } | 245 | } |
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c index be283cda63dd..650650815915 100644 --- a/arch/arm/mach-omap1/leds-h2p2-debug.c +++ b/arch/arm/mach-omap1/leds-h2p2-debug.c | |||
@@ -13,12 +13,12 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/kernel_stat.h> | 14 | #include <linux/kernel_stat.h> |
15 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
16 | #include <linux/version.h> | ||
17 | 16 | ||
18 | #include <asm/io.h> | 17 | #include <asm/io.h> |
19 | #include <asm/hardware.h> | 18 | #include <asm/hardware.h> |
20 | #include <asm/leds.h> | 19 | #include <asm/leds.h> |
21 | #include <asm/system.h> | 20 | #include <asm/system.h> |
21 | #include <asm/mach-types.h> | ||
22 | 22 | ||
23 | #include <asm/arch/fpga.h> | 23 | #include <asm/arch/fpga.h> |
24 | #include <asm/arch/gpio.h> | 24 | #include <asm/arch/gpio.h> |
@@ -64,14 +64,19 @@ void h2p2_dbg_leds_event(led_event_t evt) | |||
64 | case led_stop: | 64 | case led_stop: |
65 | case led_halted: | 65 | case led_halted: |
66 | /* all leds off during suspend or shutdown */ | 66 | /* all leds off during suspend or shutdown */ |
67 | omap_set_gpio_dataout(GPIO_TIMER, 0); | 67 | |
68 | omap_set_gpio_dataout(GPIO_IDLE, 0); | 68 | if (! machine_is_omap_perseus2()) { |
69 | omap_set_gpio_dataout(GPIO_TIMER, 0); | ||
70 | omap_set_gpio_dataout(GPIO_IDLE, 0); | ||
71 | } | ||
72 | |||
69 | __raw_writew(~0, &fpga->leds); | 73 | __raw_writew(~0, &fpga->leds); |
70 | led_state &= ~LED_STATE_ENABLED; | 74 | led_state &= ~LED_STATE_ENABLED; |
71 | if (evt == led_halted) { | 75 | if (evt == led_halted) { |
72 | iounmap(fpga); | 76 | iounmap(fpga); |
73 | fpga = NULL; | 77 | fpga = NULL; |
74 | } | 78 | } |
79 | |||
75 | goto done; | 80 | goto done; |
76 | 81 | ||
77 | case led_claim: | 82 | case led_claim: |
@@ -86,18 +91,37 @@ void h2p2_dbg_leds_event(led_event_t evt) | |||
86 | #ifdef CONFIG_LEDS_TIMER | 91 | #ifdef CONFIG_LEDS_TIMER |
87 | case led_timer: | 92 | case led_timer: |
88 | led_state ^= LED_TIMER_ON; | 93 | led_state ^= LED_TIMER_ON; |
89 | omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON); | 94 | |
90 | goto done; | 95 | if (machine_is_omap_perseus2()) |
96 | hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER; | ||
97 | else { | ||
98 | omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON); | ||
99 | goto done; | ||
100 | } | ||
101 | |||
102 | break; | ||
91 | #endif | 103 | #endif |
92 | 104 | ||
93 | #ifdef CONFIG_LEDS_CPU | 105 | #ifdef CONFIG_LEDS_CPU |
94 | case led_idle_start: | 106 | case led_idle_start: |
95 | omap_set_gpio_dataout(GPIO_IDLE, 1); | 107 | if (machine_is_omap_perseus2()) |
96 | goto done; | 108 | hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE; |
109 | else { | ||
110 | omap_set_gpio_dataout(GPIO_IDLE, 1); | ||
111 | goto done; | ||
112 | } | ||
113 | |||
114 | break; | ||
97 | 115 | ||
98 | case led_idle_end: | 116 | case led_idle_end: |
99 | omap_set_gpio_dataout(GPIO_IDLE, 0); | 117 | if (machine_is_omap_perseus2()) |
100 | goto done; | 118 | hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE; |
119 | else { | ||
120 | omap_set_gpio_dataout(GPIO_IDLE, 0); | ||
121 | goto done; | ||
122 | } | ||
123 | |||
124 | break; | ||
101 | #endif | 125 | #endif |
102 | 126 | ||
103 | case led_green_on: | 127 | case led_green_on: |
@@ -136,7 +160,7 @@ void h2p2_dbg_leds_event(led_event_t evt) | |||
136 | /* | 160 | /* |
137 | * Actually burn the LEDs | 161 | * Actually burn the LEDs |
138 | */ | 162 | */ |
139 | if (led_state & LED_STATE_CLAIMED) | 163 | if (led_state & LED_STATE_ENABLED) |
140 | __raw_writew(~hw_led_state, &fpga->leds); | 164 | __raw_writew(~hw_led_state, &fpga->leds); |
141 | 165 | ||
142 | done: | 166 | done: |
diff --git a/arch/arm/mach-omap1/leds.c b/arch/arm/mach-omap1/leds.c index 5c6b1bb6e722..3f9dcac4fd41 100644 --- a/arch/arm/mach-omap1/leds.c +++ b/arch/arm/mach-omap1/leds.c | |||
@@ -33,7 +33,6 @@ omap_leds_init(void) | |||
33 | 33 | ||
34 | if (machine_is_omap_h2() | 34 | if (machine_is_omap_h2() |
35 | || machine_is_omap_h3() | 35 | || machine_is_omap_h3() |
36 | || machine_is_omap_perseus2() | ||
37 | #ifdef CONFIG_OMAP_OSK_MISTRAL | 36 | #ifdef CONFIG_OMAP_OSK_MISTRAL |
38 | || machine_is_omap_osk() | 37 | || machine_is_omap_osk() |
39 | #endif | 38 | #endif |
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c new file mode 100644 index 000000000000..d4b8d624e742 --- /dev/null +++ b/arch/arm/mach-omap1/mux.c | |||
@@ -0,0 +1,289 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap1/mux.c | ||
3 | * | ||
4 | * OMAP1 pin multiplexing configurations | ||
5 | * | ||
6 | * Copyright (C) 2003 - 2005 Nokia Corporation | ||
7 | * | ||
8 | * Written by Tony Lindgren <tony.lindgren@nokia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/config.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <asm/system.h> | ||
29 | #include <asm/io.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | |||
32 | #include <asm/arch/mux.h> | ||
33 | |||
34 | #ifdef CONFIG_OMAP_MUX | ||
35 | |||
36 | #ifdef CONFIG_ARCH_OMAP730 | ||
37 | struct pin_config __initdata_or_module omap730_pins[] = { | ||
38 | MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0) | ||
39 | MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0) | ||
40 | MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0) | ||
41 | MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0) | ||
42 | MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0) | ||
43 | MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0) | ||
44 | MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0) | ||
45 | MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0) | ||
46 | MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0) | ||
47 | MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0) | ||
48 | }; | ||
49 | #endif | ||
50 | |||
51 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) | ||
52 | struct pin_config __initdata_or_module omap1xxx_pins[] = { | ||
53 | /* | ||
54 | * description mux mode mux pull pull pull pu_pd pu dbg | ||
55 | * reg offset mode reg bit ena reg | ||
56 | */ | ||
57 | MUX_CFG("UART1_TX", 9, 21, 1, 2, 3, 0, NA, 0, 0) | ||
58 | MUX_CFG("UART1_RTS", 9, 12, 1, 2, 0, 0, NA, 0, 0) | ||
59 | |||
60 | /* UART2 (COM_UART_GATING), conflicts with USB2 */ | ||
61 | MUX_CFG("UART2_TX", C, 27, 1, 3, 3, 0, NA, 0, 0) | ||
62 | MUX_CFG("UART2_RX", C, 18, 0, 3, 1, 1, NA, 0, 0) | ||
63 | MUX_CFG("UART2_CTS", C, 21, 0, 3, 1, 1, NA, 0, 0) | ||
64 | MUX_CFG("UART2_RTS", C, 24, 1, 3, 2, 0, NA, 0, 0) | ||
65 | |||
66 | /* UART3 (GIGA_UART_GATING) */ | ||
67 | MUX_CFG("UART3_TX", 6, 0, 1, 0, 30, 0, NA, 0, 0) | ||
68 | MUX_CFG("UART3_RX", 6, 3, 0, 0, 31, 1, NA, 0, 0) | ||
69 | MUX_CFG("UART3_CTS", 5, 12, 2, 0, 24, 0, NA, 0, 0) | ||
70 | MUX_CFG("UART3_RTS", 5, 15, 2, 0, 25, 0, NA, 0, 0) | ||
71 | MUX_CFG("UART3_CLKREQ", 9, 27, 0, 2, 5, 0, NA, 0, 0) | ||
72 | MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0) | ||
73 | MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0) | ||
74 | |||
75 | /* PWT & PWL, conflicts with UART3 */ | ||
76 | MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0) | ||
77 | MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0) | ||
78 | |||
79 | /* USB internal master generic */ | ||
80 | MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1) | ||
81 | MUX_CFG("R18_1510_USB_GPIO0", 7, 9, 0, 1, 11, 1, NA, 0, 1) | ||
82 | /* works around erratum: W4_USB_PUEN and W4_USB_PUDIS are switched! */ | ||
83 | MUX_CFG("W4_USB_PUEN", D, 3, 3, 3, 5, 1, NA, 0, 1) | ||
84 | MUX_CFG("W4_USB_CLKO", D, 3, 1, 3, 5, 0, NA, 0, 1) | ||
85 | MUX_CFG("W4_USB_HIGHZ", D, 3, 4, 3, 5, 0, 3, 0, 1) | ||
86 | MUX_CFG("W4_GPIO58", D, 3, 7, 3, 5, 0, 3, 0, 1) | ||
87 | |||
88 | /* USB1 master */ | ||
89 | MUX_CFG("USB1_SUSP", 8, 27, 2, 1, 27, 0, NA, 0, 1) | ||
90 | MUX_CFG("USB1_SE0", 9, 0, 2, 1, 28, 0, NA, 0, 1) | ||
91 | MUX_CFG("W13_1610_USB1_SE0", 9, 0, 4, 1, 28, 0, NA, 0, 1) | ||
92 | MUX_CFG("USB1_TXEN", 9, 3, 2, 1, 29, 0, NA, 0, 1) | ||
93 | MUX_CFG("USB1_TXD", 9, 24, 1, 2, 4, 0, NA, 0, 1) | ||
94 | MUX_CFG("USB1_VP", A, 3, 1, 2, 7, 0, NA, 0, 1) | ||
95 | MUX_CFG("USB1_VM", A, 6, 1, 2, 8, 0, NA, 0, 1) | ||
96 | MUX_CFG("USB1_RCV", A, 9, 1, 2, 9, 0, NA, 0, 1) | ||
97 | MUX_CFG("USB1_SPEED", A, 12, 2, 2, 10, 0, NA, 0, 1) | ||
98 | MUX_CFG("R13_1610_USB1_SPEED", A, 12, 5, 2, 10, 0, NA, 0, 1) | ||
99 | MUX_CFG("R13_1710_USB1_SEO", A, 12, 5, 2, 10, 0, NA, 0, 1) | ||
100 | |||
101 | /* USB2 master */ | ||
102 | MUX_CFG("USB2_SUSP", B, 3, 1, 2, 17, 0, NA, 0, 1) | ||
103 | MUX_CFG("USB2_VP", B, 6, 1, 2, 18, 0, NA, 0, 1) | ||
104 | MUX_CFG("USB2_TXEN", B, 9, 1, 2, 19, 0, NA, 0, 1) | ||
105 | MUX_CFG("USB2_VM", C, 18, 1, 3, 0, 0, NA, 0, 1) | ||
106 | MUX_CFG("USB2_RCV", C, 21, 1, 3, 1, 0, NA, 0, 1) | ||
107 | MUX_CFG("USB2_SE0", C, 24, 2, 3, 2, 0, NA, 0, 1) | ||
108 | MUX_CFG("USB2_TXD", C, 27, 2, 3, 3, 0, NA, 0, 1) | ||
109 | |||
110 | /* OMAP-1510 GPIO */ | ||
111 | MUX_CFG("R18_1510_GPIO0", 7, 9, 0, 1, 11, 1, 0, 0, 1) | ||
112 | MUX_CFG("R19_1510_GPIO1", 7, 6, 0, 1, 10, 1, 0, 0, 1) | ||
113 | MUX_CFG("M14_1510_GPIO2", 7, 3, 0, 1, 9, 1, 0, 0, 1) | ||
114 | |||
115 | /* OMAP1610 GPIO */ | ||
116 | MUX_CFG("P18_1610_GPIO3", 7, 0, 0, 1, 8, 0, NA, 0, 1) | ||
117 | MUX_CFG("Y15_1610_GPIO17", A, 0, 7, 2, 6, 0, NA, 0, 1) | ||
118 | |||
119 | /* OMAP-1710 GPIO */ | ||
120 | MUX_CFG("R18_1710_GPIO0", 7, 9, 0, 1, 11, 1, 1, 1, 1) | ||
121 | MUX_CFG("V2_1710_GPIO10", F, 27, 1, 4, 3, 1, 4, 1, 1) | ||
122 | MUX_CFG("N21_1710_GPIO14", 6, 9, 0, 1, 1, 1, 1, 1, 1) | ||
123 | MUX_CFG("W15_1710_GPIO40", 9, 27, 7, 2, 5, 1, 2, 1, 1) | ||
124 | |||
125 | /* MPUIO */ | ||
126 | MUX_CFG("MPUIO2", 7, 18, 0, 1, 14, 1, NA, 0, 1) | ||
127 | MUX_CFG("N15_1610_MPUIO2", 7, 18, 0, 1, 14, 1, 1, 0, 1) | ||
128 | MUX_CFG("MPUIO4", 7, 15, 0, 1, 13, 1, NA, 0, 1) | ||
129 | MUX_CFG("MPUIO5", 7, 12, 0, 1, 12, 1, NA, 0, 1) | ||
130 | |||
131 | MUX_CFG("T20_1610_MPUIO5", 7, 12, 0, 1, 12, 0, 3, 0, 1) | ||
132 | MUX_CFG("W11_1610_MPUIO6", 10, 15, 2, 3, 8, 0, 3, 0, 1) | ||
133 | MUX_CFG("V10_1610_MPUIO7", A, 24, 2, 2, 14, 0, 2, 0, 1) | ||
134 | MUX_CFG("W11_1610_MPUIO9", 10, 15, 1, 3, 8, 0, 3, 0, 1) | ||
135 | MUX_CFG("V10_1610_MPUIO10", A, 24, 1, 2, 14, 0, 2, 0, 1) | ||
136 | MUX_CFG("W10_1610_MPUIO11", A, 18, 2, 2, 11, 0, 2, 0, 1) | ||
137 | MUX_CFG("E20_1610_MPUIO13", 3, 21, 1, 0, 7, 0, 0, 0, 1) | ||
138 | MUX_CFG("U20_1610_MPUIO14", 9, 6, 6, 0, 30, 0, 0, 0, 1) | ||
139 | MUX_CFG("E19_1610_MPUIO15", 3, 18, 1, 0, 6, 0, 0, 0, 1) | ||
140 | |||
141 | /* MCBSP2 */ | ||
142 | MUX_CFG("MCBSP2_CLKR", C, 6, 0, 2, 27, 1, NA, 0, 1) | ||
143 | MUX_CFG("MCBSP2_CLKX", C, 9, 0, 2, 29, 1, NA, 0, 1) | ||
144 | MUX_CFG("MCBSP2_DR", C, 0, 0, 2, 26, 1, NA, 0, 1) | ||
145 | MUX_CFG("MCBSP2_DX", C, 15, 0, 2, 31, 1, NA, 0, 1) | ||
146 | MUX_CFG("MCBSP2_FSR", C, 12, 0, 2, 30, 1, NA, 0, 1) | ||
147 | MUX_CFG("MCBSP2_FSX", C, 3, 0, 2, 27, 1, NA, 0, 1) | ||
148 | |||
149 | /* MCBSP3 NOTE: Mode must 1 for clock */ | ||
150 | MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1) | ||
151 | |||
152 | /* Misc ballouts */ | ||
153 | MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1) | ||
154 | MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0) | ||
155 | |||
156 | /* OMAP-1610 MMC2 */ | ||
157 | MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1) | ||
158 | MUX_CFG("V8_1610_MMC2_DAT1", B, 27, 6, 2, 25, 1, 2, 1, 1) | ||
159 | MUX_CFG("W15_1610_MMC2_DAT2", 9, 12, 6, 2, 5, 1, 2, 1, 1) | ||
160 | MUX_CFG("R10_1610_MMC2_DAT3", B, 18, 6, 2, 22, 1, 2, 1, 1) | ||
161 | MUX_CFG("Y10_1610_MMC2_CLK", B, 3, 6, 2, 17, 0, 2, 0, 1) | ||
162 | MUX_CFG("Y8_1610_MMC2_CMD", B, 24, 6, 2, 24, 1, 2, 1, 1) | ||
163 | MUX_CFG("V9_1610_MMC2_CMDDIR", B, 12, 6, 2, 20, 0, 2, 1, 1) | ||
164 | MUX_CFG("V5_1610_MMC2_DATDIR0", B, 15, 6, 2, 21, 0, 2, 1, 1) | ||
165 | MUX_CFG("W19_1610_MMC2_DATDIR1", 8, 15, 6, 1, 23, 0, 1, 1, 1) | ||
166 | MUX_CFG("R18_1610_MMC2_CLKIN", 7, 9, 6, 1, 11, 0, 1, 11, 1) | ||
167 | |||
168 | /* OMAP-1610 External Trace Interface */ | ||
169 | MUX_CFG("M19_1610_ETM_PSTAT0", 5, 27, 1, 0, 29, 0, 0, 0, 1) | ||
170 | MUX_CFG("L15_1610_ETM_PSTAT1", 5, 24, 1, 0, 28, 0, 0, 0, 1) | ||
171 | MUX_CFG("L18_1610_ETM_PSTAT2", 5, 21, 1, 0, 27, 0, 0, 0, 1) | ||
172 | MUX_CFG("L19_1610_ETM_D0", 5, 18, 1, 0, 26, 0, 0, 0, 1) | ||
173 | MUX_CFG("J19_1610_ETM_D6", 5, 0, 1, 0, 20, 0, 0, 0, 1) | ||
174 | MUX_CFG("J18_1610_ETM_D7", 5, 27, 1, 0, 19, 0, 0, 0, 1) | ||
175 | |||
176 | /* OMAP16XX GPIO */ | ||
177 | MUX_CFG("P20_1610_GPIO4", 6, 27, 0, 1, 7, 0, 1, 1, 1) | ||
178 | MUX_CFG("V9_1610_GPIO7", B, 12, 1, 2, 20, 0, 2, 1, 1) | ||
179 | MUX_CFG("W8_1610_GPIO9", B, 21, 0, 2, 23, 0, 2, 1, 1) | ||
180 | MUX_CFG("N20_1610_GPIO11", 6, 18, 0, 1, 4, 0, 1, 1, 1) | ||
181 | MUX_CFG("N19_1610_GPIO13", 6, 12, 0, 1, 2, 0, 1, 1, 1) | ||
182 | MUX_CFG("P10_1610_GPIO22", C, 0, 7, 2, 26, 0, 2, 1, 1) | ||
183 | MUX_CFG("V5_1610_GPIO24", B, 15, 7, 2, 21, 0, 2, 1, 1) | ||
184 | MUX_CFG("AA20_1610_GPIO_41", 9, 9, 7, 1, 31, 0, 1, 1, 1) | ||
185 | MUX_CFG("W19_1610_GPIO48", 8, 15, 7, 1, 23, 1, 1, 0, 1) | ||
186 | MUX_CFG("M7_1610_GPIO62", 10, 0, 0, 4, 24, 0, 4, 0, 1) | ||
187 | MUX_CFG("V14_16XX_GPIO37", 9, 18, 7, 2, 2, 0, 2, 2, 0) | ||
188 | MUX_CFG("R9_16XX_GPIO18", C, 18, 7, 3, 0, 0, 3, 0, 0) | ||
189 | MUX_CFG("L14_16XX_GPIO49", 6, 3, 7, 0, 31, 0, 0, 31, 0) | ||
190 | |||
191 | /* OMAP-1610 uWire */ | ||
192 | MUX_CFG("V19_1610_UWIRE_SCLK", 8, 6, 0, 1, 20, 0, 1, 1, 1) | ||
193 | MUX_CFG("U18_1610_UWIRE_SDI", 8, 0, 0, 1, 18, 0, 1, 1, 1) | ||
194 | MUX_CFG("W21_1610_UWIRE_SDO", 8, 3, 0, 1, 19, 0, 1, 1, 1) | ||
195 | MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1) | ||
196 | MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1) | ||
197 | MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1) | ||
198 | |||
199 | /* OMAP-1610 Flash */ | ||
200 | MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1) | ||
201 | MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1) | ||
202 | |||
203 | /* First MMC interface, same on 1510, 1610 and 1710 */ | ||
204 | MUX_CFG("MMC_CMD", A, 27, 0, 2, 15, 1, 2, 1, 1) | ||
205 | MUX_CFG("MMC_DAT1", A, 24, 0, 2, 14, 1, 2, 1, 1) | ||
206 | MUX_CFG("MMC_DAT2", A, 18, 0, 2, 12, 1, 2, 1, 1) | ||
207 | MUX_CFG("MMC_DAT0", B, 0, 0, 2, 16, 1, 2, 1, 1) | ||
208 | MUX_CFG("MMC_CLK", A, 21, 0, NA, 0, 0, NA, 0, 1) | ||
209 | MUX_CFG("MMC_DAT3", 10, 15, 0, 3, 8, 1, 3, 1, 1) | ||
210 | MUX_CFG("M15_1710_MMC_CLKI", 6, 21, 2, 0, 0, 0, NA, 0, 1) | ||
211 | MUX_CFG("P19_1710_MMC_CMDDIR", 6, 24, 6, 0, 0, 0, NA, 0, 1) | ||
212 | MUX_CFG("P20_1710_MMC_DATDIR0", 6, 27, 5, 0, 0, 0, NA, 0, 1) | ||
213 | |||
214 | /* OMAP-1610 USB0 alternate configuration */ | ||
215 | MUX_CFG("W9_USB0_TXEN", B, 9, 5, 2, 19, 0, 2, 0, 1) | ||
216 | MUX_CFG("AA9_USB0_VP", B, 6, 5, 2, 18, 0, 2, 0, 1) | ||
217 | MUX_CFG("Y5_USB0_RCV", C, 21, 5, 3, 1, 0, 1, 0, 1) | ||
218 | MUX_CFG("R9_USB0_VM", C, 18, 5, 3, 0, 0, 3, 0, 1) | ||
219 | MUX_CFG("V6_USB0_TXD", C, 27, 5, 3, 3, 0, 3, 0, 1) | ||
220 | MUX_CFG("W5_USB0_SE0", C, 24, 5, 3, 2, 0, 3, 0, 1) | ||
221 | MUX_CFG("V9_USB0_SPEED", B, 12, 5, 2, 20, 0, 2, 0, 1) | ||
222 | MUX_CFG("Y10_USB0_SUSP", B, 3, 5, 2, 17, 0, 2, 0, 1) | ||
223 | |||
224 | /* USB2 interface */ | ||
225 | MUX_CFG("W9_USB2_TXEN", B, 9, 1, NA, 0, 0, NA, 0, 1) | ||
226 | MUX_CFG("AA9_USB2_VP", B, 6, 1, NA, 0, 0, NA, 0, 1) | ||
227 | MUX_CFG("Y5_USB2_RCV", C, 21, 1, NA, 0, 0, NA, 0, 1) | ||
228 | MUX_CFG("R9_USB2_VM", C, 18, 1, NA, 0, 0, NA, 0, 1) | ||
229 | MUX_CFG("V6_USB2_TXD", C, 27, 2, NA, 0, 0, NA, 0, 1) | ||
230 | MUX_CFG("W5_USB2_SE0", C, 24, 2, NA, 0, 0, NA, 0, 1) | ||
231 | |||
232 | /* 16XX UART */ | ||
233 | MUX_CFG("R13_1610_UART1_TX", A, 12, 6, 2, 10, 0, 2, 10, 1) | ||
234 | MUX_CFG("V14_16XX_UART1_RX", 9, 18, 0, 2, 2, 0, 2, 2, 1) | ||
235 | MUX_CFG("R14_1610_UART1_CTS", 9, 15, 0, 2, 1, 0, 2, 1, 1) | ||
236 | MUX_CFG("AA15_1610_UART1_RTS", 9, 12, 1, 2, 0, 0, 2, 0, 1) | ||
237 | MUX_CFG("R9_16XX_UART2_RX", C, 18, 0, 3, 0, 0, 3, 0, 1) | ||
238 | MUX_CFG("L14_16XX_UART3_RX", 6, 3, 0, 0, 31, 0, 0, 31, 1) | ||
239 | |||
240 | /* I2C interface */ | ||
241 | MUX_CFG("I2C_SCL", 7, 24, 0, NA, 0, 0, NA, 0, 0) | ||
242 | MUX_CFG("I2C_SDA", 7, 27, 0, NA, 0, 0, NA, 0, 0) | ||
243 | |||
244 | /* Keypad */ | ||
245 | MUX_CFG("F18_1610_KBC0", 3, 15, 0, 0, 5, 1, 0, 0, 0) | ||
246 | MUX_CFG("D20_1610_KBC1", 3, 12, 0, 0, 4, 1, 0, 0, 0) | ||
247 | MUX_CFG("D19_1610_KBC2", 3, 9, 0, 0, 3, 1, 0, 0, 0) | ||
248 | MUX_CFG("E18_1610_KBC3", 3, 6, 0, 0, 2, 1, 0, 0, 0) | ||
249 | MUX_CFG("C21_1610_KBC4", 3, 3, 0, 0, 1, 1, 0, 0, 0) | ||
250 | MUX_CFG("G18_1610_KBR0", 4, 0, 0, 0, 10, 1, 0, 1, 0) | ||
251 | MUX_CFG("F19_1610_KBR1", 3, 27, 0, 0, 9, 1, 0, 1, 0) | ||
252 | MUX_CFG("H14_1610_KBR2", 3, 24, 0, 0, 8, 1, 0, 1, 0) | ||
253 | MUX_CFG("E20_1610_KBR3", 3, 21, 0, 0, 7, 1, 0, 1, 0) | ||
254 | MUX_CFG("E19_1610_KBR4", 3, 18, 0, 0, 6, 1, 0, 1, 0) | ||
255 | MUX_CFG("N19_1610_KBR5", 6, 12, 1, 1, 2, 1, 1, 1, 0) | ||
256 | |||
257 | /* Power management */ | ||
258 | MUX_CFG("T20_1610_LOW_PWR", 7, 12, 1, NA, 0, 0, NA, 0, 0) | ||
259 | |||
260 | /* MCLK Settings */ | ||
261 | MUX_CFG("V5_1710_MCLK_ON", B, 15, 0, NA, 0, 0, NA, 0, 0) | ||
262 | MUX_CFG("V5_1710_MCLK_OFF", B, 15, 6, NA, 0, 0, NA, 0, 0) | ||
263 | MUX_CFG("R10_1610_MCLK_ON", B, 18, 0, NA, 22, 0, NA, 1, 0) | ||
264 | MUX_CFG("R10_1610_MCLK_OFF", B, 18, 6, 2, 22, 1, 2, 1, 1) | ||
265 | |||
266 | /* CompactFlash controller, conflicts with MMC1 */ | ||
267 | MUX_CFG("P11_1610_CF_CD2", A, 27, 3, 2, 15, 1, 2, 1, 1) | ||
268 | MUX_CFG("R11_1610_CF_IOIS16", B, 0, 3, 2, 16, 1, 2, 1, 1) | ||
269 | MUX_CFG("V10_1610_CF_IREQ", A, 24, 3, 2, 14, 0, 2, 0, 1) | ||
270 | MUX_CFG("W10_1610_CF_RESET", A, 18, 3, 2, 12, 1, 2, 1, 1) | ||
271 | MUX_CFG("W11_1610_CF_CD1", 10, 15, 3, 3, 8, 1, 3, 1, 1) | ||
272 | }; | ||
273 | #endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */ | ||
274 | |||
275 | int __init omap1_mux_init(void) | ||
276 | { | ||
277 | |||
278 | #ifdef CONFIG_ARCH_OMAP730 | ||
279 | omap_mux_register(omap730_pins, ARRAY_SIZE(omap730_pins)); | ||
280 | #endif | ||
281 | |||
282 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) | ||
283 | omap_mux_register(omap1xxx_pins, ARRAY_SIZE(omap1xxx_pins)); | ||
284 | #endif | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | #endif | ||
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c index 40c4f7c40e73..6810cfb84462 100644 --- a/arch/arm/mach-omap1/serial.c +++ b/arch/arm/mach-omap1/serial.c | |||
@@ -109,9 +109,10 @@ static struct platform_device serial_device = { | |||
109 | * By default UART2 does not work on Innovator-1510 if you have | 109 | * By default UART2 does not work on Innovator-1510 if you have |
110 | * USB OHCI enabled. To use UART2, you must disable USB2 first. | 110 | * USB OHCI enabled. To use UART2, you must disable USB2 first. |
111 | */ | 111 | */ |
112 | void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS]) | 112 | void __init omap_serial_init(void) |
113 | { | 113 | { |
114 | int i; | 114 | int i; |
115 | const struct omap_uart_config *info; | ||
115 | 116 | ||
116 | if (cpu_is_omap730()) { | 117 | if (cpu_is_omap730()) { |
117 | serial_platform_data[0].regshift = 0; | 118 | serial_platform_data[0].regshift = 0; |
@@ -126,10 +127,14 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS]) | |||
126 | serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; | 127 | serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; |
127 | } | 128 | } |
128 | 129 | ||
130 | info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config); | ||
131 | if (info == NULL) | ||
132 | return; | ||
133 | |||
129 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { | 134 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { |
130 | unsigned char reg; | 135 | unsigned char reg; |
131 | 136 | ||
132 | if (ports[i] == 0) { | 137 | if (!((1 << i) & info->enabled_uarts)) { |
133 | serial_platform_data[i].membase = NULL; | 138 | serial_platform_data[i].membase = NULL; |
134 | serial_platform_data[i].mapbase = 0; | 139 | serial_platform_data[i].mapbase = 0; |
135 | continue; | 140 | continue; |
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index 191a9b1ee9b7..cdbf4d7620c6 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c | |||
@@ -226,8 +226,8 @@ unsigned long long sched_clock(void) | |||
226 | 226 | ||
227 | #ifdef CONFIG_OMAP_32K_TIMER | 227 | #ifdef CONFIG_OMAP_32K_TIMER |
228 | 228 | ||
229 | #ifdef CONFIG_ARCH_OMAP1510 | 229 | #ifdef CONFIG_ARCH_OMAP15XX |
230 | #error OMAP 32KHz timer does not currently work on 1510! | 230 | #error OMAP 32KHz timer does not currently work on 15XX! |
231 | #endif | 231 | #endif |
232 | 232 | ||
233 | /* | 233 | /* |
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig new file mode 100644 index 000000000000..578880943cf2 --- /dev/null +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -0,0 +1,22 @@ | |||
1 | comment "OMAP Core Type" | ||
2 | depends on ARCH_OMAP2 | ||
3 | |||
4 | config ARCH_OMAP24XX | ||
5 | bool "OMAP24xx Based System" | ||
6 | depends on ARCH_OMAP2 | ||
7 | |||
8 | config ARCH_OMAP2420 | ||
9 | bool "OMAP2420 support" | ||
10 | depends on ARCH_OMAP24XX | ||
11 | |||
12 | comment "OMAP Board Type" | ||
13 | depends on ARCH_OMAP2 | ||
14 | |||
15 | config MACH_OMAP_GENERIC | ||
16 | bool "Generic OMAP board" | ||
17 | depends on ARCH_OMAP2 && ARCH_OMAP24XX | ||
18 | |||
19 | config MACH_OMAP_H4 | ||
20 | bool "OMAP 2420 H4 board" | ||
21 | depends on ARCH_OMAP2 && ARCH_OMAP24XX | ||
22 | |||
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile new file mode 100644 index 000000000000..42041166435c --- /dev/null +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -0,0 +1,13 @@ | |||
1 | # | ||
2 | # Makefile for the linux kernel. | ||
3 | # | ||
4 | |||
5 | # Common support | ||
6 | obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o | ||
7 | |||
8 | obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o | ||
9 | |||
10 | # Specific board support | ||
11 | obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o | ||
12 | obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o | ||
13 | |||
diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot new file mode 100644 index 000000000000..565aff7f37a9 --- /dev/null +++ b/arch/arm/mach-omap2/Makefile.boot | |||
@@ -0,0 +1,3 @@ | |||
1 | zreladdr-y := 0x80008000 | ||
2 | params_phys-y := 0x80000100 | ||
3 | initrd_phys-y := 0x80800000 | ||
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c new file mode 100644 index 000000000000..c602e7a3d93e --- /dev/null +++ b/arch/arm/mach-omap2/board-generic.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap/omap2/board-generic.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Nokia Corporation | ||
5 | * Author: Paul Mundt <paul.mundt@nokia.com> | ||
6 | * | ||
7 | * Modified from mach-omap/omap1/board-generic.c | ||
8 | * | ||
9 | * Code for generic OMAP2 board. Should work on many OMAP2 systems where | ||
10 | * the bootloader passes the board-specific data to the kernel. | ||
11 | * Do not put any board specific code to this file; create a new machine | ||
12 | * type if you need custom low-level initializations. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License version 2 as | ||
16 | * published by the Free Software Foundation. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/device.h> | ||
22 | |||
23 | #include <asm/hardware.h> | ||
24 | #include <asm/mach-types.h> | ||
25 | #include <asm/mach/arch.h> | ||
26 | #include <asm/mach/map.h> | ||
27 | |||
28 | #include <asm/arch/gpio.h> | ||
29 | #include <asm/arch/mux.h> | ||
30 | #include <asm/arch/usb.h> | ||
31 | #include <asm/arch/board.h> | ||
32 | #include <asm/arch/common.h> | ||
33 | |||
34 | static void __init omap_generic_init_irq(void) | ||
35 | { | ||
36 | omap_init_irq(); | ||
37 | } | ||
38 | |||
39 | static struct omap_uart_config generic_uart_config __initdata = { | ||
40 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
41 | }; | ||
42 | |||
43 | static struct omap_mmc_config generic_mmc_config __initdata = { | ||
44 | .mmc [0] = { | ||
45 | .enabled = 0, | ||
46 | .wire4 = 0, | ||
47 | .wp_pin = -1, | ||
48 | .power_pin = -1, | ||
49 | .switch_pin = -1, | ||
50 | }, | ||
51 | }; | ||
52 | |||
53 | static struct omap_board_config_kernel generic_config[] = { | ||
54 | { OMAP_TAG_UART, &generic_uart_config }, | ||
55 | { OMAP_TAG_MMC, &generic_mmc_config }, | ||
56 | }; | ||
57 | |||
58 | static void __init omap_generic_init(void) | ||
59 | { | ||
60 | omap_board_config = generic_config; | ||
61 | omap_board_config_size = ARRAY_SIZE(generic_config); | ||
62 | omap_serial_init(); | ||
63 | } | ||
64 | |||
65 | static void __init omap_generic_map_io(void) | ||
66 | { | ||
67 | omap_map_common_io(); | ||
68 | } | ||
69 | |||
70 | MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") | ||
71 | /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ | ||
72 | .phys_ram = 0x80000000, | ||
73 | .phys_io = 0x48000000, | ||
74 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, | ||
75 | .boot_params = 0x80000100, | ||
76 | .map_io = omap_generic_map_io, | ||
77 | .init_irq = omap_generic_init_irq, | ||
78 | .init_machine = omap_generic_init, | ||
79 | .timer = &omap_timer, | ||
80 | MACHINE_END | ||
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c new file mode 100644 index 000000000000..f2554469a76a --- /dev/null +++ b/arch/arm/mach-omap2/board-h4.c | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap/omap2/board-h4.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Nokia Corporation | ||
5 | * Author: Paul Mundt <paul.mundt@nokia.com> | ||
6 | * | ||
7 | * Modified from mach-omap/omap1/board-generic.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/mtd/mtd.h> | ||
18 | #include <linux/mtd/partitions.h> | ||
19 | #include <linux/delay.h> | ||
20 | |||
21 | #include <asm/hardware.h> | ||
22 | #include <asm/mach-types.h> | ||
23 | #include <asm/mach/arch.h> | ||
24 | #include <asm/mach/map.h> | ||
25 | #include <asm/mach/flash.h> | ||
26 | |||
27 | #include <asm/arch/gpio.h> | ||
28 | #include <asm/arch/mux.h> | ||
29 | #include <asm/arch/usb.h> | ||
30 | #include <asm/arch/board.h> | ||
31 | #include <asm/arch/common.h> | ||
32 | #include <asm/arch/prcm.h> | ||
33 | |||
34 | #include <asm/io.h> | ||
35 | #include <asm/delay.h> | ||
36 | |||
37 | static struct mtd_partition h4_partitions[] = { | ||
38 | /* bootloader (U-Boot, etc) in first sector */ | ||
39 | { | ||
40 | .name = "bootloader", | ||
41 | .offset = 0, | ||
42 | .size = SZ_128K, | ||
43 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
44 | }, | ||
45 | /* bootloader params in the next sector */ | ||
46 | { | ||
47 | .name = "params", | ||
48 | .offset = MTDPART_OFS_APPEND, | ||
49 | .size = SZ_128K, | ||
50 | .mask_flags = 0, | ||
51 | }, | ||
52 | /* kernel */ | ||
53 | { | ||
54 | .name = "kernel", | ||
55 | .offset = MTDPART_OFS_APPEND, | ||
56 | .size = SZ_2M, | ||
57 | .mask_flags = 0 | ||
58 | }, | ||
59 | /* file system */ | ||
60 | { | ||
61 | .name = "filesystem", | ||
62 | .offset = MTDPART_OFS_APPEND, | ||
63 | .size = MTDPART_SIZ_FULL, | ||
64 | .mask_flags = 0 | ||
65 | } | ||
66 | }; | ||
67 | |||
68 | static struct flash_platform_data h4_flash_data = { | ||
69 | .map_name = "cfi_probe", | ||
70 | .width = 2, | ||
71 | .parts = h4_partitions, | ||
72 | .nr_parts = ARRAY_SIZE(h4_partitions), | ||
73 | }; | ||
74 | |||
75 | static struct resource h4_flash_resource = { | ||
76 | .start = H4_CS0_BASE, | ||
77 | .end = H4_CS0_BASE + SZ_64M - 1, | ||
78 | .flags = IORESOURCE_MEM, | ||
79 | }; | ||
80 | |||
81 | static struct platform_device h4_flash_device = { | ||
82 | .name = "omapflash", | ||
83 | .id = 0, | ||
84 | .dev = { | ||
85 | .platform_data = &h4_flash_data, | ||
86 | }, | ||
87 | .num_resources = 1, | ||
88 | .resource = &h4_flash_resource, | ||
89 | }; | ||
90 | |||
91 | static struct resource h4_smc91x_resources[] = { | ||
92 | [0] = { | ||
93 | .start = OMAP24XX_ETHR_START, /* Physical */ | ||
94 | .end = OMAP24XX_ETHR_START + 0xf, | ||
95 | .flags = IORESOURCE_MEM, | ||
96 | }, | ||
97 | [1] = { | ||
98 | .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), | ||
99 | .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ), | ||
100 | .flags = IORESOURCE_IRQ, | ||
101 | }, | ||
102 | }; | ||
103 | |||
104 | static struct platform_device h4_smc91x_device = { | ||
105 | .name = "smc91x", | ||
106 | .id = -1, | ||
107 | .num_resources = ARRAY_SIZE(h4_smc91x_resources), | ||
108 | .resource = h4_smc91x_resources, | ||
109 | }; | ||
110 | |||
111 | static struct platform_device *h4_devices[] __initdata = { | ||
112 | &h4_smc91x_device, | ||
113 | &h4_flash_device, | ||
114 | }; | ||
115 | |||
116 | static inline void __init h4_init_smc91x(void) | ||
117 | { | ||
118 | /* Make sure CS1 timings are correct */ | ||
119 | GPMC_CONFIG1_1 = 0x00011200; | ||
120 | GPMC_CONFIG2_1 = 0x001f1f01; | ||
121 | GPMC_CONFIG3_1 = 0x00080803; | ||
122 | GPMC_CONFIG4_1 = 0x1c091c09; | ||
123 | GPMC_CONFIG5_1 = 0x041f1f1f; | ||
124 | GPMC_CONFIG6_1 = 0x000004c4; | ||
125 | GPMC_CONFIG7_1 = 0x00000f40 | (0x08000000 >> 24); | ||
126 | udelay(100); | ||
127 | |||
128 | omap_cfg_reg(M15_24XX_GPIO92); | ||
129 | if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) { | ||
130 | printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", | ||
131 | OMAP24XX_ETHR_GPIO_IRQ); | ||
132 | return; | ||
133 | } | ||
134 | omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1); | ||
135 | } | ||
136 | |||
137 | static void __init omap_h4_init_irq(void) | ||
138 | { | ||
139 | omap_init_irq(); | ||
140 | omap_gpio_init(); | ||
141 | h4_init_smc91x(); | ||
142 | } | ||
143 | |||
144 | static struct omap_uart_config h4_uart_config __initdata = { | ||
145 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
146 | }; | ||
147 | |||
148 | static struct omap_mmc_config h4_mmc_config __initdata = { | ||
149 | .mmc [0] = { | ||
150 | .enabled = 1, | ||
151 | .wire4 = 1, | ||
152 | .wp_pin = -1, | ||
153 | .power_pin = -1, | ||
154 | .switch_pin = -1, | ||
155 | }, | ||
156 | }; | ||
157 | |||
158 | static struct omap_lcd_config h4_lcd_config __initdata = { | ||
159 | .panel_name = "h4", | ||
160 | .ctrl_name = "internal", | ||
161 | }; | ||
162 | |||
163 | static struct omap_board_config_kernel h4_config[] = { | ||
164 | { OMAP_TAG_UART, &h4_uart_config }, | ||
165 | { OMAP_TAG_MMC, &h4_mmc_config }, | ||
166 | { OMAP_TAG_LCD, &h4_lcd_config }, | ||
167 | }; | ||
168 | |||
169 | static void __init omap_h4_init(void) | ||
170 | { | ||
171 | /* | ||
172 | * Make sure the serial ports are muxed on at this point. | ||
173 | * You have to mux them off in device drivers later on | ||
174 | * if not needed. | ||
175 | */ | ||
176 | platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); | ||
177 | omap_board_config = h4_config; | ||
178 | omap_board_config_size = ARRAY_SIZE(h4_config); | ||
179 | omap_serial_init(); | ||
180 | } | ||
181 | |||
182 | static void __init omap_h4_map_io(void) | ||
183 | { | ||
184 | omap_map_common_io(); | ||
185 | } | ||
186 | |||
187 | MACHINE_START(OMAP_H4, "OMAP2420 H4 board") | ||
188 | /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ | ||
189 | .phys_ram = 0x80000000, | ||
190 | .phys_io = 0x48000000, | ||
191 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, | ||
192 | .boot_params = 0x80000100, | ||
193 | .map_io = omap_h4_map_io, | ||
194 | .init_irq = omap_h4_init_irq, | ||
195 | .init_machine = omap_h4_init, | ||
196 | .timer = &omap_timer, | ||
197 | MACHINE_END | ||
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c new file mode 100644 index 000000000000..85818d9f2635 --- /dev/null +++ b/arch/arm/mach-omap2/clock.c | |||
@@ -0,0 +1,1129 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/clock.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Texas Instruments Inc. | ||
5 | * Richard Woodruff <r-woodruff2@ti.com> | ||
6 | * Created for OMAP2. | ||
7 | * | ||
8 | * Cleaned up and modified to use omap shared clock framework by | ||
9 | * Tony Lindgren <tony@atomide.com> | ||
10 | * | ||
11 | * Based on omap1 clock.c, Copyright (C) 2004 - 2005 Nokia corporation | ||
12 | * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License version 2 as | ||
16 | * published by the Free Software Foundation. | ||
17 | */ | ||
18 | #include <linux/config.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/list.h> | ||
23 | #include <linux/errno.h> | ||
24 | #include <linux/delay.h> | ||
25 | |||
26 | #include <asm/io.h> | ||
27 | |||
28 | #include <asm/hardware/clock.h> | ||
29 | #include <asm/arch/clock.h> | ||
30 | #include <asm/arch/sram.h> | ||
31 | #include <asm/arch/prcm.h> | ||
32 | |||
33 | #include "clock.h" | ||
34 | |||
35 | //#define DOWN_VARIABLE_DPLL 1 /* Experimental */ | ||
36 | |||
37 | static struct prcm_config *curr_prcm_set; | ||
38 | static struct memory_timings mem_timings; | ||
39 | static u32 curr_perf_level = PRCM_FULL_SPEED; | ||
40 | |||
41 | /*------------------------------------------------------------------------- | ||
42 | * Omap2 specific clock functions | ||
43 | *-------------------------------------------------------------------------*/ | ||
44 | |||
45 | /* Recalculate SYST_CLK */ | ||
46 | static void omap2_sys_clk_recalc(struct clk * clk) | ||
47 | { | ||
48 | u32 div = PRCM_CLKSRC_CTRL; | ||
49 | div &= (1 << 7) | (1 << 6); /* Test if ext clk divided by 1 or 2 */ | ||
50 | div >>= clk->rate_offset; | ||
51 | clk->rate = (clk->parent->rate / div); | ||
52 | propagate_rate(clk); | ||
53 | } | ||
54 | |||
55 | static u32 omap2_get_dpll_rate(struct clk * tclk) | ||
56 | { | ||
57 | int dpll_clk, dpll_mult, dpll_div, amult; | ||
58 | |||
59 | dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */ | ||
60 | dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */ | ||
61 | dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1); | ||
62 | amult = CM_CLKSEL2_PLL & 0x3; | ||
63 | dpll_clk *= amult; | ||
64 | |||
65 | return dpll_clk; | ||
66 | } | ||
67 | |||
68 | static void omap2_followparent_recalc(struct clk *clk) | ||
69 | { | ||
70 | followparent_recalc(clk); | ||
71 | } | ||
72 | |||
73 | static void omap2_propagate_rate(struct clk * clk) | ||
74 | { | ||
75 | if (!(clk->flags & RATE_FIXED)) | ||
76 | clk->rate = clk->parent->rate; | ||
77 | |||
78 | propagate_rate(clk); | ||
79 | } | ||
80 | |||
81 | /* Enable an APLL if off */ | ||
82 | static void omap2_clk_fixed_enable(struct clk *clk) | ||
83 | { | ||
84 | u32 cval, i=0; | ||
85 | |||
86 | if (clk->enable_bit == 0xff) /* Parent will do it */ | ||
87 | return; | ||
88 | |||
89 | cval = CM_CLKEN_PLL; | ||
90 | |||
91 | if ((cval & (0x3 << clk->enable_bit)) == (0x3 << clk->enable_bit)) | ||
92 | return; | ||
93 | |||
94 | cval &= ~(0x3 << clk->enable_bit); | ||
95 | cval |= (0x3 << clk->enable_bit); | ||
96 | CM_CLKEN_PLL = cval; | ||
97 | |||
98 | if (clk == &apll96_ck) | ||
99 | cval = (1 << 8); | ||
100 | else if (clk == &apll54_ck) | ||
101 | cval = (1 << 6); | ||
102 | |||
103 | while (!CM_IDLEST_CKGEN & cval) { /* Wait for lock */ | ||
104 | ++i; | ||
105 | udelay(1); | ||
106 | if (i == 100000) | ||
107 | break; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | /* Enables clock without considering parent dependencies or use count | ||
112 | * REVISIT: Maybe change this to use clk->enable like on omap1? | ||
113 | */ | ||
114 | static int omap2_clk_enable(struct clk * clk) | ||
115 | { | ||
116 | u32 regval32; | ||
117 | |||
118 | if (clk->flags & ALWAYS_ENABLED) | ||
119 | return 0; | ||
120 | |||
121 | if (unlikely(clk->enable_reg == 0)) { | ||
122 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", | ||
123 | clk->name); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) { | ||
128 | omap2_clk_fixed_enable(clk); | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | regval32 = __raw_readl(clk->enable_reg); | ||
133 | regval32 |= (1 << clk->enable_bit); | ||
134 | __raw_writel(regval32, clk->enable_reg); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | /* Stop APLL */ | ||
140 | static void omap2_clk_fixed_disable(struct clk *clk) | ||
141 | { | ||
142 | u32 cval; | ||
143 | |||
144 | if(clk->enable_bit == 0xff) /* let parent off do it */ | ||
145 | return; | ||
146 | |||
147 | cval = CM_CLKEN_PLL; | ||
148 | cval &= ~(0x3 << clk->enable_bit); | ||
149 | CM_CLKEN_PLL = cval; | ||
150 | } | ||
151 | |||
152 | /* Disables clock without considering parent dependencies or use count */ | ||
153 | static void omap2_clk_disable(struct clk *clk) | ||
154 | { | ||
155 | u32 regval32; | ||
156 | |||
157 | if (clk->enable_reg == 0) | ||
158 | return; | ||
159 | |||
160 | if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) { | ||
161 | omap2_clk_fixed_disable(clk); | ||
162 | return; | ||
163 | } | ||
164 | |||
165 | regval32 = __raw_readl(clk->enable_reg); | ||
166 | regval32 &= ~(1 << clk->enable_bit); | ||
167 | __raw_writel(regval32, clk->enable_reg); | ||
168 | } | ||
169 | |||
170 | static int omap2_clk_use(struct clk *clk) | ||
171 | { | ||
172 | int ret = 0; | ||
173 | |||
174 | if (clk->usecount++ == 0) { | ||
175 | if (likely((u32)clk->parent)) | ||
176 | ret = omap2_clk_use(clk->parent); | ||
177 | |||
178 | if (unlikely(ret != 0)) { | ||
179 | clk->usecount--; | ||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | ret = omap2_clk_enable(clk); | ||
184 | |||
185 | if (unlikely(ret != 0) && clk->parent) { | ||
186 | omap2_clk_unuse(clk->parent); | ||
187 | clk->usecount--; | ||
188 | } | ||
189 | } | ||
190 | |||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | static void omap2_clk_unuse(struct clk *clk) | ||
195 | { | ||
196 | if (clk->usecount > 0 && !(--clk->usecount)) { | ||
197 | omap2_clk_disable(clk); | ||
198 | if (likely((u32)clk->parent)) | ||
199 | omap2_clk_unuse(clk->parent); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * Uses the current prcm set to tell if a rate is valid. | ||
205 | * You can go slower, but not faster within a given rate set. | ||
206 | */ | ||
207 | static u32 omap2_dpll_round_rate(unsigned long target_rate) | ||
208 | { | ||
209 | u32 high, low; | ||
210 | |||
211 | if ((CM_CLKSEL2_PLL & 0x3) == 1) { /* DPLL clockout */ | ||
212 | high = curr_prcm_set->dpll_speed * 2; | ||
213 | low = curr_prcm_set->dpll_speed; | ||
214 | } else { /* DPLL clockout x 2 */ | ||
215 | high = curr_prcm_set->dpll_speed; | ||
216 | low = curr_prcm_set->dpll_speed / 2; | ||
217 | } | ||
218 | |||
219 | #ifdef DOWN_VARIABLE_DPLL | ||
220 | if (target_rate > high) | ||
221 | return high; | ||
222 | else | ||
223 | return target_rate; | ||
224 | #else | ||
225 | if (target_rate > low) | ||
226 | return high; | ||
227 | else | ||
228 | return low; | ||
229 | #endif | ||
230 | |||
231 | } | ||
232 | |||
233 | /* | ||
234 | * Used for clocks that are part of CLKSEL_xyz governed clocks. | ||
235 | * REVISIT: Maybe change to use clk->enable() functions like on omap1? | ||
236 | */ | ||
237 | static void omap2_clksel_recalc(struct clk * clk) | ||
238 | { | ||
239 | u32 fixed = 0, div = 0; | ||
240 | |||
241 | if (clk == &dpll_ck) { | ||
242 | clk->rate = omap2_get_dpll_rate(clk); | ||
243 | fixed = 1; | ||
244 | div = 0; | ||
245 | } | ||
246 | |||
247 | if (clk == &iva1_mpu_int_ifck) { | ||
248 | div = 2; | ||
249 | fixed = 1; | ||
250 | } | ||
251 | |||
252 | if ((clk == &dss1_fck) && ((CM_CLKSEL1_CORE & (0x1f << 8)) == 0)) { | ||
253 | clk->rate = sys_ck.rate; | ||
254 | return; | ||
255 | } | ||
256 | |||
257 | if (!fixed) { | ||
258 | div = omap2_clksel_get_divisor(clk); | ||
259 | if (div == 0) | ||
260 | return; | ||
261 | } | ||
262 | |||
263 | if (div != 0) { | ||
264 | if (unlikely(clk->rate == clk->parent->rate / div)) | ||
265 | return; | ||
266 | clk->rate = clk->parent->rate / div; | ||
267 | } | ||
268 | |||
269 | if (unlikely(clk->flags & RATE_PROPAGATES)) | ||
270 | propagate_rate(clk); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * Finds best divider value in an array based on the source and target | ||
275 | * rates. The divider array must be sorted with smallest divider first. | ||
276 | */ | ||
277 | static inline u32 omap2_divider_from_table(u32 size, u32 *div_array, | ||
278 | u32 src_rate, u32 tgt_rate) | ||
279 | { | ||
280 | int i, test_rate; | ||
281 | |||
282 | if (div_array == NULL) | ||
283 | return ~1; | ||
284 | |||
285 | for (i=0; i < size; i++) { | ||
286 | test_rate = src_rate / *div_array; | ||
287 | if (test_rate <= tgt_rate) | ||
288 | return *div_array; | ||
289 | ++div_array; | ||
290 | } | ||
291 | |||
292 | return ~0; /* No acceptable divider */ | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Find divisor for the given clock and target rate. | ||
297 | * | ||
298 | * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT, | ||
299 | * they are only settable as part of virtual_prcm set. | ||
300 | */ | ||
301 | static u32 omap2_clksel_round_rate(struct clk *tclk, u32 target_rate, | ||
302 | u32 *new_div) | ||
303 | { | ||
304 | u32 gfx_div[] = {2, 3, 4}; | ||
305 | u32 sysclkout_div[] = {1, 2, 4, 8, 16}; | ||
306 | u32 dss1_div[] = {1, 2, 3, 4, 5, 6, 8, 9, 12, 16}; | ||
307 | u32 vylnq_div[] = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18}; | ||
308 | u32 best_div = ~0, asize = 0; | ||
309 | u32 *div_array = NULL; | ||
310 | |||
311 | switch (tclk->flags & SRC_RATE_SEL_MASK) { | ||
312 | case CM_GFX_SEL1: | ||
313 | asize = 3; | ||
314 | div_array = gfx_div; | ||
315 | break; | ||
316 | case CM_PLL_SEL1: | ||
317 | return omap2_dpll_round_rate(target_rate); | ||
318 | case CM_SYSCLKOUT_SEL1: | ||
319 | asize = 5; | ||
320 | div_array = sysclkout_div; | ||
321 | break; | ||
322 | case CM_CORE_SEL1: | ||
323 | if(tclk == &dss1_fck){ | ||
324 | if(tclk->parent == &core_ck){ | ||
325 | asize = 10; | ||
326 | div_array = dss1_div; | ||
327 | } else { | ||
328 | *new_div = 0; /* fixed clk */ | ||
329 | return(tclk->parent->rate); | ||
330 | } | ||
331 | } else if((tclk == &vlynq_fck) && cpu_is_omap2420()){ | ||
332 | if(tclk->parent == &core_ck){ | ||
333 | asize = 10; | ||
334 | div_array = vylnq_div; | ||
335 | } else { | ||
336 | *new_div = 0; /* fixed clk */ | ||
337 | return(tclk->parent->rate); | ||
338 | } | ||
339 | } | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | best_div = omap2_divider_from_table(asize, div_array, | ||
344 | tclk->parent->rate, target_rate); | ||
345 | if (best_div == ~0){ | ||
346 | *new_div = 1; | ||
347 | return best_div; /* signal error */ | ||
348 | } | ||
349 | |||
350 | *new_div = best_div; | ||
351 | return (tclk->parent->rate / best_div); | ||
352 | } | ||
353 | |||
354 | /* Given a clock and a rate apply a clock specific rounding function */ | ||
355 | static long omap2_clk_round_rate(struct clk *clk, unsigned long rate) | ||
356 | { | ||
357 | u32 new_div = 0; | ||
358 | int valid_rate; | ||
359 | |||
360 | if (clk->flags & RATE_FIXED) | ||
361 | return clk->rate; | ||
362 | |||
363 | if (clk->flags & RATE_CKCTL) { | ||
364 | valid_rate = omap2_clksel_round_rate(clk, rate, &new_div); | ||
365 | return valid_rate; | ||
366 | } | ||
367 | |||
368 | if (clk->round_rate != 0) | ||
369 | return clk->round_rate(clk, rate); | ||
370 | |||
371 | return clk->rate; | ||
372 | } | ||
373 | |||
374 | /* | ||
375 | * Check the DLL lock state, and return tue if running in unlock mode. | ||
376 | * This is needed to compenste for the shifted DLL value in unlock mode. | ||
377 | */ | ||
378 | static u32 omap2_dll_force_needed(void) | ||
379 | { | ||
380 | u32 dll_state = SDRC_DLLA_CTRL; /* dlla and dllb are a set */ | ||
381 | |||
382 | if ((dll_state & (1 << 2)) == (1 << 2)) | ||
383 | return 1; | ||
384 | else | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static void omap2_init_memory_params(u32 force_lock_to_unlock_mode) | ||
389 | { | ||
390 | unsigned long dll_cnt; | ||
391 | u32 fast_dll = 0; | ||
392 | |||
393 | mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */ | ||
394 | |||
395 | /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others. | ||
396 | * In the case of 2422, its ok to use CS1 instead of CS0. | ||
397 | */ | ||
398 | |||
399 | #if 0 /* FIXME: Enable after 24xx cpu detection works */ | ||
400 | ctype = get_cpu_type(); | ||
401 | if (cpu_is_omap2422()) | ||
402 | mem_timings.base_cs = 1; | ||
403 | else | ||
404 | #endif | ||
405 | mem_timings.base_cs = 0; | ||
406 | |||
407 | if (mem_timings.m_type != M_DDR) | ||
408 | return; | ||
409 | |||
410 | /* With DDR we need to determine the low frequency DLL value */ | ||
411 | if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL)) | ||
412 | mem_timings.dll_mode = M_UNLOCK; | ||
413 | else | ||
414 | mem_timings.dll_mode = M_LOCK; | ||
415 | |||
416 | if (mem_timings.base_cs == 0) { | ||
417 | fast_dll = SDRC_DLLA_CTRL; | ||
418 | dll_cnt = SDRC_DLLA_STATUS & 0xff00; | ||
419 | } else { | ||
420 | fast_dll = SDRC_DLLB_CTRL; | ||
421 | dll_cnt = SDRC_DLLB_STATUS & 0xff00; | ||
422 | } | ||
423 | if (force_lock_to_unlock_mode) { | ||
424 | fast_dll &= ~0xff00; | ||
425 | fast_dll |= dll_cnt; /* Current lock mode */ | ||
426 | } | ||
427 | mem_timings.fast_dll_ctrl = fast_dll; | ||
428 | |||
429 | /* No disruptions, DDR will be offline & C-ABI not followed */ | ||
430 | omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl, | ||
431 | mem_timings.fast_dll_ctrl, | ||
432 | mem_timings.base_cs, | ||
433 | force_lock_to_unlock_mode); | ||
434 | mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */ | ||
435 | |||
436 | /* Turn status into unlock ctrl */ | ||
437 | mem_timings.slow_dll_ctrl |= | ||
438 | ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2)); | ||
439 | |||
440 | /* 90 degree phase for anything below 133Mhz */ | ||
441 | mem_timings.slow_dll_ctrl |= (1 << 1); | ||
442 | } | ||
443 | |||
444 | static u32 omap2_reprogram_sdrc(u32 level, u32 force) | ||
445 | { | ||
446 | u32 prev = curr_perf_level, flags; | ||
447 | |||
448 | if ((curr_perf_level == level) && !force) | ||
449 | return prev; | ||
450 | |||
451 | if (level == PRCM_HALF_SPEED) { | ||
452 | local_irq_save(flags); | ||
453 | PRCM_VOLTSETUP = 0xffff; | ||
454 | omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED, | ||
455 | mem_timings.slow_dll_ctrl, | ||
456 | mem_timings.m_type); | ||
457 | curr_perf_level = PRCM_HALF_SPEED; | ||
458 | local_irq_restore(flags); | ||
459 | } | ||
460 | if (level == PRCM_FULL_SPEED) { | ||
461 | local_irq_save(flags); | ||
462 | PRCM_VOLTSETUP = 0xffff; | ||
463 | omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED, | ||
464 | mem_timings.fast_dll_ctrl, | ||
465 | mem_timings.m_type); | ||
466 | curr_perf_level = PRCM_FULL_SPEED; | ||
467 | local_irq_restore(flags); | ||
468 | } | ||
469 | |||
470 | return prev; | ||
471 | } | ||
472 | |||
473 | static int omap2_reprogram_dpll(struct clk * clk, unsigned long rate) | ||
474 | { | ||
475 | u32 flags, cur_rate, low, mult, div, valid_rate, done_rate; | ||
476 | u32 bypass = 0; | ||
477 | struct prcm_config tmpset; | ||
478 | int ret = -EINVAL; | ||
479 | |||
480 | local_irq_save(flags); | ||
481 | cur_rate = omap2_get_dpll_rate(&dpll_ck); | ||
482 | mult = CM_CLKSEL2_PLL & 0x3; | ||
483 | |||
484 | if ((rate == (cur_rate / 2)) && (mult == 2)) { | ||
485 | omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1); | ||
486 | } else if ((rate == (cur_rate * 2)) && (mult == 1)) { | ||
487 | omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); | ||
488 | } else if (rate != cur_rate) { | ||
489 | valid_rate = omap2_dpll_round_rate(rate); | ||
490 | if (valid_rate != rate) | ||
491 | goto dpll_exit; | ||
492 | |||
493 | if ((CM_CLKSEL2_PLL & 0x3) == 1) | ||
494 | low = curr_prcm_set->dpll_speed; | ||
495 | else | ||
496 | low = curr_prcm_set->dpll_speed / 2; | ||
497 | |||
498 | tmpset.cm_clksel1_pll = CM_CLKSEL1_PLL; | ||
499 | tmpset.cm_clksel1_pll &= ~(0x3FFF << 8); | ||
500 | div = ((curr_prcm_set->xtal_speed / 1000000) - 1); | ||
501 | tmpset.cm_clksel2_pll = CM_CLKSEL2_PLL; | ||
502 | tmpset.cm_clksel2_pll &= ~0x3; | ||
503 | if (rate > low) { | ||
504 | tmpset.cm_clksel2_pll |= 0x2; | ||
505 | mult = ((rate / 2) / 1000000); | ||
506 | done_rate = PRCM_FULL_SPEED; | ||
507 | } else { | ||
508 | tmpset.cm_clksel2_pll |= 0x1; | ||
509 | mult = (rate / 1000000); | ||
510 | done_rate = PRCM_HALF_SPEED; | ||
511 | } | ||
512 | tmpset.cm_clksel1_pll |= ((div << 8) | (mult << 12)); | ||
513 | |||
514 | /* Worst case */ | ||
515 | tmpset.base_sdrc_rfr = V24XX_SDRC_RFR_CTRL_BYPASS; | ||
516 | |||
517 | if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */ | ||
518 | bypass = 1; | ||
519 | |||
520 | omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); /* For init_mem */ | ||
521 | |||
522 | /* Force dll lock mode */ | ||
523 | omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr, | ||
524 | bypass); | ||
525 | |||
526 | /* Errata: ret dll entry state */ | ||
527 | omap2_init_memory_params(omap2_dll_force_needed()); | ||
528 | omap2_reprogram_sdrc(done_rate, 0); | ||
529 | } | ||
530 | omap2_clksel_recalc(&dpll_ck); | ||
531 | ret = 0; | ||
532 | |||
533 | dpll_exit: | ||
534 | local_irq_restore(flags); | ||
535 | return(ret); | ||
536 | } | ||
537 | |||
538 | /* Just return the MPU speed */ | ||
539 | static void omap2_mpu_recalc(struct clk * clk) | ||
540 | { | ||
541 | clk->rate = curr_prcm_set->mpu_speed; | ||
542 | } | ||
543 | |||
544 | /* | ||
545 | * Look for a rate equal or less than the target rate given a configuration set. | ||
546 | * | ||
547 | * What's not entirely clear is "which" field represents the key field. | ||
548 | * Some might argue L3-DDR, others ARM, others IVA. This code is simple and | ||
549 | * just uses the ARM rates. | ||
550 | */ | ||
551 | static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate) | ||
552 | { | ||
553 | struct prcm_config * ptr; | ||
554 | long highest_rate; | ||
555 | |||
556 | if (clk != &virt_prcm_set) | ||
557 | return -EINVAL; | ||
558 | |||
559 | highest_rate = -EINVAL; | ||
560 | |||
561 | for (ptr = rate_table; ptr->mpu_speed; ptr++) { | ||
562 | if (ptr->xtal_speed != sys_ck.rate) | ||
563 | continue; | ||
564 | |||
565 | highest_rate = ptr->mpu_speed; | ||
566 | |||
567 | /* Can check only after xtal frequency check */ | ||
568 | if (ptr->mpu_speed <= rate) | ||
569 | break; | ||
570 | } | ||
571 | return highest_rate; | ||
572 | } | ||
573 | |||
574 | /* | ||
575 | * omap2_convert_field_to_div() - turn field value into integer divider | ||
576 | */ | ||
577 | static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val) | ||
578 | { | ||
579 | u32 i; | ||
580 | u32 clkout_array[] = {1, 2, 4, 8, 16}; | ||
581 | |||
582 | if ((div_sel & SRC_RATE_SEL_MASK) == CM_SYSCLKOUT_SEL1) { | ||
583 | for (i = 0; i < 5; i++) { | ||
584 | if (field_val == i) | ||
585 | return clkout_array[i]; | ||
586 | } | ||
587 | return ~0; | ||
588 | } else | ||
589 | return field_val; | ||
590 | } | ||
591 | |||
592 | /* | ||
593 | * Returns the CLKSEL divider register value | ||
594 | * REVISIT: This should be cleaned up to work nicely with void __iomem * | ||
595 | */ | ||
596 | static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask, | ||
597 | struct clk *clk) | ||
598 | { | ||
599 | int ret = ~0; | ||
600 | u32 reg_val, div_off; | ||
601 | u32 div_addr = 0; | ||
602 | u32 mask = ~0; | ||
603 | |||
604 | div_off = clk->rate_offset; | ||
605 | |||
606 | switch ((*div_sel & SRC_RATE_SEL_MASK)) { | ||
607 | case CM_MPU_SEL1: | ||
608 | div_addr = (u32)&CM_CLKSEL_MPU; | ||
609 | mask = 0x1f; | ||
610 | break; | ||
611 | case CM_DSP_SEL1: | ||
612 | div_addr = (u32)&CM_CLKSEL_DSP; | ||
613 | if (cpu_is_omap2420()) { | ||
614 | if ((div_off == 0) || (div_off == 8)) | ||
615 | mask = 0x1f; | ||
616 | else if (div_off == 5) | ||
617 | mask = 0x3; | ||
618 | } else if (cpu_is_omap2430()) { | ||
619 | if (div_off == 0) | ||
620 | mask = 0x1f; | ||
621 | else if (div_off == 5) | ||
622 | mask = 0x3; | ||
623 | } | ||
624 | break; | ||
625 | case CM_GFX_SEL1: | ||
626 | div_addr = (u32)&CM_CLKSEL_GFX; | ||
627 | if (div_off == 0) | ||
628 | mask = 0x7; | ||
629 | break; | ||
630 | case CM_MODEM_SEL1: | ||
631 | div_addr = (u32)&CM_CLKSEL_MDM; | ||
632 | if (div_off == 0) | ||
633 | mask = 0xf; | ||
634 | break; | ||
635 | case CM_SYSCLKOUT_SEL1: | ||
636 | div_addr = (u32)&PRCM_CLKOUT_CTRL; | ||
637 | if ((div_off == 3) || (div_off = 11)) | ||
638 | mask= 0x3; | ||
639 | break; | ||
640 | case CM_CORE_SEL1: | ||
641 | div_addr = (u32)&CM_CLKSEL1_CORE; | ||
642 | switch (div_off) { | ||
643 | case 0: /* l3 */ | ||
644 | case 8: /* dss1 */ | ||
645 | case 15: /* vylnc-2420 */ | ||
646 | case 20: /* ssi */ | ||
647 | mask = 0x1f; break; | ||
648 | case 5: /* l4 */ | ||
649 | mask = 0x3; break; | ||
650 | case 13: /* dss2 */ | ||
651 | mask = 0x1; break; | ||
652 | case 25: /* usb */ | ||
653 | mask = 0xf; break; | ||
654 | } | ||
655 | } | ||
656 | |||
657 | *field_mask = mask; | ||
658 | |||
659 | if (unlikely(mask == ~0)) | ||
660 | div_addr = 0; | ||
661 | |||
662 | *div_sel = div_addr; | ||
663 | |||
664 | if (unlikely(div_addr == 0)) | ||
665 | return ret; | ||
666 | |||
667 | /* Isolate field */ | ||
668 | reg_val = __raw_readl((void __iomem *)div_addr) & (mask << div_off); | ||
669 | |||
670 | /* Normalize back to divider value */ | ||
671 | reg_val >>= div_off; | ||
672 | |||
673 | return reg_val; | ||
674 | } | ||
675 | |||
676 | /* | ||
677 | * Return divider to be applied to parent clock. | ||
678 | * Return 0 on error. | ||
679 | */ | ||
680 | static u32 omap2_clksel_get_divisor(struct clk *clk) | ||
681 | { | ||
682 | int ret = 0; | ||
683 | u32 div, div_sel, div_off, field_mask, field_val; | ||
684 | |||
685 | /* isolate control register */ | ||
686 | div_sel = (SRC_RATE_SEL_MASK & clk->flags); | ||
687 | |||
688 | div_off = clk->rate_offset; | ||
689 | field_val = omap2_get_clksel(&div_sel, &field_mask, clk); | ||
690 | if (div_sel == 0) | ||
691 | return ret; | ||
692 | |||
693 | div_sel = (SRC_RATE_SEL_MASK & clk->flags); | ||
694 | div = omap2_clksel_to_divisor(div_sel, field_val); | ||
695 | |||
696 | return div; | ||
697 | } | ||
698 | |||
699 | /* Set the clock rate for a clock source */ | ||
700 | static int omap2_clk_set_rate(struct clk *clk, unsigned long rate) | ||
701 | |||
702 | { | ||
703 | int ret = -EINVAL; | ||
704 | void __iomem * reg; | ||
705 | u32 div_sel, div_off, field_mask, field_val, reg_val, validrate; | ||
706 | u32 new_div = 0; | ||
707 | |||
708 | if (!(clk->flags & CONFIG_PARTICIPANT) && (clk->flags & RATE_CKCTL)) { | ||
709 | if (clk == &dpll_ck) | ||
710 | return omap2_reprogram_dpll(clk, rate); | ||
711 | |||
712 | /* Isolate control register */ | ||
713 | div_sel = (SRC_RATE_SEL_MASK & clk->flags); | ||
714 | div_off = clk->src_offset; | ||
715 | |||
716 | validrate = omap2_clksel_round_rate(clk, rate, &new_div); | ||
717 | if(validrate != rate) | ||
718 | return(ret); | ||
719 | |||
720 | field_val = omap2_get_clksel(&div_sel, &field_mask, clk); | ||
721 | if (div_sel == 0) | ||
722 | return ret; | ||
723 | |||
724 | if(clk->flags & CM_SYSCLKOUT_SEL1){ | ||
725 | switch(new_div){ | ||
726 | case 16: field_val = 4; break; | ||
727 | case 8: field_val = 3; break; | ||
728 | case 4: field_val = 2; break; | ||
729 | case 2: field_val = 1; break; | ||
730 | case 1: field_val = 0; break; | ||
731 | } | ||
732 | } | ||
733 | else | ||
734 | field_val = new_div; | ||
735 | |||
736 | reg = (void __iomem *)div_sel; | ||
737 | |||
738 | reg_val = __raw_readl(reg); | ||
739 | reg_val &= ~(field_mask << div_off); | ||
740 | reg_val |= (field_val << div_off); | ||
741 | |||
742 | __raw_writel(reg_val, reg); | ||
743 | clk->rate = clk->parent->rate / field_val; | ||
744 | |||
745 | if (clk->flags & DELAYED_APP) | ||
746 | __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); | ||
747 | ret = 0; | ||
748 | } else if (clk->set_rate != 0) | ||
749 | ret = clk->set_rate(clk, rate); | ||
750 | |||
751 | if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) | ||
752 | propagate_rate(clk); | ||
753 | |||
754 | return ret; | ||
755 | } | ||
756 | |||
757 | /* Converts encoded control register address into a full address */ | ||
758 | static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset, | ||
759 | struct clk *src_clk, u32 *field_mask) | ||
760 | { | ||
761 | u32 val = ~0, src_reg_addr = 0, mask = 0; | ||
762 | |||
763 | /* Find target control register.*/ | ||
764 | switch ((*type_to_addr & SRC_RATE_SEL_MASK)) { | ||
765 | case CM_CORE_SEL1: | ||
766 | src_reg_addr = (u32)&CM_CLKSEL1_CORE; | ||
767 | if (reg_offset == 13) { /* DSS2_fclk */ | ||
768 | mask = 0x1; | ||
769 | if (src_clk == &sys_ck) | ||
770 | val = 0; | ||
771 | if (src_clk == &func_48m_ck) | ||
772 | val = 1; | ||
773 | } else if (reg_offset == 8) { /* DSS1_fclk */ | ||
774 | mask = 0x1f; | ||
775 | if (src_clk == &sys_ck) | ||
776 | val = 0; | ||
777 | else if (src_clk == &core_ck) /* divided clock */ | ||
778 | val = 0x10; /* rate needs fixing */ | ||
779 | } else if ((reg_offset == 15) && cpu_is_omap2420()){ /*vlnyq*/ | ||
780 | mask = 0x1F; | ||
781 | if(src_clk == &func_96m_ck) | ||
782 | val = 0; | ||
783 | else if (src_clk == &core_ck) | ||
784 | val = 0x10; | ||
785 | } | ||
786 | break; | ||
787 | case CM_CORE_SEL2: | ||
788 | src_reg_addr = (u32)&CM_CLKSEL2_CORE; | ||
789 | mask = 0x3; | ||
790 | if (src_clk == &func_32k_ck) | ||
791 | val = 0x0; | ||
792 | if (src_clk == &sys_ck) | ||
793 | val = 0x1; | ||
794 | if (src_clk == &alt_ck) | ||
795 | val = 0x2; | ||
796 | break; | ||
797 | case CM_WKUP_SEL1: | ||
798 | src_reg_addr = (u32)&CM_CLKSEL2_CORE; | ||
799 | mask = 0x3; | ||
800 | if (src_clk == &func_32k_ck) | ||
801 | val = 0x0; | ||
802 | if (src_clk == &sys_ck) | ||
803 | val = 0x1; | ||
804 | if (src_clk == &alt_ck) | ||
805 | val = 0x2; | ||
806 | break; | ||
807 | case CM_PLL_SEL1: | ||
808 | src_reg_addr = (u32)&CM_CLKSEL1_PLL; | ||
809 | mask = 0x1; | ||
810 | if (reg_offset == 0x3) { | ||
811 | if (src_clk == &apll96_ck) | ||
812 | val = 0; | ||
813 | if (src_clk == &alt_ck) | ||
814 | val = 1; | ||
815 | } | ||
816 | else if (reg_offset == 0x5) { | ||
817 | if (src_clk == &apll54_ck) | ||
818 | val = 0; | ||
819 | if (src_clk == &alt_ck) | ||
820 | val = 1; | ||
821 | } | ||
822 | break; | ||
823 | case CM_PLL_SEL2: | ||
824 | src_reg_addr = (u32)&CM_CLKSEL2_PLL; | ||
825 | mask = 0x3; | ||
826 | if (src_clk == &func_32k_ck) | ||
827 | val = 0x0; | ||
828 | if (src_clk == &dpll_ck) | ||
829 | val = 0x2; | ||
830 | break; | ||
831 | case CM_SYSCLKOUT_SEL1: | ||
832 | src_reg_addr = (u32)&PRCM_CLKOUT_CTRL; | ||
833 | mask = 0x3; | ||
834 | if (src_clk == &dpll_ck) | ||
835 | val = 0; | ||
836 | if (src_clk == &sys_ck) | ||
837 | val = 1; | ||
838 | if (src_clk == &func_54m_ck) | ||
839 | val = 2; | ||
840 | if (src_clk == &func_96m_ck) | ||
841 | val = 3; | ||
842 | break; | ||
843 | } | ||
844 | |||
845 | if (val == ~0) /* Catch errors in offset */ | ||
846 | *type_to_addr = 0; | ||
847 | else | ||
848 | *type_to_addr = src_reg_addr; | ||
849 | *field_mask = mask; | ||
850 | |||
851 | return val; | ||
852 | } | ||
853 | |||
854 | static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) | ||
855 | { | ||
856 | void __iomem * reg; | ||
857 | u32 src_sel, src_off, field_val, field_mask, reg_val, rate; | ||
858 | int ret = -EINVAL; | ||
859 | |||
860 | if (unlikely(clk->flags & CONFIG_PARTICIPANT)) | ||
861 | return ret; | ||
862 | |||
863 | if (clk->flags & SRC_SEL_MASK) { /* On-chip SEL collection */ | ||
864 | src_sel = (SRC_RATE_SEL_MASK & clk->flags); | ||
865 | src_off = clk->src_offset; | ||
866 | |||
867 | if (src_sel == 0) | ||
868 | goto set_parent_error; | ||
869 | |||
870 | field_val = omap2_get_src_field(&src_sel, src_off, new_parent, | ||
871 | &field_mask); | ||
872 | |||
873 | reg = (void __iomem *)src_sel; | ||
874 | |||
875 | if (clk->usecount > 0) | ||
876 | omap2_clk_disable(clk); | ||
877 | |||
878 | /* Set new source value (previous dividers if any in effect) */ | ||
879 | reg_val = __raw_readl(reg) & ~(field_mask << src_off); | ||
880 | reg_val |= (field_val << src_off); | ||
881 | __raw_writel(reg_val, reg); | ||
882 | |||
883 | if (clk->flags & DELAYED_APP) | ||
884 | __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); | ||
885 | |||
886 | if (clk->usecount > 0) | ||
887 | omap2_clk_enable(clk); | ||
888 | |||
889 | clk->parent = new_parent; | ||
890 | |||
891 | /* SRC_RATE_SEL_MASK clocks follow their parents rates.*/ | ||
892 | if ((new_parent == &core_ck) && (clk == &dss1_fck)) | ||
893 | clk->rate = new_parent->rate / 0x10; | ||
894 | else | ||
895 | clk->rate = new_parent->rate; | ||
896 | |||
897 | if (unlikely(clk->flags & RATE_PROPAGATES)) | ||
898 | propagate_rate(clk); | ||
899 | |||
900 | return 0; | ||
901 | } else { | ||
902 | clk->parent = new_parent; | ||
903 | rate = new_parent->rate; | ||
904 | omap2_clk_set_rate(clk, rate); | ||
905 | ret = 0; | ||
906 | } | ||
907 | |||
908 | set_parent_error: | ||
909 | return ret; | ||
910 | } | ||
911 | |||
912 | /* Sets basic clocks based on the specified rate */ | ||
913 | static int omap2_select_table_rate(struct clk * clk, unsigned long rate) | ||
914 | { | ||
915 | u32 flags, cur_rate, done_rate, bypass = 0; | ||
916 | u8 cpu_mask = 0; | ||
917 | struct prcm_config *prcm; | ||
918 | unsigned long found_speed = 0; | ||
919 | |||
920 | if (clk != &virt_prcm_set) | ||
921 | return -EINVAL; | ||
922 | |||
923 | /* FIXME: Change cpu_is_omap2420() to cpu_is_omap242x() */ | ||
924 | if (cpu_is_omap2420()) | ||
925 | cpu_mask = RATE_IN_242X; | ||
926 | else if (cpu_is_omap2430()) | ||
927 | cpu_mask = RATE_IN_243X; | ||
928 | |||
929 | for (prcm = rate_table; prcm->mpu_speed; prcm++) { | ||
930 | if (!(prcm->flags & cpu_mask)) | ||
931 | continue; | ||
932 | |||
933 | if (prcm->xtal_speed != sys_ck.rate) | ||
934 | continue; | ||
935 | |||
936 | if (prcm->mpu_speed <= rate) { | ||
937 | found_speed = prcm->mpu_speed; | ||
938 | break; | ||
939 | } | ||
940 | } | ||
941 | |||
942 | if (!found_speed) { | ||
943 | printk(KERN_INFO "Could not set MPU rate to %luMHz\n", | ||
944 | rate / 1000000); | ||
945 | return -EINVAL; | ||
946 | } | ||
947 | |||
948 | curr_prcm_set = prcm; | ||
949 | cur_rate = omap2_get_dpll_rate(&dpll_ck); | ||
950 | |||
951 | if (prcm->dpll_speed == cur_rate / 2) { | ||
952 | omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1); | ||
953 | } else if (prcm->dpll_speed == cur_rate * 2) { | ||
954 | omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); | ||
955 | } else if (prcm->dpll_speed != cur_rate) { | ||
956 | local_irq_save(flags); | ||
957 | |||
958 | if (prcm->dpll_speed == prcm->xtal_speed) | ||
959 | bypass = 1; | ||
960 | |||
961 | if ((prcm->cm_clksel2_pll & 0x3) == 2) | ||
962 | done_rate = PRCM_FULL_SPEED; | ||
963 | else | ||
964 | done_rate = PRCM_HALF_SPEED; | ||
965 | |||
966 | /* MPU divider */ | ||
967 | CM_CLKSEL_MPU = prcm->cm_clksel_mpu; | ||
968 | |||
969 | /* dsp + iva1 div(2420), iva2.1(2430) */ | ||
970 | CM_CLKSEL_DSP = prcm->cm_clksel_dsp; | ||
971 | |||
972 | CM_CLKSEL_GFX = prcm->cm_clksel_gfx; | ||
973 | |||
974 | /* Major subsystem dividers */ | ||
975 | CM_CLKSEL1_CORE = prcm->cm_clksel1_core; | ||
976 | if (cpu_is_omap2430()) | ||
977 | CM_CLKSEL_MDM = prcm->cm_clksel_mdm; | ||
978 | |||
979 | /* x2 to enter init_mem */ | ||
980 | omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); | ||
981 | |||
982 | omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr, | ||
983 | bypass); | ||
984 | |||
985 | omap2_init_memory_params(omap2_dll_force_needed()); | ||
986 | omap2_reprogram_sdrc(done_rate, 0); | ||
987 | |||
988 | local_irq_restore(flags); | ||
989 | } | ||
990 | omap2_clksel_recalc(&dpll_ck); | ||
991 | |||
992 | return 0; | ||
993 | } | ||
994 | |||
995 | /*------------------------------------------------------------------------- | ||
996 | * Omap2 clock reset and init functions | ||
997 | *-------------------------------------------------------------------------*/ | ||
998 | |||
999 | static struct clk_functions omap2_clk_functions = { | ||
1000 | .clk_enable = omap2_clk_enable, | ||
1001 | .clk_disable = omap2_clk_disable, | ||
1002 | .clk_use = omap2_clk_use, | ||
1003 | .clk_unuse = omap2_clk_unuse, | ||
1004 | .clk_round_rate = omap2_clk_round_rate, | ||
1005 | .clk_set_rate = omap2_clk_set_rate, | ||
1006 | .clk_set_parent = omap2_clk_set_parent, | ||
1007 | }; | ||
1008 | |||
1009 | static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) | ||
1010 | { | ||
1011 | u32 div, aplls, sclk = 13000000; | ||
1012 | |||
1013 | aplls = CM_CLKSEL1_PLL; | ||
1014 | aplls &= ((1 << 23) | (1 << 24) | (1 << 25)); | ||
1015 | aplls >>= 23; /* Isolate field, 0,2,3 */ | ||
1016 | |||
1017 | if (aplls == 0) | ||
1018 | sclk = 19200000; | ||
1019 | else if (aplls == 2) | ||
1020 | sclk = 13000000; | ||
1021 | else if (aplls == 3) | ||
1022 | sclk = 12000000; | ||
1023 | |||
1024 | div = PRCM_CLKSRC_CTRL; | ||
1025 | div &= ((1 << 7) | (1 << 6)); | ||
1026 | div >>= sys->rate_offset; | ||
1027 | |||
1028 | osc->rate = sclk * div; | ||
1029 | sys->rate = sclk; | ||
1030 | } | ||
1031 | |||
1032 | #ifdef CONFIG_OMAP_RESET_CLOCKS | ||
1033 | static void __init omap2_disable_unused_clocks(void) | ||
1034 | { | ||
1035 | struct clk *ck; | ||
1036 | u32 regval32; | ||
1037 | |||
1038 | list_for_each_entry(ck, &clocks, node) { | ||
1039 | if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || | ||
1040 | ck->enable_reg == 0) | ||
1041 | continue; | ||
1042 | |||
1043 | regval32 = __raw_readl(ck->enable_reg); | ||
1044 | if ((regval32 & (1 << ck->enable_bit)) == 0) | ||
1045 | continue; | ||
1046 | |||
1047 | printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); | ||
1048 | omap2_clk_disable(ck); | ||
1049 | } | ||
1050 | } | ||
1051 | late_initcall(omap2_disable_unused_clocks); | ||
1052 | #endif | ||
1053 | |||
1054 | /* | ||
1055 | * Switch the MPU rate if specified on cmdline. | ||
1056 | * We cannot do this early until cmdline is parsed. | ||
1057 | */ | ||
1058 | static int __init omap2_clk_arch_init(void) | ||
1059 | { | ||
1060 | if (!mpurate) | ||
1061 | return -EINVAL; | ||
1062 | |||
1063 | if (omap2_select_table_rate(&virt_prcm_set, mpurate)) | ||
1064 | printk(KERN_ERR "Could not find matching MPU rate\n"); | ||
1065 | |||
1066 | propagate_rate(&osc_ck); /* update main root fast */ | ||
1067 | propagate_rate(&func_32k_ck); /* update main root slow */ | ||
1068 | |||
1069 | printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): " | ||
1070 | "%ld.%01ld/%ld/%ld MHz\n", | ||
1071 | (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10, | ||
1072 | (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ; | ||
1073 | |||
1074 | return 0; | ||
1075 | } | ||
1076 | arch_initcall(omap2_clk_arch_init); | ||
1077 | |||
1078 | int __init omap2_clk_init(void) | ||
1079 | { | ||
1080 | struct prcm_config *prcm; | ||
1081 | struct clk ** clkp; | ||
1082 | u32 clkrate; | ||
1083 | |||
1084 | clk_init(&omap2_clk_functions); | ||
1085 | omap2_get_crystal_rate(&osc_ck, &sys_ck); | ||
1086 | |||
1087 | for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks); | ||
1088 | clkp++) { | ||
1089 | |||
1090 | if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) { | ||
1091 | clk_register(*clkp); | ||
1092 | continue; | ||
1093 | } | ||
1094 | |||
1095 | if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) { | ||
1096 | clk_register(*clkp); | ||
1097 | continue; | ||
1098 | } | ||
1099 | } | ||
1100 | |||
1101 | /* Check the MPU rate set by bootloader */ | ||
1102 | clkrate = omap2_get_dpll_rate(&dpll_ck); | ||
1103 | for (prcm = rate_table; prcm->mpu_speed; prcm++) { | ||
1104 | if (prcm->xtal_speed != sys_ck.rate) | ||
1105 | continue; | ||
1106 | if (prcm->dpll_speed <= clkrate) | ||
1107 | break; | ||
1108 | } | ||
1109 | curr_prcm_set = prcm; | ||
1110 | |||
1111 | propagate_rate(&osc_ck); /* update main root fast */ | ||
1112 | propagate_rate(&func_32k_ck); /* update main root slow */ | ||
1113 | |||
1114 | printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): " | ||
1115 | "%ld.%01ld/%ld/%ld MHz\n", | ||
1116 | (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10, | ||
1117 | (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ; | ||
1118 | |||
1119 | /* | ||
1120 | * Only enable those clocks we will need, let the drivers | ||
1121 | * enable other clocks as necessary | ||
1122 | */ | ||
1123 | clk_use(&sync_32k_ick); | ||
1124 | clk_use(&omapctrl_ick); | ||
1125 | if (cpu_is_omap2430()) | ||
1126 | clk_use(&sdrc_ick); | ||
1127 | |||
1128 | return 0; | ||
1129 | } | ||
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h new file mode 100644 index 000000000000..4aeab5591bd3 --- /dev/null +++ b/arch/arm/mach-omap2/clock.h | |||
@@ -0,0 +1,2103 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap24xx/clock.h | ||
3 | * | ||
4 | * Copyright (C) 2005 Texas Instruments Inc. | ||
5 | * Richard Woodruff <r-woodruff2@ti.com> | ||
6 | * Created for OMAP2. | ||
7 | * | ||
8 | * Copyright (C) 2004 Nokia corporation | ||
9 | * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> | ||
10 | * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H | ||
18 | #define __ARCH_ARM_MACH_OMAP2_CLOCK_H | ||
19 | |||
20 | static void omap2_sys_clk_recalc(struct clk * clk); | ||
21 | static void omap2_clksel_recalc(struct clk * clk); | ||
22 | static void omap2_followparent_recalc(struct clk * clk); | ||
23 | static void omap2_propagate_rate(struct clk * clk); | ||
24 | static void omap2_mpu_recalc(struct clk * clk); | ||
25 | static int omap2_select_table_rate(struct clk * clk, unsigned long rate); | ||
26 | static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate); | ||
27 | static void omap2_clk_unuse(struct clk *clk); | ||
28 | static void omap2_sys_clk_recalc(struct clk * clk); | ||
29 | static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val); | ||
30 | static u32 omap2_clksel_get_divisor(struct clk *clk); | ||
31 | |||
32 | |||
33 | #define RATE_IN_242X (1 << 0) | ||
34 | #define RATE_IN_243X (1 << 1) | ||
35 | |||
36 | /* Memory timings */ | ||
37 | #define M_DDR 1 | ||
38 | #define M_LOCK_CTRL (1 << 2) | ||
39 | #define M_UNLOCK 0 | ||
40 | #define M_LOCK 1 | ||
41 | |||
42 | struct memory_timings { | ||
43 | u32 m_type; /* ddr = 1, sdr = 0 */ | ||
44 | u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */ | ||
45 | u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */ | ||
46 | u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */ | ||
47 | u32 base_cs; /* base chip select to use for calculations */ | ||
48 | }; | ||
49 | |||
50 | /* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. | ||
51 | * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP | ||
52 | * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM | ||
53 | */ | ||
54 | struct prcm_config { | ||
55 | unsigned long xtal_speed; /* crystal rate */ | ||
56 | unsigned long dpll_speed; /* dpll: out*xtal*M/(N-1)table_recalc */ | ||
57 | unsigned long mpu_speed; /* speed of MPU */ | ||
58 | unsigned long cm_clksel_mpu; /* mpu divider */ | ||
59 | unsigned long cm_clksel_dsp; /* dsp+iva1 div(2420), iva2.1(2430) */ | ||
60 | unsigned long cm_clksel_gfx; /* gfx dividers */ | ||
61 | unsigned long cm_clksel1_core; /* major subsystem dividers */ | ||
62 | unsigned long cm_clksel1_pll; /* m,n */ | ||
63 | unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */ | ||
64 | unsigned long cm_clksel_mdm; /* modem dividers 2430 only */ | ||
65 | unsigned long base_sdrc_rfr; /* base refresh timing for a set */ | ||
66 | unsigned char flags; | ||
67 | }; | ||
68 | |||
69 | /* Mask for clksel which support parent settign in set_rate */ | ||
70 | #define SRC_SEL_MASK (CM_CORE_SEL1 | CM_CORE_SEL2 | CM_WKUP_SEL1 | \ | ||
71 | CM_PLL_SEL1 | CM_PLL_SEL2 | CM_SYSCLKOUT_SEL1) | ||
72 | |||
73 | /* Mask for clksel regs which support rate operations */ | ||
74 | #define SRC_RATE_SEL_MASK (CM_MPU_SEL1 | CM_DSP_SEL1 | CM_GFX_SEL1 | \ | ||
75 | CM_MODEM_SEL1 | CM_CORE_SEL1 | CM_CORE_SEL2 | \ | ||
76 | CM_WKUP_SEL1 | CM_PLL_SEL1 | CM_PLL_SEL2 | \ | ||
77 | CM_SYSCLKOUT_SEL1) | ||
78 | |||
79 | /* | ||
80 | * The OMAP2 processor can be run at several discrete 'PRCM configurations'. | ||
81 | * These configurations are characterized by voltage and speed for clocks. | ||
82 | * The device is only validated for certain combinations. One way to express | ||
83 | * these combinations is via the 'ratio's' which the clocks operate with | ||
84 | * respect to each other. These ratio sets are for a given voltage/DPLL | ||
85 | * setting. All configurations can be described by a DPLL setting and a ratio | ||
86 | * There are 3 ratio sets for the 2430 and X ratio sets for 2420. | ||
87 | * | ||
88 | * 2430 differs from 2420 in that there are no more phase synchronizers used. | ||
89 | * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs | ||
90 | * 2430 (iva2.1, NOdsp, mdm) | ||
91 | */ | ||
92 | |||
93 | /* Core fields for cm_clksel, not ratio governed */ | ||
94 | #define RX_CLKSEL_DSS1 (0x10 << 8) | ||
95 | #define RX_CLKSEL_DSS2 (0x0 << 13) | ||
96 | #define RX_CLKSEL_SSI (0x5 << 20) | ||
97 | |||
98 | /*------------------------------------------------------------------------- | ||
99 | * Voltage/DPLL ratios | ||
100 | *-------------------------------------------------------------------------*/ | ||
101 | |||
102 | /* 2430 Ratio's, 2430-Ratio Config 1 */ | ||
103 | #define R1_CLKSEL_L3 (4 << 0) | ||
104 | #define R1_CLKSEL_L4 (2 << 5) | ||
105 | #define R1_CLKSEL_USB (4 << 25) | ||
106 | #define R1_CM_CLKSEL1_CORE_VAL R1_CLKSEL_USB | RX_CLKSEL_SSI | \ | ||
107 | RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ | ||
108 | R1_CLKSEL_L4 | R1_CLKSEL_L3 | ||
109 | #define R1_CLKSEL_MPU (2 << 0) | ||
110 | #define R1_CM_CLKSEL_MPU_VAL R1_CLKSEL_MPU | ||
111 | #define R1_CLKSEL_DSP (2 << 0) | ||
112 | #define R1_CLKSEL_DSP_IF (2 << 5) | ||
113 | #define R1_CM_CLKSEL_DSP_VAL R1_CLKSEL_DSP | R1_CLKSEL_DSP_IF | ||
114 | #define R1_CLKSEL_GFX (2 << 0) | ||
115 | #define R1_CM_CLKSEL_GFX_VAL R1_CLKSEL_GFX | ||
116 | #define R1_CLKSEL_MDM (4 << 0) | ||
117 | #define R1_CM_CLKSEL_MDM_VAL R1_CLKSEL_MDM | ||
118 | |||
119 | /* 2430-Ratio Config 2 */ | ||
120 | #define R2_CLKSEL_L3 (6 << 0) | ||
121 | #define R2_CLKSEL_L4 (2 << 5) | ||
122 | #define R2_CLKSEL_USB (2 << 25) | ||
123 | #define R2_CM_CLKSEL1_CORE_VAL R2_CLKSEL_USB | RX_CLKSEL_SSI | \ | ||
124 | RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ | ||
125 | R2_CLKSEL_L4 | R2_CLKSEL_L3 | ||
126 | #define R2_CLKSEL_MPU (2 << 0) | ||
127 | #define R2_CM_CLKSEL_MPU_VAL R2_CLKSEL_MPU | ||
128 | #define R2_CLKSEL_DSP (2 << 0) | ||
129 | #define R2_CLKSEL_DSP_IF (3 << 5) | ||
130 | #define R2_CM_CLKSEL_DSP_VAL R2_CLKSEL_DSP | R2_CLKSEL_DSP_IF | ||
131 | #define R2_CLKSEL_GFX (2 << 0) | ||
132 | #define R2_CM_CLKSEL_GFX_VAL R2_CLKSEL_GFX | ||
133 | #define R2_CLKSEL_MDM (6 << 0) | ||
134 | #define R2_CM_CLKSEL_MDM_VAL R2_CLKSEL_MDM | ||
135 | |||
136 | /* 2430-Ratio Bootm (BYPASS) */ | ||
137 | #define RB_CLKSEL_L3 (1 << 0) | ||
138 | #define RB_CLKSEL_L4 (1 << 5) | ||
139 | #define RB_CLKSEL_USB (1 << 25) | ||
140 | #define RB_CM_CLKSEL1_CORE_VAL RB_CLKSEL_USB | RX_CLKSEL_SSI | \ | ||
141 | RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ | ||
142 | RB_CLKSEL_L4 | RB_CLKSEL_L3 | ||
143 | #define RB_CLKSEL_MPU (1 << 0) | ||
144 | #define RB_CM_CLKSEL_MPU_VAL RB_CLKSEL_MPU | ||
145 | #define RB_CLKSEL_DSP (1 << 0) | ||
146 | #define RB_CLKSEL_DSP_IF (1 << 5) | ||
147 | #define RB_CM_CLKSEL_DSP_VAL RB_CLKSEL_DSP | RB_CLKSEL_DSP_IF | ||
148 | #define RB_CLKSEL_GFX (1 << 0) | ||
149 | #define RB_CM_CLKSEL_GFX_VAL RB_CLKSEL_GFX | ||
150 | #define RB_CLKSEL_MDM (1 << 0) | ||
151 | #define RB_CM_CLKSEL_MDM_VAL RB_CLKSEL_MDM | ||
152 | |||
153 | /* 2420 Ratio Equivalents */ | ||
154 | #define RXX_CLKSEL_VLYNQ (0x12 << 15) | ||
155 | #define RXX_CLKSEL_SSI (0x8 << 20) | ||
156 | |||
157 | /* 2420-PRCM III 532MHz core */ | ||
158 | #define RIII_CLKSEL_L3 (4 << 0) /* 133MHz */ | ||
159 | #define RIII_CLKSEL_L4 (2 << 5) /* 66.5MHz */ | ||
160 | #define RIII_CLKSEL_USB (4 << 25) /* 33.25MHz */ | ||
161 | #define RIII_CM_CLKSEL1_CORE_VAL RIII_CLKSEL_USB | RXX_CLKSEL_SSI | \ | ||
162 | RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \ | ||
163 | RX_CLKSEL_DSS1 | RIII_CLKSEL_L4 | \ | ||
164 | RIII_CLKSEL_L3 | ||
165 | #define RIII_CLKSEL_MPU (2 << 0) /* 266MHz */ | ||
166 | #define RIII_CM_CLKSEL_MPU_VAL RIII_CLKSEL_MPU | ||
167 | #define RIII_CLKSEL_DSP (3 << 0) /* c5x - 177.3MHz */ | ||
168 | #define RIII_CLKSEL_DSP_IF (2 << 5) /* c5x - 88.67MHz */ | ||
169 | #define RIII_SYNC_DSP (1 << 7) /* Enable sync */ | ||
170 | #define RIII_CLKSEL_IVA (6 << 8) /* iva1 - 88.67MHz */ | ||
171 | #define RIII_SYNC_IVA (1 << 13) /* Enable sync */ | ||
172 | #define RIII_CM_CLKSEL_DSP_VAL RIII_SYNC_IVA | RIII_CLKSEL_IVA | \ | ||
173 | RIII_SYNC_DSP | RIII_CLKSEL_DSP_IF | \ | ||
174 | RIII_CLKSEL_DSP | ||
175 | #define RIII_CLKSEL_GFX (2 << 0) /* 66.5MHz */ | ||
176 | #define RIII_CM_CLKSEL_GFX_VAL RIII_CLKSEL_GFX | ||
177 | |||
178 | /* 2420-PRCM II 600MHz core */ | ||
179 | #define RII_CLKSEL_L3 (6 << 0) /* 100MHz */ | ||
180 | #define RII_CLKSEL_L4 (2 << 5) /* 50MHz */ | ||
181 | #define RII_CLKSEL_USB (2 << 25) /* 50MHz */ | ||
182 | #define RII_CM_CLKSEL1_CORE_VAL RII_CLKSEL_USB | \ | ||
183 | RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \ | ||
184 | RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \ | ||
185 | RII_CLKSEL_L4 | RII_CLKSEL_L3 | ||
186 | #define RII_CLKSEL_MPU (2 << 0) /* 300MHz */ | ||
187 | #define RII_CM_CLKSEL_MPU_VAL RII_CLKSEL_MPU | ||
188 | #define RII_CLKSEL_DSP (3 << 0) /* c5x - 200MHz */ | ||
189 | #define RII_CLKSEL_DSP_IF (2 << 5) /* c5x - 100MHz */ | ||
190 | #define RII_SYNC_DSP (0 << 7) /* Bypass sync */ | ||
191 | #define RII_CLKSEL_IVA (6 << 8) /* iva1 - 200MHz */ | ||
192 | #define RII_SYNC_IVA (0 << 13) /* Bypass sync */ | ||
193 | #define RII_CM_CLKSEL_DSP_VAL RII_SYNC_IVA | RII_CLKSEL_IVA | \ | ||
194 | RII_SYNC_DSP | RII_CLKSEL_DSP_IF | \ | ||
195 | RII_CLKSEL_DSP | ||
196 | #define RII_CLKSEL_GFX (2 << 0) /* 50MHz */ | ||
197 | #define RII_CM_CLKSEL_GFX_VAL RII_CLKSEL_GFX | ||
198 | |||
199 | /* 2420-PRCM VII (boot) */ | ||
200 | #define RVII_CLKSEL_L3 (1 << 0) | ||
201 | #define RVII_CLKSEL_L4 (1 << 5) | ||
202 | #define RVII_CLKSEL_DSS1 (1 << 8) | ||
203 | #define RVII_CLKSEL_DSS2 (0 << 13) | ||
204 | #define RVII_CLKSEL_VLYNQ (1 << 15) | ||
205 | #define RVII_CLKSEL_SSI (1 << 20) | ||
206 | #define RVII_CLKSEL_USB (1 << 25) | ||
207 | |||
208 | #define RVII_CM_CLKSEL1_CORE_VAL RVII_CLKSEL_USB | RVII_CLKSEL_SSI | \ | ||
209 | RVII_CLKSEL_VLYNQ | RVII_CLKSEL_DSS2 | \ | ||
210 | RVII_CLKSEL_DSS1 | RVII_CLKSEL_L4 | RVII_CLKSEL_L3 | ||
211 | |||
212 | #define RVII_CLKSEL_MPU (1 << 0) /* all divide by 1 */ | ||
213 | #define RVII_CM_CLKSEL_MPU_VAL RVII_CLKSEL_MPU | ||
214 | |||
215 | #define RVII_CLKSEL_DSP (1 << 0) | ||
216 | #define RVII_CLKSEL_DSP_IF (1 << 5) | ||
217 | #define RVII_SYNC_DSP (0 << 7) | ||
218 | #define RVII_CLKSEL_IVA (1 << 8) | ||
219 | #define RVII_SYNC_IVA (0 << 13) | ||
220 | #define RVII_CM_CLKSEL_DSP_VAL RVII_SYNC_IVA | RVII_CLKSEL_IVA | RVII_SYNC_DSP | \ | ||
221 | RVII_CLKSEL_DSP_IF | RVII_CLKSEL_DSP | ||
222 | |||
223 | #define RVII_CLKSEL_GFX (1 << 0) | ||
224 | #define RVII_CM_CLKSEL_GFX_VAL RVII_CLKSEL_GFX | ||
225 | |||
226 | /*------------------------------------------------------------------------- | ||
227 | * 2430 Target modes: Along with each configuration the CPU has several | ||
228 | * modes which goes along with them. Modes mainly are the addition of | ||
229 | * describe DPLL combinations to go along with a ratio. | ||
230 | *-------------------------------------------------------------------------*/ | ||
231 | |||
232 | /* Hardware governed */ | ||
233 | #define MX_48M_SRC (0 << 3) | ||
234 | #define MX_54M_SRC (0 << 5) | ||
235 | #define MX_APLLS_CLIKIN_12 (3 << 23) | ||
236 | #define MX_APLLS_CLIKIN_13 (2 << 23) | ||
237 | #define MX_APLLS_CLIKIN_19_2 (0 << 23) | ||
238 | |||
239 | /* | ||
240 | * 2430 - standalone, 2*ref*M/(n+1), M/N is for exactness not relock speed | ||
241 | * #2 (ratio1) baseport-target | ||
242 | * #5a (ratio1) baseport-target, target DPLL = 266*2 = 532MHz | ||
243 | */ | ||
244 | #define M5A_DPLL_MULT_12 (133 << 12) | ||
245 | #define M5A_DPLL_DIV_12 (5 << 8) | ||
246 | #define M5A_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
247 | M5A_DPLL_DIV_12 | M5A_DPLL_MULT_12 | \ | ||
248 | MX_APLLS_CLIKIN_12 | ||
249 | #define M5A_DPLL_MULT_13 (266 << 12) | ||
250 | #define M5A_DPLL_DIV_13 (12 << 8) | ||
251 | #define M5A_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
252 | M5A_DPLL_DIV_13 | M5A_DPLL_MULT_13 | \ | ||
253 | MX_APLLS_CLIKIN_13 | ||
254 | #define M5A_DPLL_MULT_19 (180 << 12) | ||
255 | #define M5A_DPLL_DIV_19 (12 << 8) | ||
256 | #define M5A_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
257 | M5A_DPLL_DIV_19 | M5A_DPLL_MULT_19 | \ | ||
258 | MX_APLLS_CLIKIN_19_2 | ||
259 | /* #5b (ratio1) target DPLL = 200*2 = 400MHz */ | ||
260 | #define M5B_DPLL_MULT_12 (50 << 12) | ||
261 | #define M5B_DPLL_DIV_12 (2 << 8) | ||
262 | #define M5B_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
263 | M5B_DPLL_DIV_12 | M5B_DPLL_MULT_12 | \ | ||
264 | MX_APLLS_CLIKIN_12 | ||
265 | #define M5B_DPLL_MULT_13 (200 << 12) | ||
266 | #define M5B_DPLL_DIV_13 (12 << 8) | ||
267 | |||
268 | #define M5B_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
269 | M5B_DPLL_DIV_13 | M5B_DPLL_MULT_13 | \ | ||
270 | MX_APLLS_CLIKIN_13 | ||
271 | #define M5B_DPLL_MULT_19 (125 << 12) | ||
272 | #define M5B_DPLL_DIV_19 (31 << 8) | ||
273 | #define M5B_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
274 | M5B_DPLL_DIV_19 | M5B_DPLL_MULT_19 | \ | ||
275 | MX_APLLS_CLIKIN_19_2 | ||
276 | /* | ||
277 | * #4 (ratio2) | ||
278 | * #3 (ratio2) baseport-target, target DPLL = 330*2 = 660MHz | ||
279 | */ | ||
280 | #define M3_DPLL_MULT_12 (55 << 12) | ||
281 | #define M3_DPLL_DIV_12 (1 << 8) | ||
282 | #define M3_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
283 | M3_DPLL_DIV_12 | M3_DPLL_MULT_12 | \ | ||
284 | MX_APLLS_CLIKIN_12 | ||
285 | #define M3_DPLL_MULT_13 (330 << 12) | ||
286 | #define M3_DPLL_DIV_13 (12 << 8) | ||
287 | #define M3_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
288 | M3_DPLL_DIV_13 | M3_DPLL_MULT_13 | \ | ||
289 | MX_APLLS_CLIKIN_13 | ||
290 | #define M3_DPLL_MULT_19 (275 << 12) | ||
291 | #define M3_DPLL_DIV_19 (15 << 8) | ||
292 | #define M3_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
293 | M3_DPLL_DIV_19 | M3_DPLL_MULT_19 | \ | ||
294 | MX_APLLS_CLIKIN_19_2 | ||
295 | /* boot (boot) */ | ||
296 | #define MB_DPLL_MULT (1 << 12) | ||
297 | #define MB_DPLL_DIV (0 << 8) | ||
298 | #define MB_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\ | ||
299 | MB_DPLL_MULT | MX_APLLS_CLIKIN_12 | ||
300 | |||
301 | #define MB_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\ | ||
302 | MB_DPLL_MULT | MX_APLLS_CLIKIN_13 | ||
303 | |||
304 | #define MB_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\ | ||
305 | MB_DPLL_MULT | MX_APLLS_CLIKIN_19 | ||
306 | |||
307 | /* | ||
308 | * 2430 - chassis (sedna) | ||
309 | * 165 (ratio1) same as above #2 | ||
310 | * 150 (ratio1) | ||
311 | * 133 (ratio2) same as above #4 | ||
312 | * 110 (ratio2) same as above #3 | ||
313 | * 104 (ratio2) | ||
314 | * boot (boot) | ||
315 | */ | ||
316 | |||
317 | /* | ||
318 | * 2420 Equivalent - mode registers | ||
319 | * PRCM II , target DPLL = 2*300MHz = 600MHz | ||
320 | */ | ||
321 | #define MII_DPLL_MULT_12 (50 << 12) | ||
322 | #define MII_DPLL_DIV_12 (1 << 8) | ||
323 | #define MII_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
324 | MII_DPLL_DIV_12 | MII_DPLL_MULT_12 | \ | ||
325 | MX_APLLS_CLIKIN_12 | ||
326 | #define MII_DPLL_MULT_13 (300 << 12) | ||
327 | #define MII_DPLL_DIV_13 (12 << 8) | ||
328 | #define MII_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
329 | MII_DPLL_DIV_13 | MII_DPLL_MULT_13 | \ | ||
330 | MX_APLLS_CLIKIN_13 | ||
331 | |||
332 | /* PRCM III target DPLL = 2*266 = 532MHz*/ | ||
333 | #define MIII_DPLL_MULT_12 (133 << 12) | ||
334 | #define MIII_DPLL_DIV_12 (5 << 8) | ||
335 | #define MIII_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
336 | MIII_DPLL_DIV_12 | MIII_DPLL_MULT_12 | \ | ||
337 | MX_APLLS_CLIKIN_12 | ||
338 | #define MIII_DPLL_MULT_13 (266 << 12) | ||
339 | #define MIII_DPLL_DIV_13 (12 << 8) | ||
340 | #define MIII_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | \ | ||
341 | MIII_DPLL_DIV_13 | MIII_DPLL_MULT_13 | \ | ||
342 | MX_APLLS_CLIKIN_13 | ||
343 | |||
344 | /* PRCM VII (boot bypass) */ | ||
345 | #define MVII_CM_CLKSEL1_PLL_12_VAL MB_CM_CLKSEL1_PLL_12_VAL | ||
346 | #define MVII_CM_CLKSEL1_PLL_13_VAL MB_CM_CLKSEL1_PLL_13_VAL | ||
347 | |||
348 | /* High and low operation value */ | ||
349 | #define MX_CLKSEL2_PLL_2x_VAL (2 << 0) | ||
350 | #define MX_CLKSEL2_PLL_1x_VAL (1 << 0) | ||
351 | |||
352 | /* | ||
353 | * These represent optimal values for common parts, it won't work for all. | ||
354 | * As long as you scale down, most parameters are still work, they just | ||
355 | * become sub-optimal. The RFR value goes in the oppisite direction. If you | ||
356 | * don't adjust it down as your clock period increases the refresh interval | ||
357 | * will not be met. Setting all parameters for complete worst case may work, | ||
358 | * but may cut memory performance by 2x. Due to errata the DLLs need to be | ||
359 | * unlocked and their value needs run time calibration. A dynamic call is | ||
360 | * need for that as no single right value exists acorss production samples. | ||
361 | * | ||
362 | * Only the FULL speed values are given. Current code is such that rate | ||
363 | * changes must be made at DPLLoutx2. The actual value adjustment for low | ||
364 | * frequency operation will be handled by omap_set_performance() | ||
365 | * | ||
366 | * By having the boot loader boot up in the fastest L4 speed available likely | ||
367 | * will result in something which you can switch between. | ||
368 | */ | ||
369 | #define V24XX_SDRC_RFR_CTRL_133MHz (0x0003de00 | 1) | ||
370 | #define V24XX_SDRC_RFR_CTRL_100MHz (0x0002da01 | 1) | ||
371 | #define V24XX_SDRC_RFR_CTRL_110MHz (0x0002da01 | 1) /* Need to calc */ | ||
372 | #define V24XX_SDRC_RFR_CTRL_BYPASS (0x00005000 | 1) /* Need to calc */ | ||
373 | |||
374 | /* MPU speed defines */ | ||
375 | #define S12M 12000000 | ||
376 | #define S13M 13000000 | ||
377 | #define S19M 19200000 | ||
378 | #define S26M 26000000 | ||
379 | #define S100M 100000000 | ||
380 | #define S133M 133000000 | ||
381 | #define S150M 150000000 | ||
382 | #define S165M 165000000 | ||
383 | #define S200M 200000000 | ||
384 | #define S266M 266000000 | ||
385 | #define S300M 300000000 | ||
386 | #define S330M 330000000 | ||
387 | #define S400M 400000000 | ||
388 | #define S532M 532000000 | ||
389 | #define S600M 600000000 | ||
390 | #define S660M 660000000 | ||
391 | |||
392 | /*------------------------------------------------------------------------- | ||
393 | * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. | ||
394 | * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU, | ||
395 | * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL, | ||
396 | * CM_CLKSEL2_PLL, CM_CLKSEL_MDM | ||
397 | * | ||
398 | * Filling in table based on H4 boards and 2430-SDPs variants available. | ||
399 | * There are quite a few more rates combinations which could be defined. | ||
400 | * | ||
401 | * When multiple values are defiend the start up will try and choose the | ||
402 | * fastest one. If a 'fast' value is defined, then automatically, the /2 | ||
403 | * one should be included as it can be used. Generally having more that | ||
404 | * one fast set does not make sense, as static timings need to be changed | ||
405 | * to change the set. The exception is the bypass setting which is | ||
406 | * availble for low power bypass. | ||
407 | * | ||
408 | * Note: This table needs to be sorted, fastest to slowest. | ||
409 | *-------------------------------------------------------------------------*/ | ||
410 | static struct prcm_config rate_table[] = { | ||
411 | /* PRCM II - FAST */ | ||
412 | {S12M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */ | ||
413 | RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, | ||
414 | RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL, | ||
415 | MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz, | ||
416 | RATE_IN_242X}, | ||
417 | |||
418 | {S13M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */ | ||
419 | RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, | ||
420 | RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL, | ||
421 | MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz, | ||
422 | RATE_IN_242X}, | ||
423 | |||
424 | /* PRCM III - FAST */ | ||
425 | {S12M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */ | ||
426 | RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, | ||
427 | RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL, | ||
428 | MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz, | ||
429 | RATE_IN_242X}, | ||
430 | |||
431 | {S13M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */ | ||
432 | RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, | ||
433 | RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL, | ||
434 | MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz, | ||
435 | RATE_IN_242X}, | ||
436 | |||
437 | /* PRCM II - SLOW */ | ||
438 | {S12M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */ | ||
439 | RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, | ||
440 | RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL, | ||
441 | MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz, | ||
442 | RATE_IN_242X}, | ||
443 | |||
444 | {S13M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */ | ||
445 | RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL, | ||
446 | RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL, | ||
447 | MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz, | ||
448 | RATE_IN_242X}, | ||
449 | |||
450 | /* PRCM III - SLOW */ | ||
451 | {S12M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */ | ||
452 | RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, | ||
453 | RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL, | ||
454 | MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz, | ||
455 | RATE_IN_242X}, | ||
456 | |||
457 | {S13M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */ | ||
458 | RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL, | ||
459 | RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL, | ||
460 | MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz, | ||
461 | RATE_IN_242X}, | ||
462 | |||
463 | /* PRCM-VII (boot-bypass) */ | ||
464 | {S12M, S12M, S12M, RVII_CM_CLKSEL_MPU_VAL, /* 12MHz ARM*/ | ||
465 | RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL, | ||
466 | RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_12_VAL, | ||
467 | MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_BYPASS, | ||
468 | RATE_IN_242X}, | ||
469 | |||
470 | /* PRCM-VII (boot-bypass) */ | ||
471 | {S13M, S13M, S13M, RVII_CM_CLKSEL_MPU_VAL, /* 13MHz ARM */ | ||
472 | RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL, | ||
473 | RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_13_VAL, | ||
474 | MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_BYPASS, | ||
475 | RATE_IN_242X}, | ||
476 | |||
477 | /* PRCM #3 - ratio2 (ES2) - FAST */ | ||
478 | {S13M, S660M, S330M, R2_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */ | ||
479 | R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL, | ||
480 | R2_CM_CLKSEL1_CORE_VAL, M3_CM_CLKSEL1_PLL_13_VAL, | ||
481 | MX_CLKSEL2_PLL_2x_VAL, R2_CM_CLKSEL_MDM_VAL, | ||
482 | V24XX_SDRC_RFR_CTRL_110MHz, | ||
483 | RATE_IN_243X}, | ||
484 | |||
485 | /* PRCM #5a - ratio1 - FAST */ | ||
486 | {S13M, S532M, S266M, R1_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */ | ||
487 | R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, | ||
488 | R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL, | ||
489 | MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL, | ||
490 | V24XX_SDRC_RFR_CTRL_133MHz, | ||
491 | RATE_IN_243X}, | ||
492 | |||
493 | /* PRCM #5b - ratio1 - FAST */ | ||
494 | {S13M, S400M, S200M, R1_CM_CLKSEL_MPU_VAL, /* 200MHz ARM */ | ||
495 | R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, | ||
496 | R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL, | ||
497 | MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL, | ||
498 | V24XX_SDRC_RFR_CTRL_100MHz, | ||
499 | RATE_IN_243X}, | ||
500 | |||
501 | /* PRCM #3 - ratio2 (ES2) - SLOW */ | ||
502 | {S13M, S330M, S165M, R2_CM_CLKSEL_MPU_VAL, /* 165MHz ARM */ | ||
503 | R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL, | ||
504 | R2_CM_CLKSEL1_CORE_VAL, M3_CM_CLKSEL1_PLL_13_VAL, | ||
505 | MX_CLKSEL2_PLL_1x_VAL, R2_CM_CLKSEL_MDM_VAL, | ||
506 | V24XX_SDRC_RFR_CTRL_110MHz, | ||
507 | RATE_IN_243X}, | ||
508 | |||
509 | /* PRCM #5a - ratio1 - SLOW */ | ||
510 | {S13M, S266M, S133M, R1_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */ | ||
511 | R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, | ||
512 | R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL, | ||
513 | MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL, | ||
514 | V24XX_SDRC_RFR_CTRL_133MHz, | ||
515 | RATE_IN_243X}, | ||
516 | |||
517 | /* PRCM #5b - ratio1 - SLOW*/ | ||
518 | {S13M, S200M, S100M, R1_CM_CLKSEL_MPU_VAL, /* 100MHz ARM */ | ||
519 | R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL, | ||
520 | R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL, | ||
521 | MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL, | ||
522 | V24XX_SDRC_RFR_CTRL_100MHz, | ||
523 | RATE_IN_243X}, | ||
524 | |||
525 | /* PRCM-boot/bypass */ | ||
526 | {S13M, S13M, S13M, RB_CM_CLKSEL_MPU_VAL, /* 13Mhz */ | ||
527 | RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL, | ||
528 | RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_13_VAL, | ||
529 | MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL, | ||
530 | V24XX_SDRC_RFR_CTRL_BYPASS, | ||
531 | RATE_IN_243X}, | ||
532 | |||
533 | /* PRCM-boot/bypass */ | ||
534 | {S12M, S12M, S12M, RB_CM_CLKSEL_MPU_VAL, /* 12Mhz */ | ||
535 | RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL, | ||
536 | RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_12_VAL, | ||
537 | MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL, | ||
538 | V24XX_SDRC_RFR_CTRL_BYPASS, | ||
539 | RATE_IN_243X}, | ||
540 | |||
541 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | ||
542 | }; | ||
543 | |||
544 | /*------------------------------------------------------------------------- | ||
545 | * 24xx clock tree. | ||
546 | * | ||
547 | * NOTE:In many cases here we are assigning a 'default' parent. In many | ||
548 | * cases the parent is selectable. The get/set parent calls will also | ||
549 | * switch sources. | ||
550 | * | ||
551 | * Many some clocks say always_enabled, but they can be auto idled for | ||
552 | * power savings. They will always be available upon clock request. | ||
553 | * | ||
554 | * Several sources are given initial rates which may be wrong, this will | ||
555 | * be fixed up in the init func. | ||
556 | * | ||
557 | * Things are broadly separated below by clock domains. It is | ||
558 | * noteworthy that most periferals have dependencies on multiple clock | ||
559 | * domains. Many get their interface clocks from the L4 domain, but get | ||
560 | * functional clocks from fixed sources or other core domain derived | ||
561 | * clocks. | ||
562 | *-------------------------------------------------------------------------*/ | ||
563 | |||
564 | /* Base external input clocks */ | ||
565 | static struct clk func_32k_ck = { | ||
566 | .name = "func_32k_ck", | ||
567 | .rate = 32000, | ||
568 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
569 | RATE_FIXED | ALWAYS_ENABLED, | ||
570 | }; | ||
571 | |||
572 | /* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */ | ||
573 | static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */ | ||
574 | .name = "osc_ck", | ||
575 | .rate = 26000000, /* fixed up in clock init */ | ||
576 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
577 | RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, | ||
578 | }; | ||
579 | |||
580 | /* With out modem likely 12MHz, with modem likely 13MHz */ | ||
581 | static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */ | ||
582 | .name = "sys_ck", /* ~ ref_clk also */ | ||
583 | .parent = &osc_ck, | ||
584 | .rate = 13000000, | ||
585 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
586 | RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, | ||
587 | .rate_offset = 6, /* sysclkdiv 1 or 2, already handled or no boot */ | ||
588 | .recalc = &omap2_sys_clk_recalc, | ||
589 | }; | ||
590 | |||
591 | static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */ | ||
592 | .name = "alt_ck", | ||
593 | .rate = 54000000, | ||
594 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
595 | RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, | ||
596 | .recalc = &omap2_propagate_rate, | ||
597 | }; | ||
598 | |||
599 | /* | ||
600 | * Analog domain root source clocks | ||
601 | */ | ||
602 | |||
603 | /* dpll_ck, is broken out in to special cases through clksel */ | ||
604 | static struct clk dpll_ck = { | ||
605 | .name = "dpll_ck", | ||
606 | .parent = &sys_ck, /* Can be func_32k also */ | ||
607 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
608 | RATE_PROPAGATES | RATE_CKCTL | CM_PLL_SEL1, | ||
609 | .recalc = &omap2_clksel_recalc, | ||
610 | }; | ||
611 | |||
612 | static struct clk apll96_ck = { | ||
613 | .name = "apll96_ck", | ||
614 | .parent = &sys_ck, | ||
615 | .rate = 96000000, | ||
616 | .flags = CLOCK_IN_OMAP242X |CLOCK_IN_OMAP243X | | ||
617 | RATE_FIXED | RATE_PROPAGATES, | ||
618 | .enable_reg = (void __iomem *)&CM_CLKEN_PLL, | ||
619 | .enable_bit = 0x2, | ||
620 | .recalc = &omap2_propagate_rate, | ||
621 | }; | ||
622 | |||
623 | static struct clk apll54_ck = { | ||
624 | .name = "apll54_ck", | ||
625 | .parent = &sys_ck, | ||
626 | .rate = 54000000, | ||
627 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
628 | RATE_FIXED | RATE_PROPAGATES, | ||
629 | .enable_reg = (void __iomem *)&CM_CLKEN_PLL, | ||
630 | .enable_bit = 0x6, | ||
631 | .recalc = &omap2_propagate_rate, | ||
632 | }; | ||
633 | |||
634 | /* | ||
635 | * PRCM digital base sources | ||
636 | */ | ||
637 | static struct clk func_54m_ck = { | ||
638 | .name = "func_54m_ck", | ||
639 | .parent = &apll54_ck, /* can also be alt_clk */ | ||
640 | .rate = 54000000, | ||
641 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
642 | RATE_FIXED | CM_PLL_SEL1 | RATE_PROPAGATES, | ||
643 | .src_offset = 5, | ||
644 | .enable_reg = (void __iomem *)&CM_CLKEN_PLL, | ||
645 | .enable_bit = 0xff, | ||
646 | .recalc = &omap2_propagate_rate, | ||
647 | }; | ||
648 | |||
649 | static struct clk core_ck = { | ||
650 | .name = "core_ck", | ||
651 | .parent = &dpll_ck, /* can also be 32k */ | ||
652 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
653 | ALWAYS_ENABLED | RATE_PROPAGATES, | ||
654 | .recalc = &omap2_propagate_rate, | ||
655 | }; | ||
656 | |||
657 | static struct clk sleep_ck = { /* sys_clk or 32k */ | ||
658 | .name = "sleep_ck", | ||
659 | .parent = &func_32k_ck, | ||
660 | .rate = 32000, | ||
661 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
662 | .recalc = &omap2_propagate_rate, | ||
663 | }; | ||
664 | |||
665 | static struct clk func_96m_ck = { | ||
666 | .name = "func_96m_ck", | ||
667 | .parent = &apll96_ck, | ||
668 | .rate = 96000000, | ||
669 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
670 | RATE_FIXED | RATE_PROPAGATES, | ||
671 | .enable_reg = (void __iomem *)&CM_CLKEN_PLL, | ||
672 | .enable_bit = 0xff, | ||
673 | .recalc = &omap2_propagate_rate, | ||
674 | }; | ||
675 | |||
676 | static struct clk func_48m_ck = { | ||
677 | .name = "func_48m_ck", | ||
678 | .parent = &apll96_ck, /* 96M or Alt */ | ||
679 | .rate = 48000000, | ||
680 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
681 | RATE_FIXED | CM_PLL_SEL1 | RATE_PROPAGATES, | ||
682 | .src_offset = 3, | ||
683 | .enable_reg = (void __iomem *)&CM_CLKEN_PLL, | ||
684 | .enable_bit = 0xff, | ||
685 | .recalc = &omap2_propagate_rate, | ||
686 | }; | ||
687 | |||
688 | static struct clk func_12m_ck = { | ||
689 | .name = "func_12m_ck", | ||
690 | .parent = &func_48m_ck, | ||
691 | .rate = 12000000, | ||
692 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
693 | RATE_FIXED | RATE_PROPAGATES, | ||
694 | .recalc = &omap2_propagate_rate, | ||
695 | .enable_reg = (void __iomem *)&CM_CLKEN_PLL, | ||
696 | .enable_bit = 0xff, | ||
697 | }; | ||
698 | |||
699 | /* Secure timer, only available in secure mode */ | ||
700 | static struct clk wdt1_osc_ck = { | ||
701 | .name = "ck_wdt1_osc", | ||
702 | .parent = &osc_ck, | ||
703 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
704 | .recalc = &omap2_followparent_recalc, | ||
705 | }; | ||
706 | |||
707 | static struct clk sys_clkout = { | ||
708 | .name = "sys_clkout", | ||
709 | .parent = &func_54m_ck, | ||
710 | .rate = 54000000, | ||
711 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
712 | CM_SYSCLKOUT_SEL1 | RATE_CKCTL, | ||
713 | .src_offset = 0, | ||
714 | .enable_reg = (void __iomem *)&PRCM_CLKOUT_CTRL, | ||
715 | .enable_bit = 7, | ||
716 | .rate_offset = 3, | ||
717 | .recalc = &omap2_clksel_recalc, | ||
718 | }; | ||
719 | |||
720 | /* In 2430, new in 2420 ES2 */ | ||
721 | static struct clk sys_clkout2 = { | ||
722 | .name = "sys_clkout2", | ||
723 | .parent = &func_54m_ck, | ||
724 | .rate = 54000000, | ||
725 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
726 | CM_SYSCLKOUT_SEL1 | RATE_CKCTL, | ||
727 | .src_offset = 8, | ||
728 | .enable_reg = (void __iomem *)&PRCM_CLKOUT_CTRL, | ||
729 | .enable_bit = 15, | ||
730 | .rate_offset = 11, | ||
731 | .recalc = &omap2_clksel_recalc, | ||
732 | }; | ||
733 | |||
734 | /* | ||
735 | * MPU clock domain | ||
736 | * Clocks: | ||
737 | * MPU_FCLK, MPU_ICLK | ||
738 | * INT_M_FCLK, INT_M_I_CLK | ||
739 | * | ||
740 | * - Individual clocks are hardware managed. | ||
741 | * - Base divider comes from: CM_CLKSEL_MPU | ||
742 | * | ||
743 | */ | ||
744 | static struct clk mpu_ck = { /* Control cpu */ | ||
745 | .name = "mpu_ck", | ||
746 | .parent = &core_ck, | ||
747 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL | | ||
748 | ALWAYS_ENABLED | CM_MPU_SEL1 | DELAYED_APP | | ||
749 | CONFIG_PARTICIPANT | RATE_PROPAGATES, | ||
750 | .rate_offset = 0, /* bits 0-4 */ | ||
751 | .recalc = &omap2_clksel_recalc, | ||
752 | }; | ||
753 | |||
754 | /* | ||
755 | * DSP (2430-IVA2.1) (2420-UMA+IVA1) clock domain | ||
756 | * Clocks: | ||
757 | * 2430: IVA2.1_FCLK, IVA2.1_ICLK | ||
758 | * 2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP | ||
759 | */ | ||
760 | static struct clk iva2_1_fck = { | ||
761 | .name = "iva2_1_fck", | ||
762 | .parent = &core_ck, | ||
763 | .flags = CLOCK_IN_OMAP243X | RATE_CKCTL | CM_DSP_SEL1 | | ||
764 | DELAYED_APP | RATE_PROPAGATES | | ||
765 | CONFIG_PARTICIPANT, | ||
766 | .rate_offset = 0, | ||
767 | .enable_reg = (void __iomem *)&CM_FCLKEN_DSP, | ||
768 | .enable_bit = 0, | ||
769 | .recalc = &omap2_clksel_recalc, | ||
770 | }; | ||
771 | |||
772 | static struct clk iva2_1_ick = { | ||
773 | .name = "iva2_1_ick", | ||
774 | .parent = &iva2_1_fck, | ||
775 | .flags = CLOCK_IN_OMAP243X | RATE_CKCTL | CM_DSP_SEL1 | | ||
776 | DELAYED_APP | CONFIG_PARTICIPANT, | ||
777 | .rate_offset = 5, | ||
778 | .recalc = &omap2_clksel_recalc, | ||
779 | }; | ||
780 | |||
781 | /* | ||
782 | * Won't be too specific here. The core clock comes into this block | ||
783 | * it is divided then tee'ed. One branch goes directly to xyz enable | ||
784 | * controls. The other branch gets further divided by 2 then possibly | ||
785 | * routed into a synchronizer and out of clocks abc. | ||
786 | */ | ||
787 | static struct clk dsp_fck = { | ||
788 | .name = "dsp_fck", | ||
789 | .parent = &core_ck, | ||
790 | .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1 | | ||
791 | DELAYED_APP | CONFIG_PARTICIPANT | RATE_PROPAGATES, | ||
792 | .rate_offset = 0, | ||
793 | .enable_reg = (void __iomem *)&CM_FCLKEN_DSP, | ||
794 | .enable_bit = 0, | ||
795 | .recalc = &omap2_clksel_recalc, | ||
796 | }; | ||
797 | |||
798 | static struct clk dsp_ick = { | ||
799 | .name = "dsp_ick", /* apparently ipi and isp */ | ||
800 | .parent = &dsp_fck, | ||
801 | .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1 | | ||
802 | DELAYED_APP | CONFIG_PARTICIPANT, | ||
803 | .rate_offset = 5, | ||
804 | .enable_reg = (void __iomem *)&CM_ICLKEN_DSP, | ||
805 | .enable_bit = 1, /* for ipi */ | ||
806 | .recalc = &omap2_clksel_recalc, | ||
807 | }; | ||
808 | |||
809 | static struct clk iva1_ifck = { | ||
810 | .name = "iva1_ifck", | ||
811 | .parent = &core_ck, | ||
812 | .flags = CLOCK_IN_OMAP242X | CM_DSP_SEL1 | RATE_CKCTL | | ||
813 | CONFIG_PARTICIPANT | RATE_PROPAGATES | DELAYED_APP, | ||
814 | .rate_offset= 8, | ||
815 | .enable_reg = (void __iomem *)&CM_FCLKEN_DSP, | ||
816 | .enable_bit = 10, | ||
817 | .recalc = &omap2_clksel_recalc, | ||
818 | }; | ||
819 | |||
820 | /* IVA1 mpu/int/i/f clocks are /2 of parent */ | ||
821 | static struct clk iva1_mpu_int_ifck = { | ||
822 | .name = "iva1_mpu_int_ifck", | ||
823 | .parent = &iva1_ifck, | ||
824 | .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1, | ||
825 | .enable_reg = (void __iomem *)&CM_FCLKEN_DSP, | ||
826 | .enable_bit = 8, | ||
827 | .recalc = &omap2_clksel_recalc, | ||
828 | }; | ||
829 | |||
830 | /* | ||
831 | * L3 clock domain | ||
832 | * L3 clocks are used for both interface and functional clocks to | ||
833 | * multiple entities. Some of these clocks are completely managed | ||
834 | * by hardware, and some others allow software control. Hardware | ||
835 | * managed ones general are based on directly CLK_REQ signals and | ||
836 | * various auto idle settings. The functional spec sets many of these | ||
837 | * as 'tie-high' for their enables. | ||
838 | * | ||
839 | * I-CLOCKS: | ||
840 | * L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA | ||
841 | * CAM, HS-USB. | ||
842 | * F-CLOCK | ||
843 | * SSI. | ||
844 | * | ||
845 | * GPMC memories and SDRC have timing and clock sensitive registers which | ||
846 | * may very well need notification when the clock changes. Currently for low | ||
847 | * operating points, these are taken care of in sleep.S. | ||
848 | */ | ||
849 | static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */ | ||
850 | .name = "core_l3_ck", | ||
851 | .parent = &core_ck, | ||
852 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
853 | RATE_CKCTL | ALWAYS_ENABLED | CM_CORE_SEL1 | | ||
854 | DELAYED_APP | CONFIG_PARTICIPANT | | ||
855 | RATE_PROPAGATES, | ||
856 | .rate_offset = 0, | ||
857 | .recalc = &omap2_clksel_recalc, | ||
858 | }; | ||
859 | |||
860 | static struct clk usb_l4_ick = { /* FS-USB interface clock */ | ||
861 | .name = "usb_l4_ick", | ||
862 | .parent = &core_ck, | ||
863 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
864 | RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP | | ||
865 | CONFIG_PARTICIPANT, | ||
866 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
867 | .enable_bit = 0, | ||
868 | .rate_offset = 25, | ||
869 | .recalc = &omap2_clksel_recalc, | ||
870 | }; | ||
871 | |||
872 | /* | ||
873 | * SSI is in L3 management domain, its direct parent is core not l3, | ||
874 | * many core power domain entities are grouped into the L3 clock | ||
875 | * domain. | ||
876 | * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_CLIK | ||
877 | * | ||
878 | * ssr = core/1/2/3/4/5, sst = 1/2 ssr. | ||
879 | */ | ||
880 | static struct clk ssi_ssr_sst_fck = { | ||
881 | .name = "ssi_fck", | ||
882 | .parent = &core_ck, | ||
883 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
884 | RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP, | ||
885 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, /* bit 1 */ | ||
886 | .enable_bit = 1, | ||
887 | .rate_offset = 20, | ||
888 | .recalc = &omap2_clksel_recalc, | ||
889 | }; | ||
890 | |||
891 | /* | ||
892 | * GFX clock domain | ||
893 | * Clocks: | ||
894 | * GFX_FCLK, GFX_ICLK | ||
895 | * GFX_CG1(2d), GFX_CG2(3d) | ||
896 | * | ||
897 | * GFX_FCLK runs from L3, and is divided by (1,2,3,4) | ||
898 | * The 2d and 3d clocks run at a hardware determined | ||
899 | * divided value of fclk. | ||
900 | * | ||
901 | */ | ||
902 | static struct clk gfx_3d_fck = { | ||
903 | .name = "gfx_3d_fck", | ||
904 | .parent = &core_l3_ck, | ||
905 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
906 | RATE_CKCTL | CM_GFX_SEL1, | ||
907 | .enable_reg = (void __iomem *)&CM_FCLKEN_GFX, | ||
908 | .enable_bit = 2, | ||
909 | .rate_offset= 0, | ||
910 | .recalc = &omap2_clksel_recalc, | ||
911 | }; | ||
912 | |||
913 | static struct clk gfx_2d_fck = { | ||
914 | .name = "gfx_2d_fck", | ||
915 | .parent = &core_l3_ck, | ||
916 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
917 | RATE_CKCTL | CM_GFX_SEL1, | ||
918 | .enable_reg = (void __iomem *)&CM_FCLKEN_GFX, | ||
919 | .enable_bit = 1, | ||
920 | .rate_offset= 0, | ||
921 | .recalc = &omap2_clksel_recalc, | ||
922 | }; | ||
923 | |||
924 | static struct clk gfx_ick = { | ||
925 | .name = "gfx_ick", /* From l3 */ | ||
926 | .parent = &core_l3_ck, | ||
927 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
928 | RATE_CKCTL, | ||
929 | .enable_reg = (void __iomem *)&CM_ICLKEN_GFX, /* bit 0 */ | ||
930 | .enable_bit = 0, | ||
931 | .recalc = &omap2_followparent_recalc, | ||
932 | }; | ||
933 | |||
934 | /* | ||
935 | * Modem clock domain (2430) | ||
936 | * CLOCKS: | ||
937 | * MDM_OSC_CLK | ||
938 | * MDM_ICLK | ||
939 | */ | ||
940 | static struct clk mdm_ick = { /* used both as a ick and fck */ | ||
941 | .name = "mdm_ick", | ||
942 | .parent = &core_ck, | ||
943 | .flags = CLOCK_IN_OMAP243X | RATE_CKCTL | CM_MODEM_SEL1 | | ||
944 | DELAYED_APP | CONFIG_PARTICIPANT, | ||
945 | .rate_offset = 0, | ||
946 | .enable_reg = (void __iomem *)&CM_ICLKEN_MDM, | ||
947 | .enable_bit = 0, | ||
948 | .recalc = &omap2_clksel_recalc, | ||
949 | }; | ||
950 | |||
951 | static struct clk mdm_osc_ck = { | ||
952 | .name = "mdm_osc_ck", | ||
953 | .rate = 26000000, | ||
954 | .parent = &osc_ck, | ||
955 | .flags = CLOCK_IN_OMAP243X | RATE_FIXED, | ||
956 | .enable_reg = (void __iomem *)&CM_FCLKEN_MDM, | ||
957 | .enable_bit = 1, | ||
958 | .recalc = &omap2_followparent_recalc, | ||
959 | }; | ||
960 | |||
961 | /* | ||
962 | * L4 clock management domain | ||
963 | * | ||
964 | * This domain contains lots of interface clocks from the L4 interface, some | ||
965 | * functional clocks. Fixed APLL functional source clocks are managed in | ||
966 | * this domain. | ||
967 | */ | ||
968 | static struct clk l4_ck = { /* used both as an ick and fck */ | ||
969 | .name = "l4_ck", | ||
970 | .parent = &core_l3_ck, | ||
971 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
972 | RATE_CKCTL | ALWAYS_ENABLED | CM_CORE_SEL1 | | ||
973 | DELAYED_APP | RATE_PROPAGATES, | ||
974 | .rate_offset = 5, | ||
975 | .recalc = &omap2_clksel_recalc, | ||
976 | }; | ||
977 | |||
978 | static struct clk ssi_l4_ick = { | ||
979 | .name = "ssi_l4_ick", | ||
980 | .parent = &l4_ck, | ||
981 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL, | ||
982 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, /* bit 1 */ | ||
983 | .enable_bit = 1, | ||
984 | .recalc = &omap2_followparent_recalc, | ||
985 | }; | ||
986 | |||
987 | /* | ||
988 | * DSS clock domain | ||
989 | * CLOCKs: | ||
990 | * DSS_L4_ICLK, DSS_L3_ICLK, | ||
991 | * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK | ||
992 | * | ||
993 | * DSS is both initiator and target. | ||
994 | */ | ||
995 | static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */ | ||
996 | .name = "dss_ick", | ||
997 | .parent = &l4_ck, /* really both l3 and l4 */ | ||
998 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL, | ||
999 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1000 | .enable_bit = 0, | ||
1001 | .recalc = &omap2_followparent_recalc, | ||
1002 | }; | ||
1003 | |||
1004 | static struct clk dss1_fck = { | ||
1005 | .name = "dss1_fck", | ||
1006 | .parent = &core_ck, /* Core or sys */ | ||
1007 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1008 | RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP, | ||
1009 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1010 | .enable_bit = 0, | ||
1011 | .rate_offset = 8, | ||
1012 | .src_offset = 8, | ||
1013 | .recalc = &omap2_clksel_recalc, | ||
1014 | }; | ||
1015 | |||
1016 | static struct clk dss2_fck = { /* Alt clk used in power management */ | ||
1017 | .name = "dss2_fck", | ||
1018 | .parent = &sys_ck, /* fixed at sys_ck or 48MHz */ | ||
1019 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1020 | RATE_CKCTL | CM_CORE_SEL1 | RATE_FIXED, | ||
1021 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1022 | .enable_bit = 1, | ||
1023 | .src_offset = 13, | ||
1024 | .recalc = &omap2_followparent_recalc, | ||
1025 | }; | ||
1026 | |||
1027 | static struct clk dss_54m_fck = { /* Alt clk used in power management */ | ||
1028 | .name = "dss_54m_fck", /* 54m tv clk */ | ||
1029 | .parent = &func_54m_ck, | ||
1030 | .rate = 54000000, | ||
1031 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1032 | RATE_FIXED | RATE_PROPAGATES, | ||
1033 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1034 | .enable_bit = 2, | ||
1035 | .recalc = &omap2_propagate_rate, | ||
1036 | }; | ||
1037 | |||
1038 | /* | ||
1039 | * CORE power domain ICLK & FCLK defines. | ||
1040 | * Many of the these can have more than one possible parent. Entries | ||
1041 | * here will likely have an L4 interface parent, and may have multiple | ||
1042 | * functional clock parents. | ||
1043 | */ | ||
1044 | static struct clk gpt1_ick = { | ||
1045 | .name = "gpt1_ick", | ||
1046 | .parent = &l4_ck, | ||
1047 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1048 | .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, /* Bit4 */ | ||
1049 | .enable_bit = 0, | ||
1050 | .recalc = &omap2_followparent_recalc, | ||
1051 | }; | ||
1052 | |||
1053 | static struct clk gpt1_fck = { | ||
1054 | .name = "gpt1_fck", | ||
1055 | .parent = &func_32k_ck, | ||
1056 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1057 | CM_WKUP_SEL1, | ||
1058 | .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP, | ||
1059 | .enable_bit = 0, | ||
1060 | .src_offset = 0, | ||
1061 | .recalc = &omap2_followparent_recalc, | ||
1062 | }; | ||
1063 | |||
1064 | static struct clk gpt2_ick = { | ||
1065 | .name = "gpt2_ick", | ||
1066 | .parent = &l4_ck, | ||
1067 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1068 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit4 */ | ||
1069 | .enable_bit = 0, | ||
1070 | .recalc = &omap2_followparent_recalc, | ||
1071 | }; | ||
1072 | |||
1073 | static struct clk gpt2_fck = { | ||
1074 | .name = "gpt2_fck", | ||
1075 | .parent = &func_32k_ck, | ||
1076 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1077 | CM_CORE_SEL2, | ||
1078 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1079 | .enable_bit = 4, | ||
1080 | .src_offset = 2, | ||
1081 | .recalc = &omap2_followparent_recalc, | ||
1082 | }; | ||
1083 | |||
1084 | static struct clk gpt3_ick = { | ||
1085 | .name = "gpt3_ick", | ||
1086 | .parent = &l4_ck, | ||
1087 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1088 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit5 */ | ||
1089 | .enable_bit = 5, | ||
1090 | .recalc = &omap2_followparent_recalc, | ||
1091 | }; | ||
1092 | |||
1093 | static struct clk gpt3_fck = { | ||
1094 | .name = "gpt3_fck", | ||
1095 | .parent = &func_32k_ck, | ||
1096 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1097 | CM_CORE_SEL2, | ||
1098 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1099 | .enable_bit = 5, | ||
1100 | .src_offset = 4, | ||
1101 | .recalc = &omap2_followparent_recalc, | ||
1102 | }; | ||
1103 | |||
1104 | static struct clk gpt4_ick = { | ||
1105 | .name = "gpt4_ick", | ||
1106 | .parent = &l4_ck, | ||
1107 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1108 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit6 */ | ||
1109 | .enable_bit = 6, | ||
1110 | .recalc = &omap2_followparent_recalc, | ||
1111 | }; | ||
1112 | |||
1113 | static struct clk gpt4_fck = { | ||
1114 | .name = "gpt4_fck", | ||
1115 | .parent = &func_32k_ck, | ||
1116 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1117 | CM_CORE_SEL2, | ||
1118 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1119 | .enable_bit = 6, | ||
1120 | .src_offset = 6, | ||
1121 | .recalc = &omap2_followparent_recalc, | ||
1122 | }; | ||
1123 | |||
1124 | static struct clk gpt5_ick = { | ||
1125 | .name = "gpt5_ick", | ||
1126 | .parent = &l4_ck, | ||
1127 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1128 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit7 */ | ||
1129 | .enable_bit = 7, | ||
1130 | .recalc = &omap2_followparent_recalc, | ||
1131 | }; | ||
1132 | |||
1133 | static struct clk gpt5_fck = { | ||
1134 | .name = "gpt5_fck", | ||
1135 | .parent = &func_32k_ck, | ||
1136 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1137 | CM_CORE_SEL2, | ||
1138 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1139 | .enable_bit = 7, | ||
1140 | .src_offset = 8, | ||
1141 | .recalc = &omap2_followparent_recalc, | ||
1142 | }; | ||
1143 | |||
1144 | static struct clk gpt6_ick = { | ||
1145 | .name = "gpt6_ick", | ||
1146 | .parent = &l4_ck, | ||
1147 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1148 | .enable_bit = 8, | ||
1149 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit8 */ | ||
1150 | .recalc = &omap2_followparent_recalc, | ||
1151 | }; | ||
1152 | |||
1153 | static struct clk gpt6_fck = { | ||
1154 | .name = "gpt6_fck", | ||
1155 | .parent = &func_32k_ck, | ||
1156 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1157 | CM_CORE_SEL2, | ||
1158 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1159 | .enable_bit = 8, | ||
1160 | .src_offset = 10, | ||
1161 | .recalc = &omap2_followparent_recalc, | ||
1162 | }; | ||
1163 | |||
1164 | static struct clk gpt7_ick = { | ||
1165 | .name = "gpt7_ick", | ||
1166 | .parent = &l4_ck, | ||
1167 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1168 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit9 */ | ||
1169 | .enable_bit = 9, | ||
1170 | .recalc = &omap2_followparent_recalc, | ||
1171 | }; | ||
1172 | |||
1173 | static struct clk gpt7_fck = { | ||
1174 | .name = "gpt7_fck", | ||
1175 | .parent = &func_32k_ck, | ||
1176 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1177 | CM_CORE_SEL2, | ||
1178 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1179 | .enable_bit = 9, | ||
1180 | .src_offset = 12, | ||
1181 | .recalc = &omap2_followparent_recalc, | ||
1182 | }; | ||
1183 | |||
1184 | static struct clk gpt8_ick = { | ||
1185 | .name = "gpt8_ick", | ||
1186 | .parent = &l4_ck, | ||
1187 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1188 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit10 */ | ||
1189 | .enable_bit = 10, | ||
1190 | .recalc = &omap2_followparent_recalc, | ||
1191 | }; | ||
1192 | |||
1193 | static struct clk gpt8_fck = { | ||
1194 | .name = "gpt8_fck", | ||
1195 | .parent = &func_32k_ck, | ||
1196 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1197 | CM_CORE_SEL2, | ||
1198 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1199 | .enable_bit = 10, | ||
1200 | .src_offset = 14, | ||
1201 | .recalc = &omap2_followparent_recalc, | ||
1202 | }; | ||
1203 | |||
1204 | static struct clk gpt9_ick = { | ||
1205 | .name = "gpt9_ick", | ||
1206 | .parent = &l4_ck, | ||
1207 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1208 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1209 | .enable_bit = 11, | ||
1210 | .recalc = &omap2_followparent_recalc, | ||
1211 | }; | ||
1212 | |||
1213 | static struct clk gpt9_fck = { | ||
1214 | .name = "gpt9_fck", | ||
1215 | .parent = &func_32k_ck, | ||
1216 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1217 | CM_CORE_SEL2, | ||
1218 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1219 | .enable_bit = 11, | ||
1220 | .src_offset = 16, | ||
1221 | .recalc = &omap2_followparent_recalc, | ||
1222 | }; | ||
1223 | |||
1224 | static struct clk gpt10_ick = { | ||
1225 | .name = "gpt10_ick", | ||
1226 | .parent = &l4_ck, | ||
1227 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1228 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1229 | .enable_bit = 12, | ||
1230 | .recalc = &omap2_followparent_recalc, | ||
1231 | }; | ||
1232 | |||
1233 | static struct clk gpt10_fck = { | ||
1234 | .name = "gpt10_fck", | ||
1235 | .parent = &func_32k_ck, | ||
1236 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1237 | CM_CORE_SEL2, | ||
1238 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1239 | .enable_bit = 12, | ||
1240 | .src_offset = 18, | ||
1241 | .recalc = &omap2_followparent_recalc, | ||
1242 | }; | ||
1243 | |||
1244 | static struct clk gpt11_ick = { | ||
1245 | .name = "gpt11_ick", | ||
1246 | .parent = &l4_ck, | ||
1247 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1248 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1249 | .enable_bit = 13, | ||
1250 | .recalc = &omap2_followparent_recalc, | ||
1251 | }; | ||
1252 | |||
1253 | static struct clk gpt11_fck = { | ||
1254 | .name = "gpt11_fck", | ||
1255 | .parent = &func_32k_ck, | ||
1256 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1257 | CM_CORE_SEL2, | ||
1258 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1259 | .enable_bit = 13, | ||
1260 | .src_offset = 20, | ||
1261 | .recalc = &omap2_followparent_recalc, | ||
1262 | }; | ||
1263 | |||
1264 | static struct clk gpt12_ick = { | ||
1265 | .name = "gpt12_ick", | ||
1266 | .parent = &l4_ck, | ||
1267 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1268 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit14 */ | ||
1269 | .enable_bit = 14, | ||
1270 | .recalc = &omap2_followparent_recalc, | ||
1271 | }; | ||
1272 | |||
1273 | static struct clk gpt12_fck = { | ||
1274 | .name = "gpt12_fck", | ||
1275 | .parent = &func_32k_ck, | ||
1276 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1277 | CM_CORE_SEL2, | ||
1278 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1279 | .enable_bit = 14, | ||
1280 | .src_offset = 22, | ||
1281 | .recalc = &omap2_followparent_recalc, | ||
1282 | }; | ||
1283 | |||
1284 | static struct clk mcbsp1_ick = { | ||
1285 | .name = "mcbsp1_ick", | ||
1286 | .parent = &l4_ck, | ||
1287 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1288 | .enable_bit = 15, | ||
1289 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit16 */ | ||
1290 | .recalc = &omap2_followparent_recalc, | ||
1291 | }; | ||
1292 | |||
1293 | static struct clk mcbsp1_fck = { | ||
1294 | .name = "mcbsp1_fck", | ||
1295 | .parent = &func_96m_ck, | ||
1296 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1297 | .enable_bit = 15, | ||
1298 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1299 | .recalc = &omap2_followparent_recalc, | ||
1300 | }; | ||
1301 | |||
1302 | static struct clk mcbsp2_ick = { | ||
1303 | .name = "mcbsp2_ick", | ||
1304 | .parent = &l4_ck, | ||
1305 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1306 | .enable_bit = 16, | ||
1307 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1308 | .recalc = &omap2_followparent_recalc, | ||
1309 | }; | ||
1310 | |||
1311 | static struct clk mcbsp2_fck = { | ||
1312 | .name = "mcbsp2_fck", | ||
1313 | .parent = &func_96m_ck, | ||
1314 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1315 | .enable_bit = 16, | ||
1316 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1317 | .recalc = &omap2_followparent_recalc, | ||
1318 | }; | ||
1319 | |||
1320 | static struct clk mcbsp3_ick = { | ||
1321 | .name = "mcbsp3_ick", | ||
1322 | .parent = &l4_ck, | ||
1323 | .flags = CLOCK_IN_OMAP243X, | ||
1324 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
1325 | .enable_bit = 3, | ||
1326 | .recalc = &omap2_followparent_recalc, | ||
1327 | }; | ||
1328 | |||
1329 | static struct clk mcbsp3_fck = { | ||
1330 | .name = "mcbsp3_fck", | ||
1331 | .parent = &func_96m_ck, | ||
1332 | .flags = CLOCK_IN_OMAP243X, | ||
1333 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1334 | .enable_bit = 3, | ||
1335 | .recalc = &omap2_followparent_recalc, | ||
1336 | }; | ||
1337 | |||
1338 | static struct clk mcbsp4_ick = { | ||
1339 | .name = "mcbsp4_ick", | ||
1340 | .parent = &l4_ck, | ||
1341 | .flags = CLOCK_IN_OMAP243X, | ||
1342 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
1343 | .enable_bit = 4, | ||
1344 | .recalc = &omap2_followparent_recalc, | ||
1345 | }; | ||
1346 | |||
1347 | static struct clk mcbsp4_fck = { | ||
1348 | .name = "mcbsp4_fck", | ||
1349 | .parent = &func_96m_ck, | ||
1350 | .flags = CLOCK_IN_OMAP243X, | ||
1351 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1352 | .enable_bit = 4, | ||
1353 | .recalc = &omap2_followparent_recalc, | ||
1354 | }; | ||
1355 | |||
1356 | static struct clk mcbsp5_ick = { | ||
1357 | .name = "mcbsp5_ick", | ||
1358 | .parent = &l4_ck, | ||
1359 | .flags = CLOCK_IN_OMAP243X, | ||
1360 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
1361 | .enable_bit = 5, | ||
1362 | .recalc = &omap2_followparent_recalc, | ||
1363 | }; | ||
1364 | |||
1365 | static struct clk mcbsp5_fck = { | ||
1366 | .name = "mcbsp5_fck", | ||
1367 | .parent = &func_96m_ck, | ||
1368 | .flags = CLOCK_IN_OMAP243X, | ||
1369 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1370 | .enable_bit = 5, | ||
1371 | .recalc = &omap2_followparent_recalc, | ||
1372 | }; | ||
1373 | |||
1374 | static struct clk mcspi1_ick = { | ||
1375 | .name = "mcspi1_ick", | ||
1376 | .parent = &l4_ck, | ||
1377 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1378 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1379 | .enable_bit = 17, | ||
1380 | .recalc = &omap2_followparent_recalc, | ||
1381 | }; | ||
1382 | |||
1383 | static struct clk mcspi1_fck = { | ||
1384 | .name = "mcspi1_fck", | ||
1385 | .parent = &func_48m_ck, | ||
1386 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1387 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1388 | .enable_bit = 17, | ||
1389 | .recalc = &omap2_followparent_recalc, | ||
1390 | }; | ||
1391 | |||
1392 | static struct clk mcspi2_ick = { | ||
1393 | .name = "mcspi2_ick", | ||
1394 | .parent = &l4_ck, | ||
1395 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1396 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1397 | .enable_bit = 18, | ||
1398 | .recalc = &omap2_followparent_recalc, | ||
1399 | }; | ||
1400 | |||
1401 | static struct clk mcspi2_fck = { | ||
1402 | .name = "mcspi2_fck", | ||
1403 | .parent = &func_48m_ck, | ||
1404 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1405 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1406 | .enable_bit = 18, | ||
1407 | .recalc = &omap2_followparent_recalc, | ||
1408 | }; | ||
1409 | |||
1410 | static struct clk mcspi3_ick = { | ||
1411 | .name = "mcspi3_ick", | ||
1412 | .parent = &l4_ck, | ||
1413 | .flags = CLOCK_IN_OMAP243X, | ||
1414 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
1415 | .enable_bit = 9, | ||
1416 | .recalc = &omap2_followparent_recalc, | ||
1417 | }; | ||
1418 | |||
1419 | static struct clk mcspi3_fck = { | ||
1420 | .name = "mcspi3_fck", | ||
1421 | .parent = &func_48m_ck, | ||
1422 | .flags = CLOCK_IN_OMAP243X, | ||
1423 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1424 | .enable_bit = 9, | ||
1425 | .recalc = &omap2_followparent_recalc, | ||
1426 | }; | ||
1427 | |||
1428 | static struct clk uart1_ick = { | ||
1429 | .name = "uart1_ick", | ||
1430 | .parent = &l4_ck, | ||
1431 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1432 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1433 | .enable_bit = 21, | ||
1434 | .recalc = &omap2_followparent_recalc, | ||
1435 | }; | ||
1436 | |||
1437 | static struct clk uart1_fck = { | ||
1438 | .name = "uart1_fck", | ||
1439 | .parent = &func_48m_ck, | ||
1440 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1441 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1442 | .enable_bit = 21, | ||
1443 | .recalc = &omap2_followparent_recalc, | ||
1444 | }; | ||
1445 | |||
1446 | static struct clk uart2_ick = { | ||
1447 | .name = "uart2_ick", | ||
1448 | .parent = &l4_ck, | ||
1449 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1450 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1451 | .enable_bit = 22, | ||
1452 | .recalc = &omap2_followparent_recalc, | ||
1453 | }; | ||
1454 | |||
1455 | static struct clk uart2_fck = { | ||
1456 | .name = "uart2_fck", | ||
1457 | .parent = &func_48m_ck, | ||
1458 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1459 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1460 | .enable_bit = 22, | ||
1461 | .recalc = &omap2_followparent_recalc, | ||
1462 | }; | ||
1463 | |||
1464 | static struct clk uart3_ick = { | ||
1465 | .name = "uart3_ick", | ||
1466 | .parent = &l4_ck, | ||
1467 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1468 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
1469 | .enable_bit = 2, | ||
1470 | .recalc = &omap2_followparent_recalc, | ||
1471 | }; | ||
1472 | |||
1473 | static struct clk uart3_fck = { | ||
1474 | .name = "uart3_fck", | ||
1475 | .parent = &func_48m_ck, | ||
1476 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1477 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1478 | .enable_bit = 2, | ||
1479 | .recalc = &omap2_followparent_recalc, | ||
1480 | }; | ||
1481 | |||
1482 | static struct clk gpios_ick = { | ||
1483 | .name = "gpios_ick", | ||
1484 | .parent = &l4_ck, | ||
1485 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1486 | .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, | ||
1487 | .enable_bit = 2, | ||
1488 | .recalc = &omap2_followparent_recalc, | ||
1489 | }; | ||
1490 | |||
1491 | static struct clk gpios_fck = { | ||
1492 | .name = "gpios_fck", | ||
1493 | .parent = &func_32k_ck, | ||
1494 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1495 | .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP, | ||
1496 | .enable_bit = 2, | ||
1497 | .recalc = &omap2_followparent_recalc, | ||
1498 | }; | ||
1499 | |||
1500 | static struct clk mpu_wdt_ick = { | ||
1501 | .name = "mpu_wdt_ick", | ||
1502 | .parent = &l4_ck, | ||
1503 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1504 | .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, | ||
1505 | .enable_bit = 3, | ||
1506 | .recalc = &omap2_followparent_recalc, | ||
1507 | }; | ||
1508 | |||
1509 | static struct clk mpu_wdt_fck = { | ||
1510 | .name = "mpu_wdt_fck", | ||
1511 | .parent = &func_32k_ck, | ||
1512 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1513 | .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP, | ||
1514 | .enable_bit = 3, | ||
1515 | .recalc = &omap2_followparent_recalc, | ||
1516 | }; | ||
1517 | |||
1518 | static struct clk sync_32k_ick = { | ||
1519 | .name = "sync_32k_ick", | ||
1520 | .parent = &l4_ck, | ||
1521 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1522 | .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, | ||
1523 | .enable_bit = 1, | ||
1524 | .recalc = &omap2_followparent_recalc, | ||
1525 | }; | ||
1526 | static struct clk wdt1_ick = { | ||
1527 | .name = "wdt1_ick", | ||
1528 | .parent = &l4_ck, | ||
1529 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1530 | .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, | ||
1531 | .enable_bit = 4, | ||
1532 | .recalc = &omap2_followparent_recalc, | ||
1533 | }; | ||
1534 | static struct clk omapctrl_ick = { | ||
1535 | .name = "omapctrl_ick", | ||
1536 | .parent = &l4_ck, | ||
1537 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1538 | .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, | ||
1539 | .enable_bit = 5, | ||
1540 | .recalc = &omap2_followparent_recalc, | ||
1541 | }; | ||
1542 | static struct clk icr_ick = { | ||
1543 | .name = "icr_ick", | ||
1544 | .parent = &l4_ck, | ||
1545 | .flags = CLOCK_IN_OMAP243X, | ||
1546 | .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, | ||
1547 | .enable_bit = 6, | ||
1548 | .recalc = &omap2_followparent_recalc, | ||
1549 | }; | ||
1550 | |||
1551 | static struct clk cam_ick = { | ||
1552 | .name = "cam_ick", | ||
1553 | .parent = &l4_ck, | ||
1554 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1555 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1556 | .enable_bit = 31, | ||
1557 | .recalc = &omap2_followparent_recalc, | ||
1558 | }; | ||
1559 | |||
1560 | static struct clk cam_fck = { | ||
1561 | .name = "cam_fck", | ||
1562 | .parent = &func_96m_ck, | ||
1563 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1564 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1565 | .enable_bit = 31, | ||
1566 | .recalc = &omap2_followparent_recalc, | ||
1567 | }; | ||
1568 | |||
1569 | static struct clk mailboxes_ick = { | ||
1570 | .name = "mailboxes_ick", | ||
1571 | .parent = &l4_ck, | ||
1572 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1573 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1574 | .enable_bit = 30, | ||
1575 | .recalc = &omap2_followparent_recalc, | ||
1576 | }; | ||
1577 | |||
1578 | static struct clk wdt4_ick = { | ||
1579 | .name = "wdt4_ick", | ||
1580 | .parent = &l4_ck, | ||
1581 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1582 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1583 | .enable_bit = 29, | ||
1584 | .recalc = &omap2_followparent_recalc, | ||
1585 | }; | ||
1586 | |||
1587 | static struct clk wdt4_fck = { | ||
1588 | .name = "wdt4_fck", | ||
1589 | .parent = &func_32k_ck, | ||
1590 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1591 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1592 | .enable_bit = 29, | ||
1593 | .recalc = &omap2_followparent_recalc, | ||
1594 | }; | ||
1595 | |||
1596 | static struct clk wdt3_ick = { | ||
1597 | .name = "wdt3_ick", | ||
1598 | .parent = &l4_ck, | ||
1599 | .flags = CLOCK_IN_OMAP242X, | ||
1600 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1601 | .enable_bit = 28, | ||
1602 | .recalc = &omap2_followparent_recalc, | ||
1603 | }; | ||
1604 | |||
1605 | static struct clk wdt3_fck = { | ||
1606 | .name = "wdt3_fck", | ||
1607 | .parent = &func_32k_ck, | ||
1608 | .flags = CLOCK_IN_OMAP242X, | ||
1609 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1610 | .enable_bit = 28, | ||
1611 | .recalc = &omap2_followparent_recalc, | ||
1612 | }; | ||
1613 | |||
1614 | static struct clk mspro_ick = { | ||
1615 | .name = "mspro_ick", | ||
1616 | .parent = &l4_ck, | ||
1617 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1618 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1619 | .enable_bit = 27, | ||
1620 | .recalc = &omap2_followparent_recalc, | ||
1621 | }; | ||
1622 | |||
1623 | static struct clk mspro_fck = { | ||
1624 | .name = "mspro_fck", | ||
1625 | .parent = &func_96m_ck, | ||
1626 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1627 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1628 | .enable_bit = 27, | ||
1629 | .recalc = &omap2_followparent_recalc, | ||
1630 | }; | ||
1631 | |||
1632 | static struct clk mmc_ick = { | ||
1633 | .name = "mmc_ick", | ||
1634 | .parent = &l4_ck, | ||
1635 | .flags = CLOCK_IN_OMAP242X, | ||
1636 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1637 | .enable_bit = 26, | ||
1638 | .recalc = &omap2_followparent_recalc, | ||
1639 | }; | ||
1640 | |||
1641 | static struct clk mmc_fck = { | ||
1642 | .name = "mmc_fck", | ||
1643 | .parent = &func_96m_ck, | ||
1644 | .flags = CLOCK_IN_OMAP242X, | ||
1645 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1646 | .enable_bit = 26, | ||
1647 | .recalc = &omap2_followparent_recalc, | ||
1648 | }; | ||
1649 | |||
1650 | static struct clk fac_ick = { | ||
1651 | .name = "fac_ick", | ||
1652 | .parent = &l4_ck, | ||
1653 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1654 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1655 | .enable_bit = 25, | ||
1656 | .recalc = &omap2_followparent_recalc, | ||
1657 | }; | ||
1658 | |||
1659 | static struct clk fac_fck = { | ||
1660 | .name = "fac_fck", | ||
1661 | .parent = &func_12m_ck, | ||
1662 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1663 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1664 | .enable_bit = 25, | ||
1665 | .recalc = &omap2_followparent_recalc, | ||
1666 | }; | ||
1667 | |||
1668 | static struct clk eac_ick = { | ||
1669 | .name = "eac_ick", | ||
1670 | .parent = &l4_ck, | ||
1671 | .flags = CLOCK_IN_OMAP242X, | ||
1672 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1673 | .enable_bit = 24, | ||
1674 | .recalc = &omap2_followparent_recalc, | ||
1675 | }; | ||
1676 | |||
1677 | static struct clk eac_fck = { | ||
1678 | .name = "eac_fck", | ||
1679 | .parent = &func_96m_ck, | ||
1680 | .flags = CLOCK_IN_OMAP242X, | ||
1681 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1682 | .enable_bit = 24, | ||
1683 | .recalc = &omap2_followparent_recalc, | ||
1684 | }; | ||
1685 | |||
1686 | static struct clk hdq_ick = { | ||
1687 | .name = "hdq_ick", | ||
1688 | .parent = &l4_ck, | ||
1689 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1690 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1691 | .enable_bit = 23, | ||
1692 | .recalc = &omap2_followparent_recalc, | ||
1693 | }; | ||
1694 | |||
1695 | static struct clk hdq_fck = { | ||
1696 | .name = "hdq_fck", | ||
1697 | .parent = &func_12m_ck, | ||
1698 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1699 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1700 | .enable_bit = 23, | ||
1701 | .recalc = &omap2_followparent_recalc, | ||
1702 | }; | ||
1703 | |||
1704 | static struct clk i2c2_ick = { | ||
1705 | .name = "i2c2_ick", | ||
1706 | .parent = &l4_ck, | ||
1707 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1708 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1709 | .enable_bit = 20, | ||
1710 | .recalc = &omap2_followparent_recalc, | ||
1711 | }; | ||
1712 | |||
1713 | static struct clk i2c2_fck = { | ||
1714 | .name = "i2c2_fck", | ||
1715 | .parent = &func_12m_ck, | ||
1716 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1717 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1718 | .enable_bit = 20, | ||
1719 | .recalc = &omap2_followparent_recalc, | ||
1720 | }; | ||
1721 | |||
1722 | static struct clk i2chs2_fck = { | ||
1723 | .name = "i2chs2_fck", | ||
1724 | .parent = &func_96m_ck, | ||
1725 | .flags = CLOCK_IN_OMAP243X, | ||
1726 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1727 | .enable_bit = 20, | ||
1728 | .recalc = &omap2_followparent_recalc, | ||
1729 | }; | ||
1730 | |||
1731 | static struct clk i2c1_ick = { | ||
1732 | .name = "i2c1_ick", | ||
1733 | .parent = &l4_ck, | ||
1734 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1735 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1736 | .enable_bit = 19, | ||
1737 | .recalc = &omap2_followparent_recalc, | ||
1738 | }; | ||
1739 | |||
1740 | static struct clk i2c1_fck = { | ||
1741 | .name = "i2c1_fck", | ||
1742 | .parent = &func_12m_ck, | ||
1743 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | ||
1744 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1745 | .enable_bit = 19, | ||
1746 | .recalc = &omap2_followparent_recalc, | ||
1747 | }; | ||
1748 | |||
1749 | static struct clk i2chs1_fck = { | ||
1750 | .name = "i2chs1_fck", | ||
1751 | .parent = &func_96m_ck, | ||
1752 | .flags = CLOCK_IN_OMAP243X, | ||
1753 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1754 | .enable_bit = 19, | ||
1755 | .recalc = &omap2_followparent_recalc, | ||
1756 | }; | ||
1757 | |||
1758 | static struct clk vlynq_ick = { | ||
1759 | .name = "vlynq_ick", | ||
1760 | .parent = &core_l3_ck, | ||
1761 | .flags = CLOCK_IN_OMAP242X, | ||
1762 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | ||
1763 | .enable_bit = 3, | ||
1764 | .recalc = &omap2_followparent_recalc, | ||
1765 | }; | ||
1766 | |||
1767 | static struct clk vlynq_fck = { | ||
1768 | .name = "vlynq_fck", | ||
1769 | .parent = &func_96m_ck, | ||
1770 | .flags = CLOCK_IN_OMAP242X | RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP, | ||
1771 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | ||
1772 | .enable_bit = 3, | ||
1773 | .src_offset = 15, | ||
1774 | .recalc = &omap2_followparent_recalc, | ||
1775 | }; | ||
1776 | |||
1777 | static struct clk sdrc_ick = { | ||
1778 | .name = "sdrc_ick", | ||
1779 | .parent = &l4_ck, | ||
1780 | .flags = CLOCK_IN_OMAP243X, | ||
1781 | .enable_reg = (void __iomem *)&CM_ICLKEN3_CORE, | ||
1782 | .enable_bit = 2, | ||
1783 | .recalc = &omap2_followparent_recalc, | ||
1784 | }; | ||
1785 | |||
1786 | static struct clk des_ick = { | ||
1787 | .name = "des_ick", | ||
1788 | .parent = &l4_ck, | ||
1789 | .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, | ||
1790 | .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE, | ||
1791 | .enable_bit = 0, | ||
1792 | .recalc = &omap2_followparent_recalc, | ||
1793 | }; | ||
1794 | |||
1795 | static struct clk sha_ick = { | ||
1796 | .name = "sha_ick", | ||
1797 | .parent = &l4_ck, | ||
1798 | .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, | ||
1799 | .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE, | ||
1800 | .enable_bit = 1, | ||
1801 | .recalc = &omap2_followparent_recalc, | ||
1802 | }; | ||
1803 | |||
1804 | static struct clk rng_ick = { | ||
1805 | .name = "rng_ick", | ||
1806 | .parent = &l4_ck, | ||
1807 | .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, | ||
1808 | .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE, | ||
1809 | .enable_bit = 2, | ||
1810 | .recalc = &omap2_followparent_recalc, | ||
1811 | }; | ||
1812 | |||
1813 | static struct clk aes_ick = { | ||
1814 | .name = "aes_ick", | ||
1815 | .parent = &l4_ck, | ||
1816 | .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, | ||
1817 | .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE, | ||
1818 | .enable_bit = 3, | ||
1819 | .recalc = &omap2_followparent_recalc, | ||
1820 | }; | ||
1821 | |||
1822 | static struct clk pka_ick = { | ||
1823 | .name = "pka_ick", | ||
1824 | .parent = &l4_ck, | ||
1825 | .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, | ||
1826 | .enable_reg = (void __iomem *)&CM_ICLKEN4_CORE, | ||
1827 | .enable_bit = 4, | ||
1828 | .recalc = &omap2_followparent_recalc, | ||
1829 | }; | ||
1830 | |||
1831 | static struct clk usb_fck = { | ||
1832 | .name = "usb_fck", | ||
1833 | .parent = &func_48m_ck, | ||
1834 | .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X, | ||
1835 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1836 | .enable_bit = 0, | ||
1837 | .recalc = &omap2_followparent_recalc, | ||
1838 | }; | ||
1839 | |||
1840 | static struct clk usbhs_ick = { | ||
1841 | .name = "usbhs_ick", | ||
1842 | .parent = &l4_ck, | ||
1843 | .flags = CLOCK_IN_OMAP243X, | ||
1844 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
1845 | .enable_bit = 6, | ||
1846 | .recalc = &omap2_followparent_recalc, | ||
1847 | }; | ||
1848 | |||
1849 | static struct clk mmchs1_ick = { | ||
1850 | .name = "mmchs1_ick", | ||
1851 | .parent = &l4_ck, | ||
1852 | .flags = CLOCK_IN_OMAP243X, | ||
1853 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
1854 | .enable_bit = 7, | ||
1855 | .recalc = &omap2_followparent_recalc, | ||
1856 | }; | ||
1857 | |||
1858 | static struct clk mmchs1_fck = { | ||
1859 | .name = "mmchs1_fck", | ||
1860 | .parent = &func_96m_ck, | ||
1861 | .flags = CLOCK_IN_OMAP243X, | ||
1862 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1863 | .enable_bit = 7, | ||
1864 | .recalc = &omap2_followparent_recalc, | ||
1865 | }; | ||
1866 | |||
1867 | static struct clk mmchs2_ick = { | ||
1868 | .name = "mmchs2_ick", | ||
1869 | .parent = &l4_ck, | ||
1870 | .flags = CLOCK_IN_OMAP243X, | ||
1871 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
1872 | .enable_bit = 8, | ||
1873 | .recalc = &omap2_followparent_recalc, | ||
1874 | }; | ||
1875 | |||
1876 | static struct clk mmchs2_fck = { | ||
1877 | .name = "mmchs2_fck", | ||
1878 | .parent = &func_96m_ck, | ||
1879 | .flags = CLOCK_IN_OMAP243X, | ||
1880 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1881 | .enable_bit = 8, | ||
1882 | .recalc = &omap2_followparent_recalc, | ||
1883 | }; | ||
1884 | |||
1885 | static struct clk gpio5_ick = { | ||
1886 | .name = "gpio5_ick", | ||
1887 | .parent = &l4_ck, | ||
1888 | .flags = CLOCK_IN_OMAP243X, | ||
1889 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
1890 | .enable_bit = 10, | ||
1891 | .recalc = &omap2_followparent_recalc, | ||
1892 | }; | ||
1893 | |||
1894 | static struct clk gpio5_fck = { | ||
1895 | .name = "gpio5_fck", | ||
1896 | .parent = &func_32k_ck, | ||
1897 | .flags = CLOCK_IN_OMAP243X, | ||
1898 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1899 | .enable_bit = 10, | ||
1900 | .recalc = &omap2_followparent_recalc, | ||
1901 | }; | ||
1902 | |||
1903 | static struct clk mdm_intc_ick = { | ||
1904 | .name = "mdm_intc_ick", | ||
1905 | .parent = &l4_ck, | ||
1906 | .flags = CLOCK_IN_OMAP243X, | ||
1907 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | ||
1908 | .enable_bit = 11, | ||
1909 | .recalc = &omap2_followparent_recalc, | ||
1910 | }; | ||
1911 | |||
1912 | static struct clk mmchsdb1_fck = { | ||
1913 | .name = "mmchsdb1_fck", | ||
1914 | .parent = &func_32k_ck, | ||
1915 | .flags = CLOCK_IN_OMAP243X, | ||
1916 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1917 | .enable_bit = 16, | ||
1918 | .recalc = &omap2_followparent_recalc, | ||
1919 | }; | ||
1920 | |||
1921 | static struct clk mmchsdb2_fck = { | ||
1922 | .name = "mmchsdb2_fck", | ||
1923 | .parent = &func_32k_ck, | ||
1924 | .flags = CLOCK_IN_OMAP243X, | ||
1925 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | ||
1926 | .enable_bit = 17, | ||
1927 | .recalc = &omap2_followparent_recalc, | ||
1928 | }; | ||
1929 | |||
1930 | /* | ||
1931 | * This clock is a composite clock which does entire set changes then | ||
1932 | * forces a rebalance. It keys on the MPU speed, but it really could | ||
1933 | * be any key speed part of a set in the rate table. | ||
1934 | * | ||
1935 | * to really change a set, you need memory table sets which get changed | ||
1936 | * in sram, pre-notifiers & post notifiers, changing the top set, without | ||
1937 | * having low level display recalc's won't work... this is why dpm notifiers | ||
1938 | * work, isr's off, walk a list of clocks already _off_ and not messing with | ||
1939 | * the bus. | ||
1940 | * | ||
1941 | * This clock should have no parent. It embodies the entire upper level | ||
1942 | * active set. A parent will mess up some of the init also. | ||
1943 | */ | ||
1944 | static struct clk virt_prcm_set = { | ||
1945 | .name = "virt_prcm_set", | ||
1946 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | ||
1947 | VIRTUAL_CLOCK | ALWAYS_ENABLED | DELAYED_APP, | ||
1948 | .parent = &mpu_ck, /* Indexed by mpu speed, no parent */ | ||
1949 | .recalc = &omap2_mpu_recalc, /* sets are keyed on mpu rate */ | ||
1950 | .set_rate = &omap2_select_table_rate, | ||
1951 | .round_rate = &omap2_round_to_table_rate, | ||
1952 | }; | ||
1953 | |||
1954 | static struct clk *onchip_clks[] = { | ||
1955 | /* external root sources */ | ||
1956 | &func_32k_ck, | ||
1957 | &osc_ck, | ||
1958 | &sys_ck, | ||
1959 | &alt_ck, | ||
1960 | /* internal analog sources */ | ||
1961 | &dpll_ck, | ||
1962 | &apll96_ck, | ||
1963 | &apll54_ck, | ||
1964 | /* internal prcm root sources */ | ||
1965 | &func_54m_ck, | ||
1966 | &core_ck, | ||
1967 | &sleep_ck, | ||
1968 | &func_96m_ck, | ||
1969 | &func_48m_ck, | ||
1970 | &func_12m_ck, | ||
1971 | &wdt1_osc_ck, | ||
1972 | &sys_clkout, | ||
1973 | &sys_clkout2, | ||
1974 | /* mpu domain clocks */ | ||
1975 | &mpu_ck, | ||
1976 | /* dsp domain clocks */ | ||
1977 | &iva2_1_fck, /* 2430 */ | ||
1978 | &iva2_1_ick, | ||
1979 | &dsp_ick, /* 2420 */ | ||
1980 | &dsp_fck, | ||
1981 | &iva1_ifck, | ||
1982 | &iva1_mpu_int_ifck, | ||
1983 | /* GFX domain clocks */ | ||
1984 | &gfx_3d_fck, | ||
1985 | &gfx_2d_fck, | ||
1986 | &gfx_ick, | ||
1987 | /* Modem domain clocks */ | ||
1988 | &mdm_ick, | ||
1989 | &mdm_osc_ck, | ||
1990 | /* DSS domain clocks */ | ||
1991 | &dss_ick, | ||
1992 | &dss1_fck, | ||
1993 | &dss2_fck, | ||
1994 | &dss_54m_fck, | ||
1995 | /* L3 domain clocks */ | ||
1996 | &core_l3_ck, | ||
1997 | &ssi_ssr_sst_fck, | ||
1998 | &usb_l4_ick, | ||
1999 | /* L4 domain clocks */ | ||
2000 | &l4_ck, /* used as both core_l4 and wu_l4 */ | ||
2001 | &ssi_l4_ick, | ||
2002 | /* virtual meta-group clock */ | ||
2003 | &virt_prcm_set, | ||
2004 | /* general l4 interface ck, multi-parent functional clk */ | ||
2005 | &gpt1_ick, | ||
2006 | &gpt1_fck, | ||
2007 | &gpt2_ick, | ||
2008 | &gpt2_fck, | ||
2009 | &gpt3_ick, | ||
2010 | &gpt3_fck, | ||
2011 | &gpt4_ick, | ||
2012 | &gpt4_fck, | ||
2013 | &gpt5_ick, | ||
2014 | &gpt5_fck, | ||
2015 | &gpt6_ick, | ||
2016 | &gpt6_fck, | ||
2017 | &gpt7_ick, | ||
2018 | &gpt7_fck, | ||
2019 | &gpt8_ick, | ||
2020 | &gpt8_fck, | ||
2021 | &gpt9_ick, | ||
2022 | &gpt9_fck, | ||
2023 | &gpt10_ick, | ||
2024 | &gpt10_fck, | ||
2025 | &gpt11_ick, | ||
2026 | &gpt11_fck, | ||
2027 | &gpt12_ick, | ||
2028 | &gpt12_fck, | ||
2029 | &mcbsp1_ick, | ||
2030 | &mcbsp1_fck, | ||
2031 | &mcbsp2_ick, | ||
2032 | &mcbsp2_fck, | ||
2033 | &mcbsp3_ick, | ||
2034 | &mcbsp3_fck, | ||
2035 | &mcbsp4_ick, | ||
2036 | &mcbsp4_fck, | ||
2037 | &mcbsp5_ick, | ||
2038 | &mcbsp5_fck, | ||
2039 | &mcspi1_ick, | ||
2040 | &mcspi1_fck, | ||
2041 | &mcspi2_ick, | ||
2042 | &mcspi2_fck, | ||
2043 | &mcspi3_ick, | ||
2044 | &mcspi3_fck, | ||
2045 | &uart1_ick, | ||
2046 | &uart1_fck, | ||
2047 | &uart2_ick, | ||
2048 | &uart2_fck, | ||
2049 | &uart3_ick, | ||
2050 | &uart3_fck, | ||
2051 | &gpios_ick, | ||
2052 | &gpios_fck, | ||
2053 | &mpu_wdt_ick, | ||
2054 | &mpu_wdt_fck, | ||
2055 | &sync_32k_ick, | ||
2056 | &wdt1_ick, | ||
2057 | &omapctrl_ick, | ||
2058 | &icr_ick, | ||
2059 | &cam_fck, | ||
2060 | &cam_ick, | ||
2061 | &mailboxes_ick, | ||
2062 | &wdt4_ick, | ||
2063 | &wdt4_fck, | ||
2064 | &wdt3_ick, | ||
2065 | &wdt3_fck, | ||
2066 | &mspro_ick, | ||
2067 | &mspro_fck, | ||
2068 | &mmc_ick, | ||
2069 | &mmc_fck, | ||
2070 | &fac_ick, | ||
2071 | &fac_fck, | ||
2072 | &eac_ick, | ||
2073 | &eac_fck, | ||
2074 | &hdq_ick, | ||
2075 | &hdq_fck, | ||
2076 | &i2c1_ick, | ||
2077 | &i2c1_fck, | ||
2078 | &i2chs1_fck, | ||
2079 | &i2c2_ick, | ||
2080 | &i2c2_fck, | ||
2081 | &i2chs2_fck, | ||
2082 | &vlynq_ick, | ||
2083 | &vlynq_fck, | ||
2084 | &sdrc_ick, | ||
2085 | &des_ick, | ||
2086 | &sha_ick, | ||
2087 | &rng_ick, | ||
2088 | &aes_ick, | ||
2089 | &pka_ick, | ||
2090 | &usb_fck, | ||
2091 | &usbhs_ick, | ||
2092 | &mmchs1_ick, | ||
2093 | &mmchs1_fck, | ||
2094 | &mmchs2_ick, | ||
2095 | &mmchs2_fck, | ||
2096 | &gpio5_ick, | ||
2097 | &gpio5_fck, | ||
2098 | &mdm_intc_ick, | ||
2099 | &mmchsdb1_fck, | ||
2100 | &mmchsdb2_fck, | ||
2101 | }; | ||
2102 | |||
2103 | #endif | ||
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c new file mode 100644 index 000000000000..7181edb89352 --- /dev/null +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -0,0 +1,89 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/devices.c | ||
3 | * | ||
4 | * OMAP2 platform device setup/initialization | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include <asm/hardware.h> | ||
19 | #include <asm/io.h> | ||
20 | #include <asm/mach-types.h> | ||
21 | #include <asm/mach/map.h> | ||
22 | |||
23 | #include <asm/arch/tc.h> | ||
24 | #include <asm/arch/board.h> | ||
25 | #include <asm/arch/mux.h> | ||
26 | #include <asm/arch/gpio.h> | ||
27 | |||
28 | extern void omap_nop_release(struct device *dev); | ||
29 | |||
30 | /*-------------------------------------------------------------------------*/ | ||
31 | |||
32 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) | ||
33 | |||
34 | #define OMAP2_I2C_BASE2 0x48072000 | ||
35 | #define OMAP2_I2C_INT2 57 | ||
36 | |||
37 | static struct resource i2c_resources2[] = { | ||
38 | { | ||
39 | .start = OMAP2_I2C_BASE2, | ||
40 | .end = OMAP2_I2C_BASE2 + 0x3f, | ||
41 | .flags = IORESOURCE_MEM, | ||
42 | }, | ||
43 | { | ||
44 | .start = OMAP2_I2C_INT2, | ||
45 | .flags = IORESOURCE_IRQ, | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | static struct platform_device omap_i2c_device2 = { | ||
50 | .name = "i2c_omap", | ||
51 | .id = 2, | ||
52 | .dev = { | ||
53 | .release = omap_nop_release, | ||
54 | }, | ||
55 | .num_resources = ARRAY_SIZE(i2c_resources2), | ||
56 | .resource = i2c_resources2, | ||
57 | }; | ||
58 | |||
59 | /* See also arch/arm/plat-omap/devices.c for first I2C on 24xx */ | ||
60 | static void omap_init_i2c(void) | ||
61 | { | ||
62 | /* REVISIT: Second I2C not in use on H4? */ | ||
63 | if (machine_is_omap_h4()) | ||
64 | return; | ||
65 | |||
66 | omap_cfg_reg(J15_24XX_I2C2_SCL); | ||
67 | omap_cfg_reg(H19_24XX_I2C2_SDA); | ||
68 | (void) platform_device_register(&omap_i2c_device2); | ||
69 | } | ||
70 | |||
71 | #else | ||
72 | |||
73 | static void omap_init_i2c(void) {} | ||
74 | |||
75 | #endif | ||
76 | |||
77 | /*-------------------------------------------------------------------------*/ | ||
78 | |||
79 | static int __init omap2_init_devices(void) | ||
80 | { | ||
81 | /* please keep these calls, and their implementations above, | ||
82 | * in alphabetical order so they're easier to sort through. | ||
83 | */ | ||
84 | omap_init_i2c(); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | arch_initcall(omap2_init_devices); | ||
89 | |||
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c new file mode 100644 index 000000000000..76187300f2b6 --- /dev/null +++ b/arch/arm/mach-omap2/id.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/id.c | ||
3 | * | ||
4 | * OMAP2 CPU identification code | ||
5 | * | ||
6 | * Copyright (C) 2005 Nokia Corporation | ||
7 | * Written by Tony Lindgren <tony@atomide.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | |||
19 | #include <asm/io.h> | ||
20 | |||
21 | #define OMAP24XX_TAP_BASE io_p2v(0x48014000) | ||
22 | |||
23 | #define OMAP_TAP_IDCODE 0x0204 | ||
24 | #define OMAP_TAP_PROD_ID 0x0208 | ||
25 | |||
26 | #define OMAP_TAP_DIE_ID_0 0x0218 | ||
27 | #define OMAP_TAP_DIE_ID_1 0x021C | ||
28 | #define OMAP_TAP_DIE_ID_2 0x0220 | ||
29 | #define OMAP_TAP_DIE_ID_3 0x0224 | ||
30 | |||
31 | /* system_rev fields for OMAP2 processors: | ||
32 | * CPU id bits [31:16], | ||
33 | * CPU device type [15:12], (unprg,normal,POP) | ||
34 | * CPU revision [11:08] | ||
35 | * CPU class bits [07:00] | ||
36 | */ | ||
37 | |||
38 | struct omap_id { | ||
39 | u16 hawkeye; /* Silicon type (Hawkeye id) */ | ||
40 | u8 dev; /* Device type from production_id reg */ | ||
41 | u32 type; /* combined type id copied to system_rev */ | ||
42 | }; | ||
43 | |||
44 | /* Register values to detect the OMAP version */ | ||
45 | static struct omap_id omap_ids[] __initdata = { | ||
46 | { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200000 }, | ||
47 | { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201000 }, | ||
48 | { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202000 }, | ||
49 | { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220000 }, | ||
50 | { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230000 }, | ||
51 | { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 }, | ||
52 | }; | ||
53 | |||
54 | static u32 __init read_tap_reg(int reg) | ||
55 | { | ||
56 | return __raw_readl(OMAP24XX_TAP_BASE + reg); | ||
57 | } | ||
58 | |||
59 | void __init omap2_check_revision(void) | ||
60 | { | ||
61 | int i, j; | ||
62 | u32 idcode; | ||
63 | u32 prod_id; | ||
64 | u16 hawkeye; | ||
65 | u8 dev_type; | ||
66 | u8 rev; | ||
67 | |||
68 | idcode = read_tap_reg(OMAP_TAP_IDCODE); | ||
69 | prod_id = read_tap_reg(OMAP_TAP_PROD_ID); | ||
70 | hawkeye = (idcode >> 12) & 0xffff; | ||
71 | rev = (idcode >> 28) & 0x0f; | ||
72 | dev_type = (prod_id >> 16) & 0x0f; | ||
73 | |||
74 | #ifdef DEBUG | ||
75 | printk(KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", | ||
76 | idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); | ||
77 | printk(KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n", | ||
78 | read_tap_reg(OMAP_TAP_DIE_ID_0)); | ||
79 | printk(KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", | ||
80 | read_tap_reg(OMAP_TAP_DIE_ID_1), | ||
81 | (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf); | ||
82 | printk(KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n", | ||
83 | read_tap_reg(OMAP_TAP_DIE_ID_2)); | ||
84 | printk(KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n", | ||
85 | read_tap_reg(OMAP_TAP_DIE_ID_3)); | ||
86 | printk(KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", | ||
87 | prod_id, dev_type); | ||
88 | #endif | ||
89 | |||
90 | /* Check hawkeye ids */ | ||
91 | for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { | ||
92 | if (hawkeye == omap_ids[i].hawkeye) | ||
93 | break; | ||
94 | } | ||
95 | |||
96 | if (i == ARRAY_SIZE(omap_ids)) { | ||
97 | printk(KERN_ERR "Unknown OMAP CPU id\n"); | ||
98 | return; | ||
99 | } | ||
100 | |||
101 | for (j = i; j < ARRAY_SIZE(omap_ids); j++) { | ||
102 | if (dev_type == omap_ids[j].dev) | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | if (j == ARRAY_SIZE(omap_ids)) { | ||
107 | printk(KERN_ERR "Unknown OMAP device type. " | ||
108 | "Handling it as OMAP%04x\n", | ||
109 | omap_ids[i].type >> 16); | ||
110 | j = i; | ||
111 | } | ||
112 | system_rev = omap_ids[j].type; | ||
113 | |||
114 | system_rev |= rev << 8; | ||
115 | |||
116 | /* Add the cpu class info (24xx) */ | ||
117 | system_rev |= 0x24; | ||
118 | |||
119 | pr_info("OMAP%04x", system_rev >> 16); | ||
120 | if ((system_rev >> 8) & 0x0f) | ||
121 | printk("%x", (system_rev >> 8) & 0x0f); | ||
122 | printk("\n"); | ||
123 | } | ||
124 | |||
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c new file mode 100644 index 000000000000..8ea67bf196a5 --- /dev/null +++ b/arch/arm/mach-omap2/io.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/io.c | ||
3 | * | ||
4 | * OMAP2 I/O mapping code | ||
5 | * | ||
6 | * Copyright (C) 2005 Nokia Corporation | ||
7 | * Author: Juha Yrjölä <juha.yrjola@nokia.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | |||
19 | #include <asm/mach/map.h> | ||
20 | #include <asm/io.h> | ||
21 | #include <asm/arch/mux.h> | ||
22 | |||
23 | extern void omap_sram_init(void); | ||
24 | extern int omap2_clk_init(void); | ||
25 | extern void omap2_check_revision(void); | ||
26 | |||
27 | /* | ||
28 | * The machine specific code may provide the extra mapping besides the | ||
29 | * default mapping provided here. | ||
30 | */ | ||
31 | static struct map_desc omap2_io_desc[] __initdata = { | ||
32 | { | ||
33 | .virtual = L3_24XX_VIRT, | ||
34 | .pfn = __phys_to_pfn(L3_24XX_PHYS), | ||
35 | .length = L3_24XX_SIZE, | ||
36 | .type = MT_DEVICE | ||
37 | }, | ||
38 | { | ||
39 | .virtual = L4_24XX_VIRT, | ||
40 | .pfn = __phys_to_pfn(L4_24XX_PHYS), | ||
41 | .length = L4_24XX_SIZE, | ||
42 | .type = MT_DEVICE | ||
43 | } | ||
44 | }; | ||
45 | |||
46 | void __init omap_map_common_io(void) | ||
47 | { | ||
48 | iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc)); | ||
49 | omap2_check_revision(); | ||
50 | omap_sram_init(); | ||
51 | omap2_mux_init(); | ||
52 | omap2_clk_init(); | ||
53 | } | ||
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c new file mode 100644 index 000000000000..d7baff675cfe --- /dev/null +++ b/arch/arm/mach-omap2/irq.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap/omap2/irq.c | ||
3 | * | ||
4 | * Interrupt handler for OMAP2 boards. | ||
5 | * | ||
6 | * Copyright (C) 2005 Nokia Corporation | ||
7 | * Author: Paul Mundt <paul.mundt@nokia.com> | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file "COPYING" in the main directory of this archive | ||
11 | * for more details. | ||
12 | */ | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/config.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <asm/hardware.h> | ||
18 | #include <asm/mach/irq.h> | ||
19 | #include <asm/irq.h> | ||
20 | #include <asm/io.h> | ||
21 | |||
22 | #define INTC_REVISION 0x0000 | ||
23 | #define INTC_SYSCONFIG 0x0010 | ||
24 | #define INTC_SYSSTATUS 0x0014 | ||
25 | #define INTC_CONTROL 0x0048 | ||
26 | #define INTC_MIR_CLEAR0 0x0088 | ||
27 | #define INTC_MIR_SET0 0x008c | ||
28 | |||
29 | /* | ||
30 | * OMAP2 has a number of different interrupt controllers, each interrupt | ||
31 | * controller is identified as its own "bank". Register definitions are | ||
32 | * fairly consistent for each bank, but not all registers are implemented | ||
33 | * for each bank.. when in doubt, consult the TRM. | ||
34 | */ | ||
35 | static struct omap_irq_bank { | ||
36 | unsigned long base_reg; | ||
37 | unsigned int nr_irqs; | ||
38 | } __attribute__ ((aligned(4))) irq_banks[] = { | ||
39 | { | ||
40 | /* MPU INTC */ | ||
41 | .base_reg = OMAP24XX_IC_BASE, | ||
42 | .nr_irqs = 96, | ||
43 | }, { | ||
44 | /* XXX: DSP INTC */ | ||
45 | |||
46 | #if 0 | ||
47 | /* | ||
48 | * Commented out for now until we fix the IVA clocking | ||
49 | */ | ||
50 | #ifdef CONFIG_ARCH_OMAP2420 | ||
51 | }, { | ||
52 | /* IVA INTC (2420 only) */ | ||
53 | .base_reg = OMAP24XX_IVA_INTC_BASE, | ||
54 | .nr_irqs = 16, /* Actually 32, but only 16 are used */ | ||
55 | #endif | ||
56 | #endif | ||
57 | } | ||
58 | }; | ||
59 | |||
60 | /* XXX: FIQ and additional INTC support (only MPU at the moment) */ | ||
61 | static void omap_ack_irq(unsigned int irq) | ||
62 | { | ||
63 | omap_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL); | ||
64 | } | ||
65 | |||
66 | static void omap_mask_irq(unsigned int irq) | ||
67 | { | ||
68 | int offset = (irq >> 5) << 5; | ||
69 | |||
70 | if (irq >= 64) { | ||
71 | irq %= 64; | ||
72 | } else if (irq >= 32) { | ||
73 | irq %= 32; | ||
74 | } | ||
75 | |||
76 | omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset); | ||
77 | } | ||
78 | |||
79 | static void omap_unmask_irq(unsigned int irq) | ||
80 | { | ||
81 | int offset = (irq >> 5) << 5; | ||
82 | |||
83 | if (irq >= 64) { | ||
84 | irq %= 64; | ||
85 | } else if (irq >= 32) { | ||
86 | irq %= 32; | ||
87 | } | ||
88 | |||
89 | omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset); | ||
90 | } | ||
91 | |||
92 | static void omap_mask_ack_irq(unsigned int irq) | ||
93 | { | ||
94 | omap_mask_irq(irq); | ||
95 | omap_ack_irq(irq); | ||
96 | } | ||
97 | |||
98 | static struct irqchip omap_irq_chip = { | ||
99 | .ack = omap_mask_ack_irq, | ||
100 | .mask = omap_mask_irq, | ||
101 | .unmask = omap_unmask_irq, | ||
102 | }; | ||
103 | |||
104 | static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank) | ||
105 | { | ||
106 | unsigned long tmp; | ||
107 | |||
108 | tmp = omap_readl(bank->base_reg + INTC_REVISION) & 0xff; | ||
109 | printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx " | ||
110 | "(revision %ld.%ld) with %d interrupts\n", | ||
111 | bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs); | ||
112 | |||
113 | tmp = omap_readl(bank->base_reg + INTC_SYSCONFIG); | ||
114 | tmp |= 1 << 1; /* soft reset */ | ||
115 | omap_writel(tmp, bank->base_reg + INTC_SYSCONFIG); | ||
116 | |||
117 | while (!(omap_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1)) | ||
118 | /* Wait for reset to complete */; | ||
119 | } | ||
120 | |||
121 | void __init omap_init_irq(void) | ||
122 | { | ||
123 | unsigned long nr_irqs = 0; | ||
124 | unsigned int nr_banks = 0; | ||
125 | int i; | ||
126 | |||
127 | for (i = 0; i < ARRAY_SIZE(irq_banks); i++) { | ||
128 | struct omap_irq_bank *bank = irq_banks + i; | ||
129 | |||
130 | /* XXX */ | ||
131 | if (!bank->base_reg) | ||
132 | continue; | ||
133 | |||
134 | omap_irq_bank_init_one(bank); | ||
135 | |||
136 | nr_irqs += bank->nr_irqs; | ||
137 | nr_banks++; | ||
138 | } | ||
139 | |||
140 | printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n", | ||
141 | nr_irqs, nr_banks, nr_banks > 1 ? "s" : ""); | ||
142 | |||
143 | for (i = 0; i < nr_irqs; i++) { | ||
144 | set_irq_chip(i, &omap_irq_chip); | ||
145 | set_irq_handler(i, do_level_IRQ); | ||
146 | set_irq_flags(i, IRQF_VALID); | ||
147 | } | ||
148 | } | ||
149 | |||
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c new file mode 100644 index 000000000000..ea4654815dd1 --- /dev/null +++ b/arch/arm/mach-omap2/mux.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/mux.c | ||
3 | * | ||
4 | * OMAP1 pin multiplexing configurations | ||
5 | * | ||
6 | * Copyright (C) 2003 - 2005 Nokia Corporation | ||
7 | * | ||
8 | * Written by Tony Lindgren <tony.lindgren@nokia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/config.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <asm/system.h> | ||
29 | #include <asm/io.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | |||
32 | #include <asm/arch/mux.h> | ||
33 | |||
34 | #ifdef CONFIG_OMAP_MUX | ||
35 | |||
36 | /* NOTE: See mux.h for the enumeration */ | ||
37 | |||
38 | struct pin_config __initdata_or_module omap24xx_pins[] = { | ||
39 | /* | ||
40 | * description mux mux pull pull debug | ||
41 | * offset mode ena type | ||
42 | */ | ||
43 | |||
44 | /* 24xx I2C */ | ||
45 | MUX_CFG_24XX("M19_24XX_I2C1_SCL", 0x111, 0, 0, 0, 1) | ||
46 | MUX_CFG_24XX("L15_24XX_I2C1_SDA", 0x112, 0, 0, 0, 1) | ||
47 | MUX_CFG_24XX("J15_24XX_I2C2_SCL", 0x113, 0, 0, 0, 1) | ||
48 | MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1) | ||
49 | |||
50 | /* Menelaus interrupt */ | ||
51 | MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1) | ||
52 | |||
53 | /* 24xx GPIO */ | ||
54 | MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1) | ||
55 | MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1) | ||
56 | |||
57 | }; | ||
58 | |||
59 | int __init omap2_mux_init(void) | ||
60 | { | ||
61 | omap_mux_register(omap24xx_pins, ARRAY_SIZE(omap24xx_pins)); | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | #endif | ||
diff --git a/arch/arm/mach-omap2/prcm.h b/arch/arm/mach-omap2/prcm.h new file mode 100644 index 000000000000..2eb89b936c83 --- /dev/null +++ b/arch/arm/mach-omap2/prcm.h | |||
@@ -0,0 +1,419 @@ | |||
1 | /* | ||
2 | * prcm.h - Access definations for use in OMAP24XX clock and power management | ||
3 | * | ||
4 | * Copyright (C) 2005 Texas Instruments, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef __ASM_ARM_ARCH_DPM_PRCM_H | ||
22 | #define __ASM_ARM_ARCH_DPM_PRCM_H | ||
23 | |||
24 | /* SET_PERFORMANCE_LEVEL PARAMETERS */ | ||
25 | #define PRCM_HALF_SPEED 1 | ||
26 | #define PRCM_FULL_SPEED 2 | ||
27 | |||
28 | #ifndef __ASSEMBLER__ | ||
29 | |||
30 | #define PRCM_REG32(offset) __REG32(OMAP24XX_PRCM_BASE + (offset)) | ||
31 | |||
32 | #define PRCM_REVISION PRCM_REG32(0x000) | ||
33 | #define PRCM_SYSCONFIG PRCM_REG32(0x010) | ||
34 | #define PRCM_IRQSTATUS_MPU PRCM_REG32(0x018) | ||
35 | #define PRCM_IRQENABLE_MPU PRCM_REG32(0x01C) | ||
36 | #define PRCM_VOLTCTRL PRCM_REG32(0x050) | ||
37 | #define PRCM_VOLTST PRCM_REG32(0x054) | ||
38 | #define PRCM_CLKSRC_CTRL PRCM_REG32(0x060) | ||
39 | #define PRCM_CLKOUT_CTRL PRCM_REG32(0x070) | ||
40 | #define PRCM_CLKEMUL_CTRL PRCM_REG32(0x078) | ||
41 | #define PRCM_CLKCFG_CTRL PRCM_REG32(0x080) | ||
42 | #define PRCM_CLKCFG_STATUS PRCM_REG32(0x084) | ||
43 | #define PRCM_VOLTSETUP PRCM_REG32(0x090) | ||
44 | #define PRCM_CLKSSETUP PRCM_REG32(0x094) | ||
45 | #define PRCM_POLCTRL PRCM_REG32(0x098) | ||
46 | |||
47 | /* GENERAL PURPOSE */ | ||
48 | #define GENERAL_PURPOSE1 PRCM_REG32(0x0B0) | ||
49 | #define GENERAL_PURPOSE2 PRCM_REG32(0x0B4) | ||
50 | #define GENERAL_PURPOSE3 PRCM_REG32(0x0B8) | ||
51 | #define GENERAL_PURPOSE4 PRCM_REG32(0x0BC) | ||
52 | #define GENERAL_PURPOSE5 PRCM_REG32(0x0C0) | ||
53 | #define GENERAL_PURPOSE6 PRCM_REG32(0x0C4) | ||
54 | #define GENERAL_PURPOSE7 PRCM_REG32(0x0C8) | ||
55 | #define GENERAL_PURPOSE8 PRCM_REG32(0x0CC) | ||
56 | #define GENERAL_PURPOSE9 PRCM_REG32(0x0D0) | ||
57 | #define GENERAL_PURPOSE10 PRCM_REG32(0x0D4) | ||
58 | #define GENERAL_PURPOSE11 PRCM_REG32(0x0D8) | ||
59 | #define GENERAL_PURPOSE12 PRCM_REG32(0x0DC) | ||
60 | #define GENERAL_PURPOSE13 PRCM_REG32(0x0E0) | ||
61 | #define GENERAL_PURPOSE14 PRCM_REG32(0x0E4) | ||
62 | #define GENERAL_PURPOSE15 PRCM_REG32(0x0E8) | ||
63 | #define GENERAL_PURPOSE16 PRCM_REG32(0x0EC) | ||
64 | #define GENERAL_PURPOSE17 PRCM_REG32(0x0F0) | ||
65 | #define GENERAL_PURPOSE18 PRCM_REG32(0x0F4) | ||
66 | #define GENERAL_PURPOSE19 PRCM_REG32(0x0F8) | ||
67 | #define GENERAL_PURPOSE20 PRCM_REG32(0x0FC) | ||
68 | |||
69 | /* MPU */ | ||
70 | #define CM_CLKSEL_MPU PRCM_REG32(0x140) | ||
71 | #define CM_CLKSTCTRL_MPU PRCM_REG32(0x148) | ||
72 | #define RM_RSTST_MPU PRCM_REG32(0x158) | ||
73 | #define PM_WKDEP_MPU PRCM_REG32(0x1C8) | ||
74 | #define PM_EVGENCTRL_MPU PRCM_REG32(0x1D4) | ||
75 | #define PM_EVEGENONTIM_MPU PRCM_REG32(0x1D8) | ||
76 | #define PM_EVEGENOFFTIM_MPU PRCM_REG32(0x1DC) | ||
77 | #define PM_PWSTCTRL_MPU PRCM_REG32(0x1E0) | ||
78 | #define PM_PWSTST_MPU PRCM_REG32(0x1E4) | ||
79 | |||
80 | /* CORE */ | ||
81 | #define CM_FCLKEN1_CORE PRCM_REG32(0x200) | ||
82 | #define CM_FCLKEN2_CORE PRCM_REG32(0x204) | ||
83 | #define CM_FCLKEN3_CORE PRCM_REG32(0x208) | ||
84 | #define CM_ICLKEN1_CORE PRCM_REG32(0x210) | ||
85 | #define CM_ICLKEN2_CORE PRCM_REG32(0x214) | ||
86 | #define CM_ICLKEN3_CORE PRCM_REG32(0x218) | ||
87 | #define CM_ICLKEN4_CORE PRCM_REG32(0x21C) | ||
88 | #define CM_IDLEST1_CORE PRCM_REG32(0x220) | ||
89 | #define CM_IDLEST2_CORE PRCM_REG32(0x224) | ||
90 | #define CM_IDLEST3_CORE PRCM_REG32(0x228) | ||
91 | #define CM_IDLEST4_CORE PRCM_REG32(0x22C) | ||
92 | #define CM_AUTOIDLE1_CORE PRCM_REG32(0x230) | ||
93 | #define CM_AUTOIDLE2_CORE PRCM_REG32(0x234) | ||
94 | #define CM_AUTOIDLE3_CORE PRCM_REG32(0x238) | ||
95 | #define CM_AUTOIDLE4_CORE PRCM_REG32(0x23C) | ||
96 | #define CM_CLKSEL1_CORE PRCM_REG32(0x240) | ||
97 | #define CM_CLKSEL2_CORE PRCM_REG32(0x244) | ||
98 | #define CM_CLKSTCTRL_CORE PRCM_REG32(0x248) | ||
99 | #define PM_WKEN1_CORE PRCM_REG32(0x2A0) | ||
100 | #define PM_WKEN2_CORE PRCM_REG32(0x2A4) | ||
101 | #define PM_WKST1_CORE PRCM_REG32(0x2B0) | ||
102 | #define PM_WKST2_CORE PRCM_REG32(0x2B4) | ||
103 | #define PM_WKDEP_CORE PRCM_REG32(0x2C8) | ||
104 | #define PM_PWSTCTRL_CORE PRCM_REG32(0x2E0) | ||
105 | #define PM_PWSTST_CORE PRCM_REG32(0x2E4) | ||
106 | |||
107 | /* GFX */ | ||
108 | #define CM_FCLKEN_GFX PRCM_REG32(0x300) | ||
109 | #define CM_ICLKEN_GFX PRCM_REG32(0x310) | ||
110 | #define CM_IDLEST_GFX PRCM_REG32(0x320) | ||
111 | #define CM_CLKSEL_GFX PRCM_REG32(0x340) | ||
112 | #define CM_CLKSTCTRL_GFX PRCM_REG32(0x348) | ||
113 | #define RM_RSTCTRL_GFX PRCM_REG32(0x350) | ||
114 | #define RM_RSTST_GFX PRCM_REG32(0x358) | ||
115 | #define PM_WKDEP_GFX PRCM_REG32(0x3C8) | ||
116 | #define PM_PWSTCTRL_GFX PRCM_REG32(0x3E0) | ||
117 | #define PM_PWSTST_GFX PRCM_REG32(0x3E4) | ||
118 | |||
119 | /* WAKE-UP */ | ||
120 | #define CM_FCLKEN_WKUP PRCM_REG32(0x400) | ||
121 | #define CM_ICLKEN_WKUP PRCM_REG32(0x410) | ||
122 | #define CM_IDLEST_WKUP PRCM_REG32(0x420) | ||
123 | #define CM_AUTOIDLE_WKUP PRCM_REG32(0x430) | ||
124 | #define CM_CLKSEL_WKUP PRCM_REG32(0x440) | ||
125 | #define RM_RSTCTRL_WKUP PRCM_REG32(0x450) | ||
126 | #define RM_RSTTIME_WKUP PRCM_REG32(0x454) | ||
127 | #define RM_RSTST_WKUP PRCM_REG32(0x458) | ||
128 | #define PM_WKEN_WKUP PRCM_REG32(0x4A0) | ||
129 | #define PM_WKST_WKUP PRCM_REG32(0x4B0) | ||
130 | |||
131 | /* CLOCKS */ | ||
132 | #define CM_CLKEN_PLL PRCM_REG32(0x500) | ||
133 | #define CM_IDLEST_CKGEN PRCM_REG32(0x520) | ||
134 | #define CM_AUTOIDLE_PLL PRCM_REG32(0x530) | ||
135 | #define CM_CLKSEL1_PLL PRCM_REG32(0x540) | ||
136 | #define CM_CLKSEL2_PLL PRCM_REG32(0x544) | ||
137 | |||
138 | /* DSP */ | ||
139 | #define CM_FCLKEN_DSP PRCM_REG32(0x800) | ||
140 | #define CM_ICLKEN_DSP PRCM_REG32(0x810) | ||
141 | #define CM_IDLEST_DSP PRCM_REG32(0x820) | ||
142 | #define CM_AUTOIDLE_DSP PRCM_REG32(0x830) | ||
143 | #define CM_CLKSEL_DSP PRCM_REG32(0x840) | ||
144 | #define CM_CLKSTCTRL_DSP PRCM_REG32(0x848) | ||
145 | #define RM_RSTCTRL_DSP PRCM_REG32(0x850) | ||
146 | #define RM_RSTST_DSP PRCM_REG32(0x858) | ||
147 | #define PM_WKEN_DSP PRCM_REG32(0x8A0) | ||
148 | #define PM_WKDEP_DSP PRCM_REG32(0x8C8) | ||
149 | #define PM_PWSTCTRL_DSP PRCM_REG32(0x8E0) | ||
150 | #define PM_PWSTST_DSP PRCM_REG32(0x8E4) | ||
151 | #define PRCM_IRQSTATUS_DSP PRCM_REG32(0x8F0) | ||
152 | #define PRCM_IRQENABLE_DSP PRCM_REG32(0x8F4) | ||
153 | |||
154 | /* IVA */ | ||
155 | #define PRCM_IRQSTATUS_IVA PRCM_REG32(0x8F8) | ||
156 | #define PRCM_IRQENABLE_IVA PRCM_REG32(0x8FC) | ||
157 | |||
158 | /* Modem on 2430 */ | ||
159 | #define CM_FCLKEN_MDM PRCM_REG32(0xC00) | ||
160 | #define CM_ICLKEN_MDM PRCM_REG32(0xC10) | ||
161 | #define CM_IDLEST_MDM PRCM_REG32(0xC20) | ||
162 | #define CM_CLKSEL_MDM PRCM_REG32(0xC40) | ||
163 | |||
164 | /* FIXME: Move to header for 2430 */ | ||
165 | #define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000) | ||
166 | #define DISP_REG32(offset) __REG32(DISP_BASE + (offset)) | ||
167 | |||
168 | #define GPMC_BASE (OMAP24XX_GPMC_BASE) | ||
169 | #define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset)) | ||
170 | |||
171 | #define GPT1_BASE (OMAP24XX_GPT1) | ||
172 | #define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset)) | ||
173 | |||
174 | /* Misc sysconfig */ | ||
175 | #define DISPC_SYSCONFIG DISP_REG32(0x410) | ||
176 | #define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000) | ||
177 | #define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10) | ||
178 | #define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10) | ||
179 | |||
180 | //#define DSP_MMU_SYSCONFIG 0x5A000010 | ||
181 | #define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10) | ||
182 | //#define IVA_MMU_SYSCONFIG 0x5D000010 | ||
183 | //#define DSP_DMA_SYSCONFIG 0x00FCC02C | ||
184 | #define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C) | ||
185 | #define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C) | ||
186 | #define GPMC_SYSCONFIG GPMC_REG32(0x010) | ||
187 | #define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010) | ||
188 | #define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054) | ||
189 | #define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054) | ||
190 | #define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054) | ||
191 | //#define IVA_SYSCONFIG 0x5C060010 | ||
192 | #define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10) | ||
193 | #define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10) | ||
194 | #define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010) | ||
195 | //#define VLYNQ_SYSCONFIG 0x67FFFE10 | ||
196 | |||
197 | /* rkw - good cannidates for PM_ to start what nm was trying */ | ||
198 | #define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000) | ||
199 | #define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000) | ||
200 | #define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000) | ||
201 | #define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000) | ||
202 | #define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000) | ||
203 | #define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000) | ||
204 | #define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000) | ||
205 | #define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000) | ||
206 | #define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000) | ||
207 | #define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000) | ||
208 | #define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000) | ||
209 | |||
210 | #define GPTIMER1_SYSCONFIG GPT1_REG32(0x010) | ||
211 | #define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10) | ||
212 | #define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10) | ||
213 | #define GPTIMER4_SYSCONFIG __REG32(OMAP24XX_GPT4 + 0x10) | ||
214 | #define GPTIMER5_SYSCONFIG __REG32(OMAP24XX_GPT5 + 0x10) | ||
215 | #define GPTIMER6_SYSCONFIG __REG32(OMAP24XX_GPT6 + 0x10) | ||
216 | #define GPTIMER7_SYSCONFIG __REG32(OMAP24XX_GPT7 + 0x10) | ||
217 | #define GPTIMER8_SYSCONFIG __REG32(OMAP24XX_GPT8 + 0x10) | ||
218 | #define GPTIMER9_SYSCONFIG __REG32(OMAP24XX_GPT9 + 0x10) | ||
219 | #define GPTIMER10_SYSCONFIG __REG32(OMAP24XX_GPT10 + 0x10) | ||
220 | #define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10) | ||
221 | #define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10) | ||
222 | |||
223 | #define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1))) | ||
224 | |||
225 | #define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10)) | ||
226 | #define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10)) | ||
227 | #define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10)) | ||
228 | #define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10)) | ||
229 | |||
230 | /* GP TIMER 1 */ | ||
231 | #define GPTIMER1_TISTAT GPT1_REG32(0x014) | ||
232 | #define GPTIMER1_TISR GPT1_REG32(0x018) | ||
233 | #define GPTIMER1_TIER GPT1_REG32(0x01C) | ||
234 | #define GPTIMER1_TWER GPT1_REG32(0x020) | ||
235 | #define GPTIMER1_TCLR GPT1_REG32(0x024) | ||
236 | #define GPTIMER1_TCRR GPT1_REG32(0x028) | ||
237 | #define GPTIMER1_TLDR GPT1_REG32(0x02C) | ||
238 | #define GPTIMER1_TTGR GPT1_REG32(0x030) | ||
239 | #define GPTIMER1_TWPS GPT1_REG32(0x034) | ||
240 | #define GPTIMER1_TMAR GPT1_REG32(0x038) | ||
241 | #define GPTIMER1_TCAR1 GPT1_REG32(0x03C) | ||
242 | #define GPTIMER1_TSICR GPT1_REG32(0x040) | ||
243 | #define GPTIMER1_TCAR2 GPT1_REG32(0x044) | ||
244 | |||
245 | /* rkw -- base fix up please... */ | ||
246 | #define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018) | ||
247 | |||
248 | /* SDRC */ | ||
249 | #define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060) | ||
250 | #define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064) | ||
251 | #define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068) | ||
252 | #define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C) | ||
253 | #define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070) | ||
254 | #define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084) | ||
255 | |||
256 | /* GPIO 1 */ | ||
257 | #define GPIO1_BASE GPIOX_BASE(1) | ||
258 | #define GPIO1_REG32(offset) __REG32(GPIO1_BASE + (offset)) | ||
259 | #define GPIO1_IRQENABLE1 GPIO1_REG32(0x01C) | ||
260 | #define GPIO1_IRQSTATUS1 GPIO1_REG32(0x018) | ||
261 | #define GPIO1_IRQENABLE2 GPIO1_REG32(0x02C) | ||
262 | #define GPIO1_IRQSTATUS2 GPIO1_REG32(0x028) | ||
263 | #define GPIO1_WAKEUPENABLE GPIO1_REG32(0x020) | ||
264 | #define GPIO1_RISINGDETECT GPIO1_REG32(0x048) | ||
265 | #define GPIO1_DATAIN GPIO1_REG32(0x038) | ||
266 | #define GPIO1_OE GPIO1_REG32(0x034) | ||
267 | #define GPIO1_DATAOUT GPIO1_REG32(0x03C) | ||
268 | |||
269 | /* GPIO2 */ | ||
270 | #define GPIO2_BASE GPIOX_BASE(2) | ||
271 | #define GPIO2_REG32(offset) __REG32(GPIO2_BASE + (offset)) | ||
272 | #define GPIO2_IRQENABLE1 GPIO2_REG32(0x01C) | ||
273 | #define GPIO2_IRQSTATUS1 GPIO2_REG32(0x018) | ||
274 | #define GPIO2_IRQENABLE2 GPIO2_REG32(0x02C) | ||
275 | #define GPIO2_IRQSTATUS2 GPIO2_REG32(0x028) | ||
276 | #define GPIO2_WAKEUPENABLE GPIO2_REG32(0x020) | ||
277 | #define GPIO2_RISINGDETECT GPIO2_REG32(0x048) | ||
278 | #define GPIO2_DATAIN GPIO2_REG32(0x038) | ||
279 | #define GPIO2_OE GPIO2_REG32(0x034) | ||
280 | #define GPIO2_DATAOUT GPIO2_REG32(0x03C) | ||
281 | |||
282 | /* GPIO 3 */ | ||
283 | #define GPIO3_BASE GPIOX_BASE(3) | ||
284 | #define GPIO3_REG32(offset) __REG32(GPIO3_BASE + (offset)) | ||
285 | #define GPIO3_IRQENABLE1 GPIO3_REG32(0x01C) | ||
286 | #define GPIO3_IRQSTATUS1 GPIO3_REG32(0x018) | ||
287 | #define GPIO3_IRQENABLE2 GPIO3_REG32(0x02C) | ||
288 | #define GPIO3_IRQSTATUS2 GPIO3_REG32(0x028) | ||
289 | #define GPIO3_WAKEUPENABLE GPIO3_REG32(0x020) | ||
290 | #define GPIO3_RISINGDETECT GPIO3_REG32(0x048) | ||
291 | #define GPIO3_FALLINGDETECT GPIO3_REG32(0x04C) | ||
292 | #define GPIO3_DATAIN GPIO3_REG32(0x038) | ||
293 | #define GPIO3_OE GPIO3_REG32(0x034) | ||
294 | #define GPIO3_DATAOUT GPIO3_REG32(0x03C) | ||
295 | #define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050) | ||
296 | #define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054) | ||
297 | |||
298 | /* GPIO 4 */ | ||
299 | #define GPIO4_BASE GPIOX_BASE(4) | ||
300 | #define GPIO4_REG32(offset) __REG32(GPIO4_BASE + (offset)) | ||
301 | #define GPIO4_IRQENABLE1 GPIO4_REG32(0x01C) | ||
302 | #define GPIO4_IRQSTATUS1 GPIO4_REG32(0x018) | ||
303 | #define GPIO4_IRQENABLE2 GPIO4_REG32(0x02C) | ||
304 | #define GPIO4_IRQSTATUS2 GPIO4_REG32(0x028) | ||
305 | #define GPIO4_WAKEUPENABLE GPIO4_REG32(0x020) | ||
306 | #define GPIO4_RISINGDETECT GPIO4_REG32(0x048) | ||
307 | #define GPIO4_FALLINGDETECT GPIO4_REG32(0x04C) | ||
308 | #define GPIO4_DATAIN GPIO4_REG32(0x038) | ||
309 | #define GPIO4_OE GPIO4_REG32(0x034) | ||
310 | #define GPIO4_DATAOUT GPIO4_REG32(0x03C) | ||
311 | #define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050) | ||
312 | #define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054) | ||
313 | |||
314 | |||
315 | /* IO CONFIG */ | ||
316 | #define CONTROL_BASE (OMAP24XX_CTRL_BASE) | ||
317 | #define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset)) | ||
318 | |||
319 | #define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104) | ||
320 | #define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134) | ||
321 | #define CONTROL_PADCONF_UART1_RX CONTROL_REG32(0x0C8) | ||
322 | #define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C) | ||
323 | #define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090) | ||
324 | #define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8) | ||
325 | #define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC) | ||
326 | #define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0) | ||
327 | #define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC) | ||
328 | |||
329 | /* CONTROL */ | ||
330 | #define CONTROL_DEVCONF CONTROL_REG32(0x274) | ||
331 | |||
332 | /* INTERRUPT CONTROLLER */ | ||
333 | #define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000) | ||
334 | #define INTC_REG32(offset) __REG32(INTC_BASE + (offset)) | ||
335 | |||
336 | #define INTC1_U_BASE INTC_REG32(0x000) | ||
337 | #define INTC_MIR0 INTC_REG32(0x084) | ||
338 | #define INTC_MIR_SET0 INTC_REG32(0x08C) | ||
339 | #define INTC_MIR_CLEAR0 INTC_REG32(0x088) | ||
340 | #define INTC_ISR_CLEAR0 INTC_REG32(0x094) | ||
341 | #define INTC_MIR1 INTC_REG32(0x0A4) | ||
342 | #define INTC_MIR_SET1 INTC_REG32(0x0AC) | ||
343 | #define INTC_MIR_CLEAR1 INTC_REG32(0x0A8) | ||
344 | #define INTC_ISR_CLEAR1 INTC_REG32(0x0B4) | ||
345 | #define INTC_MIR2 INTC_REG32(0x0C4) | ||
346 | #define INTC_MIR_SET2 INTC_REG32(0x0CC) | ||
347 | #define INTC_MIR_CLEAR2 INTC_REG32(0x0C8) | ||
348 | #define INTC_ISR_CLEAR2 INTC_REG32(0x0D4) | ||
349 | #define INTC_SIR_IRQ INTC_REG32(0x040) | ||
350 | #define INTC_CONTROL INTC_REG32(0x048) | ||
351 | #define INTC_ILR11 INTC_REG32(0x12C) | ||
352 | #define INTC_ILR32 INTC_REG32(0x180) | ||
353 | #define INTC_ILR37 INTC_REG32(0x194) | ||
354 | #define INTC_SYSCONFIG INTC_REG32(0x010) | ||
355 | |||
356 | /* RAM FIREWALL */ | ||
357 | #define RAMFW_BASE (0x68005000) | ||
358 | #define RAMFW_REG32(offset) __REG32(RAMFW_BASE + (offset)) | ||
359 | |||
360 | #define RAMFW_REQINFOPERM0 RAMFW_REG32(0x048) | ||
361 | #define RAMFW_READPERM0 RAMFW_REG32(0x050) | ||
362 | #define RAMFW_WRITEPERM0 RAMFW_REG32(0x058) | ||
363 | |||
364 | /* GPMC CS1 FPGA ON USER INTERFACE MODULE */ | ||
365 | //#define DEBUG_BOARD_LED_REGISTER 0x04000014 | ||
366 | |||
367 | /* GPMC CS0 */ | ||
368 | #define GPMC_CONFIG1_0 GPMC_REG32(0x060) | ||
369 | #define GPMC_CONFIG2_0 GPMC_REG32(0x064) | ||
370 | #define GPMC_CONFIG3_0 GPMC_REG32(0x068) | ||
371 | #define GPMC_CONFIG4_0 GPMC_REG32(0x06C) | ||
372 | #define GPMC_CONFIG5_0 GPMC_REG32(0x070) | ||
373 | #define GPMC_CONFIG6_0 GPMC_REG32(0x074) | ||
374 | #define GPMC_CONFIG7_0 GPMC_REG32(0x078) | ||
375 | |||
376 | /* DSS */ | ||
377 | #define DSS_CONTROL DISP_REG32(0x040) | ||
378 | #define DISPC_CONTROL DISP_REG32(0x440) | ||
379 | #define DISPC_SYSSTATUS DISP_REG32(0x414) | ||
380 | #define DISPC_IRQSTATUS DISP_REG32(0x418) | ||
381 | #define DISPC_IRQENABLE DISP_REG32(0x41C) | ||
382 | #define DISPC_CONFIG DISP_REG32(0x444) | ||
383 | #define DISPC_DEFAULT_COLOR0 DISP_REG32(0x44C) | ||
384 | #define DISPC_DEFAULT_COLOR1 DISP_REG32(0x450) | ||
385 | #define DISPC_TRANS_COLOR0 DISP_REG32(0x454) | ||
386 | #define DISPC_TRANS_COLOR1 DISP_REG32(0x458) | ||
387 | #define DISPC_LINE_NUMBER DISP_REG32(0x460) | ||
388 | #define DISPC_TIMING_H DISP_REG32(0x464) | ||
389 | #define DISPC_TIMING_V DISP_REG32(0x468) | ||
390 | #define DISPC_POL_FREQ DISP_REG32(0x46C) | ||
391 | #define DISPC_DIVISOR DISP_REG32(0x470) | ||
392 | #define DISPC_SIZE_DIG DISP_REG32(0x478) | ||
393 | #define DISPC_SIZE_LCD DISP_REG32(0x47C) | ||
394 | #define DISPC_GFX_BA0 DISP_REG32(0x480) | ||
395 | #define DISPC_GFX_BA1 DISP_REG32(0x484) | ||
396 | #define DISPC_GFX_POSITION DISP_REG32(0x488) | ||
397 | #define DISPC_GFX_SIZE DISP_REG32(0x48C) | ||
398 | #define DISPC_GFX_ATTRIBUTES DISP_REG32(0x4A0) | ||
399 | #define DISPC_GFX_FIFO_THRESHOLD DISP_REG32(0x4A4) | ||
400 | #define DISPC_GFX_ROW_INC DISP_REG32(0x4AC) | ||
401 | #define DISPC_GFX_PIXEL_INC DISP_REG32(0x4B0) | ||
402 | #define DISPC_GFX_WINDOW_SKIP DISP_REG32(0x4B4) | ||
403 | #define DISPC_GFX_TABLE_BA DISP_REG32(0x4B8) | ||
404 | #define DISPC_DATA_CYCLE1 DISP_REG32(0x5D4) | ||
405 | #define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8) | ||
406 | #define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC) | ||
407 | |||
408 | /* Wake up define for board */ | ||
409 | #define GPIO97 (1 << 1) | ||
410 | #define GPIO88 (1 << 24) | ||
411 | |||
412 | #endif /* __ASSEMBLER__ */ | ||
413 | |||
414 | #endif | ||
415 | |||
416 | |||
417 | |||
418 | |||
419 | |||
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c new file mode 100644 index 000000000000..f4df04fe1dd8 --- /dev/null +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-omap/omap2/serial.c | ||
3 | * | ||
4 | * OMAP2 serial support. | ||
5 | * | ||
6 | * Copyright (C) 2005 Nokia Corporation | ||
7 | * Author: Paul Mundt <paul.mundt@nokia.com> | ||
8 | * | ||
9 | * Based off of arch/arm/mach-omap/omap1/serial.c | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file "COPYING" in the main directory of this archive | ||
13 | * for more details. | ||
14 | */ | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/serial_8250.h> | ||
18 | #include <linux/serial_reg.h> | ||
19 | |||
20 | #include <asm/io.h> | ||
21 | #include <asm/hardware/clock.h> | ||
22 | |||
23 | #include <asm/arch/common.h> | ||
24 | #include <asm/arch/board.h> | ||
25 | |||
26 | static struct clk * uart1_ick = NULL; | ||
27 | static struct clk * uart1_fck = NULL; | ||
28 | static struct clk * uart2_ick = NULL; | ||
29 | static struct clk * uart2_fck = NULL; | ||
30 | static struct clk * uart3_ick = NULL; | ||
31 | static struct clk * uart3_fck = NULL; | ||
32 | |||
33 | static struct plat_serial8250_port serial_platform_data[] = { | ||
34 | { | ||
35 | .membase = (char *)IO_ADDRESS(OMAP_UART1_BASE), | ||
36 | .mapbase = (unsigned long)OMAP_UART1_BASE, | ||
37 | .irq = 72, | ||
38 | .flags = UPF_BOOT_AUTOCONF, | ||
39 | .iotype = UPIO_MEM, | ||
40 | .regshift = 2, | ||
41 | .uartclk = OMAP16XX_BASE_BAUD * 16, | ||
42 | }, { | ||
43 | .membase = (char *)IO_ADDRESS(OMAP_UART2_BASE), | ||
44 | .mapbase = (unsigned long)OMAP_UART2_BASE, | ||
45 | .irq = 73, | ||
46 | .flags = UPF_BOOT_AUTOCONF, | ||
47 | .iotype = UPIO_MEM, | ||
48 | .regshift = 2, | ||
49 | .uartclk = OMAP16XX_BASE_BAUD * 16, | ||
50 | }, { | ||
51 | .membase = (char *)IO_ADDRESS(OMAP_UART3_BASE), | ||
52 | .mapbase = (unsigned long)OMAP_UART3_BASE, | ||
53 | .irq = 74, | ||
54 | .flags = UPF_BOOT_AUTOCONF, | ||
55 | .iotype = UPIO_MEM, | ||
56 | .regshift = 2, | ||
57 | .uartclk = OMAP16XX_BASE_BAUD * 16, | ||
58 | }, { | ||
59 | .flags = 0 | ||
60 | } | ||
61 | }; | ||
62 | |||
63 | static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, | ||
64 | int offset) | ||
65 | { | ||
66 | offset <<= up->regshift; | ||
67 | return (unsigned int)__raw_readb(up->membase + offset); | ||
68 | } | ||
69 | |||
70 | static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, | ||
71 | int value) | ||
72 | { | ||
73 | offset <<= p->regshift; | ||
74 | __raw_writeb(value, (unsigned long)(p->membase + offset)); | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * Internal UARTs need to be initialized for the 8250 autoconfig to work | ||
79 | * properly. Note that the TX watermark initialization may not be needed | ||
80 | * once the 8250.c watermark handling code is merged. | ||
81 | */ | ||
82 | static inline void __init omap_serial_reset(struct plat_serial8250_port *p) | ||
83 | { | ||
84 | serial_write_reg(p, UART_OMAP_MDR1, 0x07); | ||
85 | serial_write_reg(p, UART_OMAP_SCR, 0x08); | ||
86 | serial_write_reg(p, UART_OMAP_MDR1, 0x00); | ||
87 | serial_write_reg(p, UART_OMAP_SYSC, 0x01); | ||
88 | } | ||
89 | |||
90 | void __init omap_serial_init() | ||
91 | { | ||
92 | int i; | ||
93 | const struct omap_uart_config *info; | ||
94 | |||
95 | /* | ||
96 | * Make sure the serial ports are muxed on at this point. | ||
97 | * You have to mux them off in device drivers later on | ||
98 | * if not needed. | ||
99 | */ | ||
100 | |||
101 | info = omap_get_config(OMAP_TAG_UART, | ||
102 | struct omap_uart_config); | ||
103 | |||
104 | if (info == NULL) | ||
105 | return; | ||
106 | |||
107 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { | ||
108 | struct plat_serial8250_port *p = serial_platform_data + i; | ||
109 | |||
110 | if (!(info->enabled_uarts & (1 << i))) { | ||
111 | p->membase = 0; | ||
112 | p->mapbase = 0; | ||
113 | continue; | ||
114 | } | ||
115 | |||
116 | switch (i) { | ||
117 | case 0: | ||
118 | uart1_ick = clk_get(NULL, "uart1_ick"); | ||
119 | if (IS_ERR(uart1_ick)) | ||
120 | printk("Could not get uart1_ick\n"); | ||
121 | else { | ||
122 | clk_use(uart1_ick); | ||
123 | } | ||
124 | |||
125 | uart1_fck = clk_get(NULL, "uart1_fck"); | ||
126 | if (IS_ERR(uart1_fck)) | ||
127 | printk("Could not get uart1_fck\n"); | ||
128 | else { | ||
129 | clk_use(uart1_fck); | ||
130 | } | ||
131 | break; | ||
132 | case 1: | ||
133 | uart2_ick = clk_get(NULL, "uart2_ick"); | ||
134 | if (IS_ERR(uart2_ick)) | ||
135 | printk("Could not get uart2_ick\n"); | ||
136 | else { | ||
137 | clk_use(uart2_ick); | ||
138 | } | ||
139 | |||
140 | uart2_fck = clk_get(NULL, "uart2_fck"); | ||
141 | if (IS_ERR(uart2_fck)) | ||
142 | printk("Could not get uart2_fck\n"); | ||
143 | else { | ||
144 | clk_use(uart2_fck); | ||
145 | } | ||
146 | break; | ||
147 | case 2: | ||
148 | uart3_ick = clk_get(NULL, "uart3_ick"); | ||
149 | if (IS_ERR(uart3_ick)) | ||
150 | printk("Could not get uart3_ick\n"); | ||
151 | else { | ||
152 | clk_use(uart3_ick); | ||
153 | } | ||
154 | |||
155 | uart3_fck = clk_get(NULL, "uart3_fck"); | ||
156 | if (IS_ERR(uart3_fck)) | ||
157 | printk("Could not get uart3_fck\n"); | ||
158 | else { | ||
159 | clk_use(uart3_fck); | ||
160 | } | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | omap_serial_reset(p); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | static struct platform_device serial_device = { | ||
169 | .name = "serial8250", | ||
170 | .id = 0, | ||
171 | .dev = { | ||
172 | .platform_data = serial_platform_data, | ||
173 | }, | ||
174 | }; | ||
175 | |||
176 | static int __init omap_init(void) | ||
177 | { | ||
178 | return platform_device_register(&serial_device); | ||
179 | } | ||
180 | arch_initcall(omap_init); | ||
diff --git a/arch/arm/mach-omap2/sram-fn.S b/arch/arm/mach-omap2/sram-fn.S new file mode 100644 index 000000000000..2a869e203342 --- /dev/null +++ b/arch/arm/mach-omap2/sram-fn.S | |||
@@ -0,0 +1,333 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap1/sram.S | ||
3 | * | ||
4 | * Omap2 specific functions that need to be run in internal SRAM | ||
5 | * | ||
6 | * (C) Copyright 2004 | ||
7 | * Texas Instruments, <www.ti.com> | ||
8 | * Richard Woodruff <r-woodruff2@ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License as | ||
12 | * published by the Free Software Foundation; either version 2 of | ||
13 | * the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
23 | * MA 02111-1307 USA | ||
24 | */ | ||
25 | #include <linux/config.h> | ||
26 | #include <linux/linkage.h> | ||
27 | #include <asm/assembler.h> | ||
28 | #include <asm/arch/io.h> | ||
29 | #include <asm/hardware.h> | ||
30 | |||
31 | #include <asm/arch/prcm.h> | ||
32 | |||
33 | #define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010) | ||
34 | |||
35 | #define CM_CLKSEL2_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x544) | ||
36 | #define PRCM_VOLTCTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x050) | ||
37 | #define PRCM_CLKCFG_CTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x080) | ||
38 | #define CM_CLKEN_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x500) | ||
39 | #define CM_IDLEST_CKGEN_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x520) | ||
40 | #define CM_CLKSEL1_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x540) | ||
41 | |||
42 | #define SDRC_DLLA_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE + 0x060) | ||
43 | #define SDRC_RFR_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE + 0x0a4) | ||
44 | |||
45 | .text | ||
46 | |||
47 | ENTRY(sram_ddr_init) | ||
48 | stmfd sp!, {r0 - r12, lr} @ save registers on stack | ||
49 | |||
50 | mov r12, r2 @ capture CS1 vs CS0 | ||
51 | mov r8, r3 @ capture force parameter | ||
52 | |||
53 | /* frequency shift down */ | ||
54 | ldr r2, cm_clksel2_pll @ get address of dpllout reg | ||
55 | mov r3, #0x1 @ value for 1x operation | ||
56 | str r3, [r2] @ go to L1-freq operation | ||
57 | |||
58 | /* voltage shift down */ | ||
59 | mov r9, #0x1 @ set up for L1 voltage call | ||
60 | bl voltage_shift @ go drop voltage | ||
61 | |||
62 | /* dll lock mode */ | ||
63 | ldr r11, sdrc_dlla_ctrl @ addr of dlla ctrl | ||
64 | ldr r10, [r11] @ get current val | ||
65 | cmp r12, #0x1 @ cs1 base (2422 es2.05/1) | ||
66 | addeq r11, r11, #0x8 @ if cs1 base, move to DLLB | ||
67 | mvn r9, #0x4 @ mask to get clear bit2 | ||
68 | and r10, r10, r9 @ clear bit2 for lock mode. | ||
69 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) | ||
70 | orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz | ||
71 | str r10, [r11] @ commit to DLLA_CTRL | ||
72 | bl i_dll_wait @ wait for dll to lock | ||
73 | |||
74 | /* get dll value */ | ||
75 | add r11, r11, #0x4 @ get addr of status reg | ||
76 | ldr r10, [r11] @ get locked value | ||
77 | |||
78 | /* voltage shift up */ | ||
79 | mov r9, #0x0 @ shift back to L0-voltage | ||
80 | bl voltage_shift @ go raise voltage | ||
81 | |||
82 | /* frequency shift up */ | ||
83 | mov r3, #0x2 @ value for 2x operation | ||
84 | str r3, [r2] @ go to L0-freq operation | ||
85 | |||
86 | /* reset entry mode for dllctrl */ | ||
87 | sub r11, r11, #0x4 @ move from status to ctrl | ||
88 | cmp r12, #0x1 @ normalize if cs1 based | ||
89 | subeq r11, r11, #0x8 @ possibly back to DLLA | ||
90 | cmp r8, #0x1 @ if forced unlock exit | ||
91 | orreq r1, r1, #0x4 @ make sure exit with unlocked value | ||
92 | str r1, [r11] @ restore DLLA_CTRL high value | ||
93 | add r11, r11, #0x8 @ move to DLLB_CTRL addr | ||
94 | str r1, [r11] @ set value DLLB_CTRL | ||
95 | bl i_dll_wait @ wait for possible lock | ||
96 | |||
97 | /* set up for return, DDR should be good */ | ||
98 | str r10, [r0] @ write dll_status and return counter | ||
99 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return | ||
100 | |||
101 | /* ensure the DLL has relocked */ | ||
102 | i_dll_wait: | ||
103 | mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks | ||
104 | i_dll_delay: | ||
105 | subs r4, r4, #0x1 | ||
106 | bne i_dll_delay | ||
107 | mov pc, lr | ||
108 | |||
109 | /* | ||
110 | * shift up or down voltage, use R9 as input to tell level. | ||
111 | * wait for it to finish, use 32k sync counter, 1tick=31uS. | ||
112 | */ | ||
113 | voltage_shift: | ||
114 | ldr r4, prcm_voltctrl @ get addr of volt ctrl. | ||
115 | ldr r5, [r4] @ get value. | ||
116 | ldr r6, prcm_mask_val @ get value of mask | ||
117 | and r5, r5, r6 @ apply mask to clear bits | ||
118 | orr r5, r5, r9 @ bulld value for L0/L1-volt operation. | ||
119 | str r5, [r4] @ set up for change. | ||
120 | mov r3, #0x4000 @ get val for force | ||
121 | orr r5, r5, r3 @ build value for force | ||
122 | str r5, [r4] @ Force transition to L1 | ||
123 | |||
124 | ldr r3, timer_32ksynct_cr @ get addr of counter | ||
125 | ldr r5, [r3] @ get value | ||
126 | add r5, r5, #0x3 @ give it at most 93uS | ||
127 | volt_delay: | ||
128 | ldr r7, [r3] @ get timer value | ||
129 | cmp r5, r7 @ time up? | ||
130 | bhi volt_delay @ not yet->branch | ||
131 | mov pc, lr @ back to caller. | ||
132 | |||
133 | /* relative load constants */ | ||
134 | cm_clksel2_pll: | ||
135 | .word CM_CLKSEL2_PLL_V | ||
136 | sdrc_dlla_ctrl: | ||
137 | .word SDRC_DLLA_CTRL_V | ||
138 | prcm_voltctrl: | ||
139 | .word PRCM_VOLTCTRL_V | ||
140 | prcm_mask_val: | ||
141 | .word 0xFFFF3FFC | ||
142 | timer_32ksynct_cr: | ||
143 | .word TIMER_32KSYNCT_CR_V | ||
144 | ENTRY(sram_ddr_init_sz) | ||
145 | .word . - sram_ddr_init | ||
146 | |||
147 | /* | ||
148 | * Reprograms memory timings. | ||
149 | * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] | ||
150 | * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 | ||
151 | */ | ||
152 | ENTRY(sram_reprogram_sdrc) | ||
153 | stmfd sp!, {r0 - r10, lr} @ save registers on stack | ||
154 | mov r3, #0x0 @ clear for mrc call | ||
155 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR | ||
156 | nop | ||
157 | nop | ||
158 | ldr r6, ddr_sdrc_rfr_ctrl @ get addr of refresh reg | ||
159 | ldr r5, [r6] @ get value | ||
160 | mov r5, r5, lsr #8 @ isolate rfr field and drop burst | ||
161 | |||
162 | cmp r0, #0x1 @ going to half speed? | ||
163 | movne r9, #0x0 @ if up set flag up for pre up, hi volt | ||
164 | |||
165 | blne voltage_shift_c @ adjust voltage | ||
166 | |||
167 | cmp r0, #0x1 @ going to half speed (post branch link) | ||
168 | moveq r5, r5, lsr #1 @ divide by 2 if to half | ||
169 | movne r5, r5, lsl #1 @ mult by 2 if to full | ||
170 | mov r5, r5, lsl #8 @ put rfr field back into place | ||
171 | add r5, r5, #0x1 @ turn on burst of 1 | ||
172 | ldr r4, ddr_cm_clksel2_pll @ get address of out reg | ||
173 | ldr r3, [r4] @ get curr value | ||
174 | orr r3, r3, #0x3 | ||
175 | bic r3, r3, #0x3 @ clear lower bits | ||
176 | orr r3, r3, r0 @ new state value | ||
177 | str r3, [r4] @ set new state (pll/x, x=1 or 2) | ||
178 | nop | ||
179 | nop | ||
180 | |||
181 | moveq r9, #0x1 @ if speed down, post down, drop volt | ||
182 | bleq voltage_shift_c | ||
183 | |||
184 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier | ||
185 | str r5, [r6] @ set new RFR_1 value | ||
186 | add r6, r6, #0x30 @ get RFR_2 addr | ||
187 | str r5, [r6] @ set RFR_2 | ||
188 | nop | ||
189 | cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL | ||
190 | bne freq_out @ leave if SDR, no DLL function | ||
191 | |||
192 | /* With DDR, we need to take care of the DLL for the frequency change */ | ||
193 | ldr r2, ddr_sdrc_dlla_ctrl @ addr of dlla ctrl | ||
194 | str r1, [r2] @ write out new SDRC_DLLA_CTRL | ||
195 | add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL | ||
196 | str r1, [r2] @ commit to SDRC_DLLB_CTRL | ||
197 | mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks | ||
198 | dll_wait: | ||
199 | subs r1, r1, #0x1 | ||
200 | bne dll_wait | ||
201 | freq_out: | ||
202 | ldmfd sp!, {r0 - r10, pc} @ restore regs and return | ||
203 | |||
204 | /* | ||
205 | * shift up or down voltage, use R9 as input to tell level. | ||
206 | * wait for it to finish, use 32k sync counter, 1tick=31uS. | ||
207 | */ | ||
208 | voltage_shift_c: | ||
209 | ldr r10, ddr_prcm_voltctrl @ get addr of volt ctrl | ||
210 | ldr r8, [r10] @ get value | ||
211 | ldr r7, ddr_prcm_mask_val @ get value of mask | ||
212 | and r8, r8, r7 @ apply mask to clear bits | ||
213 | orr r8, r8, r9 @ bulld value for L0/L1-volt operation. | ||
214 | str r8, [r10] @ set up for change. | ||
215 | mov r7, #0x4000 @ get val for force | ||
216 | orr r8, r8, r7 @ build value for force | ||
217 | str r8, [r10] @ Force transition to L1 | ||
218 | |||
219 | ldr r10, ddr_timer_32ksynct @ get addr of counter | ||
220 | ldr r8, [r10] @ get value | ||
221 | add r8, r8, #0x2 @ give it at most 62uS (min 31+) | ||
222 | volt_delay_c: | ||
223 | ldr r7, [r10] @ get timer value | ||
224 | cmp r8, r7 @ time up? | ||
225 | bhi volt_delay_c @ not yet->branch | ||
226 | mov pc, lr @ back to caller | ||
227 | |||
228 | ddr_cm_clksel2_pll: | ||
229 | .word CM_CLKSEL2_PLL_V | ||
230 | ddr_sdrc_dlla_ctrl: | ||
231 | .word SDRC_DLLA_CTRL_V | ||
232 | ddr_sdrc_rfr_ctrl: | ||
233 | .word SDRC_RFR_CTRL_V | ||
234 | ddr_prcm_voltctrl: | ||
235 | .word PRCM_VOLTCTRL_V | ||
236 | ddr_prcm_mask_val: | ||
237 | .word 0xFFFF3FFC | ||
238 | ddr_timer_32ksynct: | ||
239 | .word TIMER_32KSYNCT_CR_V | ||
240 | |||
241 | ENTRY(sram_reprogram_sdrc_sz) | ||
242 | .word . - sram_reprogram_sdrc | ||
243 | |||
244 | /* | ||
245 | * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. | ||
246 | */ | ||
247 | ENTRY(sram_set_prcm) | ||
248 | stmfd sp!, {r0-r12, lr} @ regs to stack | ||
249 | adr r4, pbegin @ addr of preload start | ||
250 | adr r8, pend @ addr of preload end | ||
251 | mcrr p15, 1, r8, r4, c12 @ preload into icache | ||
252 | pbegin: | ||
253 | /* move into fast relock bypass */ | ||
254 | ldr r8, pll_ctl @ get addr | ||
255 | ldr r5, [r8] @ get val | ||
256 | mvn r6, #0x3 @ clear mask | ||
257 | and r5, r5, r6 @ clear field | ||
258 | orr r7, r5, #0x2 @ fast relock val | ||
259 | str r7, [r8] @ go to fast relock | ||
260 | ldr r4, pll_stat @ addr of stat | ||
261 | block: | ||
262 | /* wait for bypass */ | ||
263 | ldr r8, [r4] @ stat value | ||
264 | and r8, r8, #0x3 @ mask for stat | ||
265 | cmp r8, #0x1 @ there yet | ||
266 | bne block @ loop if not | ||
267 | |||
268 | /* set new dpll dividers _after_ in bypass */ | ||
269 | ldr r4, pll_div @ get addr | ||
270 | str r0, [r4] @ set dpll ctrl val | ||
271 | |||
272 | ldr r4, set_config @ get addr | ||
273 | mov r8, #1 @ valid cfg msk | ||
274 | str r8, [r4] @ make dividers take | ||
275 | |||
276 | mov r4, #100 @ dead spin a bit | ||
277 | wait_a_bit: | ||
278 | subs r4, r4, #1 @ dec loop | ||
279 | bne wait_a_bit @ delay done? | ||
280 | |||
281 | /* check if staying in bypass */ | ||
282 | cmp r2, #0x1 @ stay in bypass? | ||
283 | beq pend @ jump over dpll relock | ||
284 | |||
285 | /* relock DPLL with new vals */ | ||
286 | ldr r5, pll_stat @ get addr | ||
287 | ldr r4, pll_ctl @ get addr | ||
288 | orr r8, r7, #0x3 @ val for lock dpll | ||
289 | str r8, [r4] @ set val | ||
290 | mov r0, #1000 @ dead spin a bit | ||
291 | wait_more: | ||
292 | subs r0, r0, #1 @ dec loop | ||
293 | bne wait_more @ delay done? | ||
294 | wait_lock: | ||
295 | ldr r8, [r5] @ get lock val | ||
296 | and r8, r8, #3 @ isolate field | ||
297 | cmp r8, #2 @ locked? | ||
298 | bne wait_lock @ wait if not | ||
299 | pend: | ||
300 | /* update memory timings & briefly lock dll */ | ||
301 | ldr r4, sdrc_rfr @ get addr | ||
302 | str r1, [r4] @ update refresh timing | ||
303 | ldr r11, dlla_ctrl @ get addr of DLLA ctrl | ||
304 | ldr r10, [r11] @ get current val | ||
305 | mvn r9, #0x4 @ mask to get clear bit2 | ||
306 | and r10, r10, r9 @ clear bit2 for lock mode | ||
307 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) | ||
308 | str r10, [r11] @ commit to DLLA_CTRL | ||
309 | add r11, r11, #0x8 @ move to dllb | ||
310 | str r10, [r11] @ hit DLLB also | ||
311 | |||
312 | mov r4, #0x800 @ relock time (min 0x400 L3 clocks) | ||
313 | wait_dll_lock: | ||
314 | subs r4, r4, #0x1 | ||
315 | bne wait_dll_lock | ||
316 | nop | ||
317 | ldmfd sp!, {r0-r12, pc} @ restore regs and return | ||
318 | |||
319 | set_config: | ||
320 | .word PRCM_CLKCFG_CTRL_V | ||
321 | pll_ctl: | ||
322 | .word CM_CLKEN_PLL_V | ||
323 | pll_stat: | ||
324 | .word CM_IDLEST_CKGEN_V | ||
325 | pll_div: | ||
326 | .word CM_CLKSEL1_PLL_V | ||
327 | sdrc_rfr: | ||
328 | .word SDRC_RFR_CTRL_V | ||
329 | dlla_ctrl: | ||
330 | .word SDRC_DLLA_CTRL_V | ||
331 | |||
332 | ENTRY(sram_set_prcm_sz) | ||
333 | .word . - sram_set_prcm | ||
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c new file mode 100644 index 000000000000..9ec11443200f --- /dev/null +++ b/arch/arm/mach-omap2/timer-gp.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/timer-gp.c | ||
3 | * | ||
4 | * OMAP2 GP timer support. | ||
5 | * | ||
6 | * Copyright (C) 2005 Nokia Corporation | ||
7 | * Author: Paul Mundt <paul.mundt@nokia.com> | ||
8 | * Juha Yrjölä <juha.yrjola@nokia.com> | ||
9 | * | ||
10 | * Some parts based off of TI's 24xx code: | ||
11 | * | ||
12 | * Copyright (C) 2004 Texas Instruments, Inc. | ||
13 | * | ||
14 | * Roughly modelled after the OMAP1 MPU timer code. | ||
15 | * | ||
16 | * This file is subject to the terms and conditions of the GNU General Public | ||
17 | * License. See the file "COPYING" in the main directory of this archive | ||
18 | * for more details. | ||
19 | */ | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/time.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <asm/mach/time.h> | ||
25 | #include <asm/delay.h> | ||
26 | #include <asm/io.h> | ||
27 | #include <asm/hardware/clock.h> | ||
28 | |||
29 | #define OMAP2_GP_TIMER1_BASE 0x48028000 | ||
30 | #define OMAP2_GP_TIMER2_BASE 0x4802a000 | ||
31 | #define OMAP2_GP_TIMER3_BASE 0x48078000 | ||
32 | #define OMAP2_GP_TIMER4_BASE 0x4807a000 | ||
33 | |||
34 | #define GP_TIMER_TIDR 0x00 | ||
35 | #define GP_TIMER_TISR 0x18 | ||
36 | #define GP_TIMER_TIER 0x1c | ||
37 | #define GP_TIMER_TCLR 0x24 | ||
38 | #define GP_TIMER_TCRR 0x28 | ||
39 | #define GP_TIMER_TLDR 0x2c | ||
40 | #define GP_TIMER_TSICR 0x40 | ||
41 | |||
42 | #define OS_TIMER_NR 1 /* GP timer 2 */ | ||
43 | |||
44 | static unsigned long timer_base[] = { | ||
45 | IO_ADDRESS(OMAP2_GP_TIMER1_BASE), | ||
46 | IO_ADDRESS(OMAP2_GP_TIMER2_BASE), | ||
47 | IO_ADDRESS(OMAP2_GP_TIMER3_BASE), | ||
48 | IO_ADDRESS(OMAP2_GP_TIMER4_BASE), | ||
49 | }; | ||
50 | |||
51 | static inline unsigned int timer_read_reg(int nr, unsigned int reg) | ||
52 | { | ||
53 | return __raw_readl(timer_base[nr] + reg); | ||
54 | } | ||
55 | |||
56 | static inline void timer_write_reg(int nr, unsigned int reg, unsigned int val) | ||
57 | { | ||
58 | __raw_writel(val, timer_base[nr] + reg); | ||
59 | } | ||
60 | |||
61 | /* Note that we always enable the clock prescale divider bit */ | ||
62 | static inline void omap2_gp_timer_start(int nr, unsigned long load_val) | ||
63 | { | ||
64 | unsigned int tmp; | ||
65 | |||
66 | tmp = 0xffffffff - load_val; | ||
67 | |||
68 | timer_write_reg(nr, GP_TIMER_TLDR, tmp); | ||
69 | timer_write_reg(nr, GP_TIMER_TCRR, tmp); | ||
70 | timer_write_reg(nr, GP_TIMER_TIER, 1 << 1); | ||
71 | timer_write_reg(nr, GP_TIMER_TCLR, (1 << 5) | (1 << 1) | 1); | ||
72 | } | ||
73 | |||
74 | static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id, | ||
75 | struct pt_regs *regs) | ||
76 | { | ||
77 | write_seqlock(&xtime_lock); | ||
78 | |||
79 | timer_write_reg(OS_TIMER_NR, GP_TIMER_TISR, 1 << 1); | ||
80 | timer_tick(regs); | ||
81 | |||
82 | write_sequnlock(&xtime_lock); | ||
83 | |||
84 | return IRQ_HANDLED; | ||
85 | } | ||
86 | |||
87 | static struct irqaction omap2_gp_timer_irq = { | ||
88 | .name = "gp timer", | ||
89 | .flags = SA_INTERRUPT, | ||
90 | .handler = omap2_gp_timer_interrupt, | ||
91 | }; | ||
92 | |||
93 | static void __init omap2_gp_timer_init(void) | ||
94 | { | ||
95 | struct clk * sys_ck; | ||
96 | u32 tick_period = 120000; | ||
97 | u32 l; | ||
98 | |||
99 | /* Reset clock and prescale value */ | ||
100 | timer_write_reg(OS_TIMER_NR, GP_TIMER_TCLR, 0); | ||
101 | |||
102 | sys_ck = clk_get(NULL, "sys_ck"); | ||
103 | if (IS_ERR(sys_ck)) | ||
104 | printk(KERN_ERR "Could not get sys_ck\n"); | ||
105 | else { | ||
106 | clk_use(sys_ck); | ||
107 | tick_period = clk_get_rate(sys_ck) / 100; | ||
108 | clk_put(sys_ck); | ||
109 | } | ||
110 | |||
111 | tick_period /= 2; /* Minimum prescale divider is 2 */ | ||
112 | tick_period -= 1; | ||
113 | |||
114 | l = timer_read_reg(OS_TIMER_NR, GP_TIMER_TIDR); | ||
115 | printk(KERN_INFO "OMAP2 GP timer (HW version %d.%d)\n", | ||
116 | (l >> 4) & 0x0f, l & 0x0f); | ||
117 | |||
118 | setup_irq(38, &omap2_gp_timer_irq); | ||
119 | |||
120 | omap2_gp_timer_start(OS_TIMER_NR, tick_period); | ||
121 | } | ||
122 | |||
123 | struct sys_timer omap_timer = { | ||
124 | .init = omap2_gp_timer_init, | ||
125 | }; | ||
126 | |||
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index b380a438e68f..e201aa9765b9 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
@@ -60,6 +60,7 @@ config MACH_CORGI | |||
60 | bool "Enable Sharp SL-C700 (Corgi) Support" | 60 | bool "Enable Sharp SL-C700 (Corgi) Support" |
61 | depends PXA_SHARPSL_25x | 61 | depends PXA_SHARPSL_25x |
62 | select PXA_SHARP_C7xx | 62 | select PXA_SHARP_C7xx |
63 | select PXA_SSP | ||
63 | 64 | ||
64 | config MACH_SHEPHERD | 65 | config MACH_SHEPHERD |
65 | bool "Enable Sharp SL-C750 (Shepherd) Support" | 66 | bool "Enable Sharp SL-C750 (Shepherd) Support" |
@@ -102,12 +103,18 @@ config IWMMXT | |||
102 | 103 | ||
103 | config PXA_SHARP_C7xx | 104 | config PXA_SHARP_C7xx |
104 | bool | 105 | bool |
106 | select PXA_SSP | ||
105 | help | 107 | help |
106 | Enable support for all Sharp C7xx models | 108 | Enable support for all Sharp C7xx models |
107 | 109 | ||
108 | config PXA_SHARP_Cxx00 | 110 | config PXA_SHARP_Cxx00 |
109 | bool | 111 | bool |
112 | select PXA_SSP | ||
110 | help | 113 | help |
111 | Enable common support for Sharp Cxx00 models | 114 | Enable common support for Sharp Cxx00 models |
112 | 115 | ||
116 | config PXA_SSP | ||
117 | tristate | ||
118 | help | ||
119 | Enable support for PXA2xx SSP ports | ||
113 | endif | 120 | endif |
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 8bc72d07cea8..d210bd5032ce 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
@@ -11,8 +11,8 @@ obj-$(CONFIG_PXA27x) += pxa27x.o | |||
11 | obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o | 11 | obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o |
12 | obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o | 12 | obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o |
13 | obj-$(CONFIG_ARCH_PXA_IDP) += idp.o | 13 | obj-$(CONFIG_ARCH_PXA_IDP) += idp.o |
14 | obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o | 14 | obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o |
15 | obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o ssp.o | 15 | obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o |
16 | obj-$(CONFIG_MACH_POODLE) += poodle.o | 16 | obj-$(CONFIG_MACH_POODLE) += poodle.o |
17 | obj-$(CONFIG_MACH_TOSA) += tosa.o | 17 | obj-$(CONFIG_MACH_TOSA) += tosa.o |
18 | 18 | ||
@@ -26,6 +26,7 @@ obj-$(CONFIG_LEDS) += $(led-y) | |||
26 | 26 | ||
27 | # Misc features | 27 | # Misc features |
28 | obj-$(CONFIG_PM) += pm.o sleep.o | 28 | obj-$(CONFIG_PM) += pm.o sleep.o |
29 | obj-$(CONFIG_PXA_SSP) += ssp.o | ||
29 | 30 | ||
30 | ifeq ($(CONFIG_PXA27x),y) | 31 | ifeq ($(CONFIG_PXA27x),y) |
31 | obj-$(CONFIG_PM) += standby.o | 32 | obj-$(CONFIG_PM) += standby.o |
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c index 9f835f32b938..b371d723635f 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c | |||
@@ -203,7 +203,7 @@ static int __init corgi_ssp_probe(struct platform_device *dev) | |||
203 | GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */ | 203 | GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */ |
204 | GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ | 204 | GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ |
205 | 205 | ||
206 | ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port); | 206 | ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0); |
207 | 207 | ||
208 | if (ret) | 208 | if (ret) |
209 | printk(KERN_ERR "Unable to register SSP handler!\n"); | 209 | printk(KERN_ERR "Unable to register SSP handler!\n"); |
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h index 3977a77aacdd..4879c0f7da72 100644 --- a/arch/arm/mach-pxa/sharpsl.h +++ b/arch/arm/mach-pxa/sharpsl.h | |||
@@ -32,3 +32,90 @@ void corgi_put_hsync(void); | |||
32 | void spitz_put_hsync(void); | 32 | void spitz_put_hsync(void); |
33 | void corgi_wait_hsync(void); | 33 | void corgi_wait_hsync(void); |
34 | void spitz_wait_hsync(void); | 34 | void spitz_wait_hsync(void); |
35 | |||
36 | /* | ||
37 | * SharpSL Battery/PM Driver | ||
38 | */ | ||
39 | |||
40 | struct sharpsl_charger_machinfo { | ||
41 | void (*init)(void); | ||
42 | int gpio_acin; | ||
43 | int gpio_batfull; | ||
44 | int gpio_batlock; | ||
45 | int gpio_fatal; | ||
46 | int (*status_acin)(void); | ||
47 | void (*discharge)(int); | ||
48 | void (*discharge1)(int); | ||
49 | void (*charge)(int); | ||
50 | void (*chargeled)(int); | ||
51 | void (*measure_temp)(int); | ||
52 | void (*presuspend)(void); | ||
53 | void (*postsuspend)(void); | ||
54 | unsigned long (*charger_wakeup)(void); | ||
55 | int (*should_wakeup)(unsigned int resume_on_alarm); | ||
56 | int bat_levels; | ||
57 | struct battery_thresh *bat_levels_noac; | ||
58 | struct battery_thresh *bat_levels_acin; | ||
59 | int status_high_acin; | ||
60 | int status_low_acin; | ||
61 | int status_high_noac; | ||
62 | int status_low_noac; | ||
63 | }; | ||
64 | |||
65 | struct battery_thresh { | ||
66 | int voltage; | ||
67 | int percentage; | ||
68 | }; | ||
69 | |||
70 | struct battery_stat { | ||
71 | int ac_status; /* APM AC Present/Not Present */ | ||
72 | int mainbat_status; /* APM Main Battery Status */ | ||
73 | int mainbat_percent; /* Main Battery Percentage Charge */ | ||
74 | int mainbat_voltage; /* Main Battery Voltage */ | ||
75 | }; | ||
76 | |||
77 | struct sharpsl_pm_status { | ||
78 | struct device *dev; | ||
79 | struct timer_list ac_timer; | ||
80 | struct timer_list chrg_full_timer; | ||
81 | |||
82 | int charge_mode; | ||
83 | #define CHRG_ERROR (-1) | ||
84 | #define CHRG_OFF (0) | ||
85 | #define CHRG_ON (1) | ||
86 | #define CHRG_DONE (2) | ||
87 | |||
88 | unsigned int flags; | ||
89 | #define SHARPSL_SUSPENDED (1 << 0) /* Device is Suspended */ | ||
90 | #define SHARPSL_ALARM_ACTIVE (1 << 1) /* Alarm is for charging event (not user) */ | ||
91 | #define SHARPSL_BL_LIMIT (1 << 2) /* Backlight Intensity Limited */ | ||
92 | #define SHARPSL_APM_QUEUED (1 << 3) /* APM Event Queued */ | ||
93 | #define SHARPSL_DO_OFFLINE_CHRG (1 << 4) /* Trigger the offline charger */ | ||
94 | |||
95 | int full_count; | ||
96 | unsigned long charge_start_time; | ||
97 | struct sharpsl_charger_machinfo *machinfo; | ||
98 | struct battery_stat battstat; | ||
99 | }; | ||
100 | |||
101 | extern struct sharpsl_pm_status sharpsl_pm; | ||
102 | extern struct battery_thresh spitz_battery_levels_acin[]; | ||
103 | extern struct battery_thresh spitz_battery_levels_noac[]; | ||
104 | |||
105 | #define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) | ||
106 | |||
107 | #define SHARPSL_LED_ERROR 2 | ||
108 | #define SHARPSL_LED_ON 1 | ||
109 | #define SHARPSL_LED_OFF 0 | ||
110 | |||
111 | #define CHARGE_ON() sharpsl_pm.machinfo->charge(1) | ||
112 | #define CHARGE_OFF() sharpsl_pm.machinfo->charge(0) | ||
113 | #define CHARGE_LED_ON() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ON) | ||
114 | #define CHARGE_LED_OFF() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_OFF) | ||
115 | #define CHARGE_LED_ERR() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR) | ||
116 | #define DISCHARGE_ON() sharpsl_pm.machinfo->discharge(1) | ||
117 | #define DISCHARGE_OFF() sharpsl_pm.machinfo->discharge(0) | ||
118 | #define STATUS_AC_IN sharpsl_pm.machinfo->status_acin() | ||
119 | #define STATUS_BATT_LOCKED READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock) | ||
120 | #define STATUS_CHRG_FULL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull) | ||
121 | #define STATUS_FATAL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal) | ||
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c new file mode 100644 index 000000000000..6c9e871c53d8 --- /dev/null +++ b/arch/arm/mach-pxa/sharpsl_pm.c | |||
@@ -0,0 +1,992 @@ | |||
1 | /* | ||
2 | * Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00 | ||
3 | * series of PDAs | ||
4 | * | ||
5 | * Copyright (c) 2004-2005 Richard Purdie | ||
6 | * | ||
7 | * Based on code written by Sharp for 2.4 kernels | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #undef DEBUG | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/timer.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/apm_bios.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/device.h> | ||
25 | |||
26 | #include <asm/hardware.h> | ||
27 | #include <asm/hardware/scoop.h> | ||
28 | #include <asm/mach-types.h> | ||
29 | #include <asm/irq.h> | ||
30 | #include <asm/apm.h> | ||
31 | |||
32 | #include <asm/arch/pm.h> | ||
33 | #include <asm/arch/pxa-regs.h> | ||
34 | #include <asm/arch/sharpsl.h> | ||
35 | #include "sharpsl.h" | ||
36 | |||
37 | /* | ||
38 | * Constants | ||
39 | */ | ||
40 | #define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */ | ||
41 | #define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */ | ||
42 | #define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */ | ||
43 | #define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */ | ||
44 | #define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */ | ||
45 | #define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ | ||
46 | #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ | ||
47 | #define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */ | ||
48 | #define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD 10 /* 10 msec */ | ||
49 | #define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */ | ||
50 | #define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */ | ||
51 | #define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */ | ||
52 | |||
53 | #define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */ | ||
54 | #define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */ | ||
55 | #define SHARPSL_CHARGE_ON_JKVAD_HIGH 0x9b /* 6V */ | ||
56 | #define SHARPSL_CHARGE_ON_JKVAD_LOW 0x34 /* 2V */ | ||
57 | #define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */ | ||
58 | #define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */ | ||
59 | |||
60 | struct battery_thresh spitz_battery_levels_acin[] = { | ||
61 | { 213, 100}, | ||
62 | { 212, 98}, | ||
63 | { 211, 95}, | ||
64 | { 210, 93}, | ||
65 | { 209, 90}, | ||
66 | { 208, 88}, | ||
67 | { 207, 85}, | ||
68 | { 206, 83}, | ||
69 | { 205, 80}, | ||
70 | { 204, 78}, | ||
71 | { 203, 75}, | ||
72 | { 202, 73}, | ||
73 | { 201, 70}, | ||
74 | { 200, 68}, | ||
75 | { 199, 65}, | ||
76 | { 198, 63}, | ||
77 | { 197, 60}, | ||
78 | { 196, 58}, | ||
79 | { 195, 55}, | ||
80 | { 194, 53}, | ||
81 | { 193, 50}, | ||
82 | { 192, 48}, | ||
83 | { 192, 45}, | ||
84 | { 191, 43}, | ||
85 | { 191, 40}, | ||
86 | { 190, 38}, | ||
87 | { 190, 35}, | ||
88 | { 189, 33}, | ||
89 | { 188, 30}, | ||
90 | { 187, 28}, | ||
91 | { 186, 25}, | ||
92 | { 185, 23}, | ||
93 | { 184, 20}, | ||
94 | { 183, 18}, | ||
95 | { 182, 15}, | ||
96 | { 181, 13}, | ||
97 | { 180, 10}, | ||
98 | { 179, 8}, | ||
99 | { 178, 5}, | ||
100 | { 0, 0}, | ||
101 | }; | ||
102 | |||
103 | struct battery_thresh spitz_battery_levels_noac[] = { | ||
104 | { 213, 100}, | ||
105 | { 212, 98}, | ||
106 | { 211, 95}, | ||
107 | { 210, 93}, | ||
108 | { 209, 90}, | ||
109 | { 208, 88}, | ||
110 | { 207, 85}, | ||
111 | { 206, 83}, | ||
112 | { 205, 80}, | ||
113 | { 204, 78}, | ||
114 | { 203, 75}, | ||
115 | { 202, 73}, | ||
116 | { 201, 70}, | ||
117 | { 200, 68}, | ||
118 | { 199, 65}, | ||
119 | { 198, 63}, | ||
120 | { 197, 60}, | ||
121 | { 196, 58}, | ||
122 | { 195, 55}, | ||
123 | { 194, 53}, | ||
124 | { 193, 50}, | ||
125 | { 192, 48}, | ||
126 | { 191, 45}, | ||
127 | { 190, 43}, | ||
128 | { 189, 40}, | ||
129 | { 188, 38}, | ||
130 | { 187, 35}, | ||
131 | { 186, 33}, | ||
132 | { 185, 30}, | ||
133 | { 184, 28}, | ||
134 | { 183, 25}, | ||
135 | { 182, 23}, | ||
136 | { 181, 20}, | ||
137 | { 180, 18}, | ||
138 | { 179, 15}, | ||
139 | { 178, 13}, | ||
140 | { 177, 10}, | ||
141 | { 176, 8}, | ||
142 | { 175, 5}, | ||
143 | { 0, 0}, | ||
144 | }; | ||
145 | |||
146 | /* MAX1111 Commands */ | ||
147 | #define MAXCTRL_PD0 1u << 0 | ||
148 | #define MAXCTRL_PD1 1u << 1 | ||
149 | #define MAXCTRL_SGL 1u << 2 | ||
150 | #define MAXCTRL_UNI 1u << 3 | ||
151 | #define MAXCTRL_SEL_SH 4 | ||
152 | #define MAXCTRL_STR 1u << 7 | ||
153 | |||
154 | /* MAX1111 Channel Definitions */ | ||
155 | #define BATT_AD 4u | ||
156 | #define BATT_THM 2u | ||
157 | #define JK_VAD 6u | ||
158 | |||
159 | |||
160 | /* | ||
161 | * Prototypes | ||
162 | */ | ||
163 | static int sharpsl_read_MainBattery(void); | ||
164 | static int sharpsl_off_charge_battery(void); | ||
165 | static int sharpsl_check_battery(int mode); | ||
166 | static int sharpsl_ac_check(void); | ||
167 | static int sharpsl_fatal_check(void); | ||
168 | static int sharpsl_average_value(int ad); | ||
169 | static void sharpsl_average_clear(void); | ||
170 | static void sharpsl_charge_toggle(void *private_); | ||
171 | static void sharpsl_battery_thread(void *private_); | ||
172 | |||
173 | |||
174 | /* | ||
175 | * Variables | ||
176 | */ | ||
177 | struct sharpsl_pm_status sharpsl_pm; | ||
178 | DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); | ||
179 | DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); | ||
180 | |||
181 | |||
182 | static int get_percentage(int voltage) | ||
183 | { | ||
184 | int i = sharpsl_pm.machinfo->bat_levels - 1; | ||
185 | struct battery_thresh *thresh; | ||
186 | |||
187 | if (sharpsl_pm.charge_mode == CHRG_ON) | ||
188 | thresh=sharpsl_pm.machinfo->bat_levels_acin; | ||
189 | else | ||
190 | thresh=sharpsl_pm.machinfo->bat_levels_noac; | ||
191 | |||
192 | while (i > 0 && (voltage > thresh[i].voltage)) | ||
193 | i--; | ||
194 | |||
195 | return thresh[i].percentage; | ||
196 | } | ||
197 | |||
198 | static int get_apm_status(int voltage) | ||
199 | { | ||
200 | int low_thresh, high_thresh; | ||
201 | |||
202 | if (sharpsl_pm.charge_mode == CHRG_ON) { | ||
203 | high_thresh = sharpsl_pm.machinfo->status_high_acin; | ||
204 | low_thresh = sharpsl_pm.machinfo->status_low_acin; | ||
205 | } else { | ||
206 | high_thresh = sharpsl_pm.machinfo->status_high_noac; | ||
207 | low_thresh = sharpsl_pm.machinfo->status_low_noac; | ||
208 | } | ||
209 | |||
210 | if (voltage >= high_thresh) | ||
211 | return APM_BATTERY_STATUS_HIGH; | ||
212 | if (voltage >= low_thresh) | ||
213 | return APM_BATTERY_STATUS_LOW; | ||
214 | return APM_BATTERY_STATUS_CRITICAL; | ||
215 | } | ||
216 | |||
217 | void sharpsl_battery_kick(void) | ||
218 | { | ||
219 | schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125)); | ||
220 | } | ||
221 | EXPORT_SYMBOL(sharpsl_battery_kick); | ||
222 | |||
223 | |||
224 | static void sharpsl_battery_thread(void *private_) | ||
225 | { | ||
226 | int voltage, percent, apm_status, i = 0; | ||
227 | |||
228 | if (!sharpsl_pm.machinfo) | ||
229 | return; | ||
230 | |||
231 | sharpsl_pm.battstat.ac_status = (!(STATUS_AC_IN) ? APM_AC_OFFLINE : APM_AC_ONLINE); | ||
232 | |||
233 | /* Corgi cannot confirm when battery fully charged so periodically kick! */ | ||
234 | if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON) | ||
235 | && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) | ||
236 | schedule_work(&toggle_charger); | ||
237 | |||
238 | while(1) { | ||
239 | voltage = sharpsl_read_MainBattery(); | ||
240 | if (voltage > 0) break; | ||
241 | if (i++ > 5) { | ||
242 | voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage; | ||
243 | dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n"); | ||
244 | break; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | voltage = sharpsl_average_value(voltage); | ||
249 | apm_status = get_apm_status(voltage); | ||
250 | percent = get_percentage(voltage); | ||
251 | |||
252 | /* At low battery voltages, the voltage has a tendency to start | ||
253 | creeping back up so we try to avoid this here */ | ||
254 | if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) || percent <= sharpsl_pm.battstat.mainbat_percent) { | ||
255 | sharpsl_pm.battstat.mainbat_voltage = voltage; | ||
256 | sharpsl_pm.battstat.mainbat_status = apm_status; | ||
257 | sharpsl_pm.battstat.mainbat_percent = percent; | ||
258 | } | ||
259 | |||
260 | dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage, | ||
261 | sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies); | ||
262 | |||
263 | /* If battery is low. limit backlight intensity to save power. */ | ||
264 | if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) | ||
265 | && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) || | ||
266 | (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) { | ||
267 | if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) { | ||
268 | corgibl_limit_intensity(1); | ||
269 | sharpsl_pm.flags |= SHARPSL_BL_LIMIT; | ||
270 | } | ||
271 | } else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) { | ||
272 | corgibl_limit_intensity(0); | ||
273 | sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT; | ||
274 | } | ||
275 | |||
276 | /* Suspend if critical battery level */ | ||
277 | if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) | ||
278 | && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL) | ||
279 | && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) { | ||
280 | sharpsl_pm.flags |= SHARPSL_APM_QUEUED; | ||
281 | dev_err(sharpsl_pm.dev, "Fatal Off\n"); | ||
282 | apm_queue_event(APM_CRITICAL_SUSPEND); | ||
283 | } | ||
284 | |||
285 | schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME); | ||
286 | } | ||
287 | |||
288 | static void sharpsl_charge_on(void) | ||
289 | { | ||
290 | dev_dbg(sharpsl_pm.dev, "Turning Charger On\n"); | ||
291 | |||
292 | sharpsl_pm.full_count = 0; | ||
293 | sharpsl_pm.charge_mode = CHRG_ON; | ||
294 | schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250)); | ||
295 | schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500)); | ||
296 | } | ||
297 | |||
298 | static void sharpsl_charge_off(void) | ||
299 | { | ||
300 | dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n"); | ||
301 | |||
302 | CHARGE_OFF(); | ||
303 | CHARGE_LED_OFF(); | ||
304 | sharpsl_pm.charge_mode = CHRG_OFF; | ||
305 | |||
306 | schedule_work(&sharpsl_bat); | ||
307 | } | ||
308 | |||
309 | static void sharpsl_charge_error(void) | ||
310 | { | ||
311 | CHARGE_LED_ERR(); | ||
312 | CHARGE_OFF(); | ||
313 | sharpsl_pm.charge_mode = CHRG_ERROR; | ||
314 | } | ||
315 | |||
316 | static void sharpsl_charge_toggle(void *private_) | ||
317 | { | ||
318 | dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies); | ||
319 | |||
320 | if (STATUS_AC_IN == 0) { | ||
321 | sharpsl_charge_off(); | ||
322 | return; | ||
323 | } else if ((sharpsl_check_battery(1) < 0) || (sharpsl_ac_check() < 0)) { | ||
324 | sharpsl_charge_error(); | ||
325 | return; | ||
326 | } | ||
327 | |||
328 | CHARGE_LED_ON(); | ||
329 | CHARGE_OFF(); | ||
330 | mdelay(SHARPSL_CHARGE_WAIT_TIME); | ||
331 | CHARGE_ON(); | ||
332 | |||
333 | sharpsl_pm.charge_start_time = jiffies; | ||
334 | } | ||
335 | |||
336 | static void sharpsl_ac_timer(unsigned long data) | ||
337 | { | ||
338 | int acin = STATUS_AC_IN; | ||
339 | |||
340 | dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin); | ||
341 | |||
342 | sharpsl_average_clear(); | ||
343 | if (acin && (sharpsl_pm.charge_mode != CHRG_ON)) | ||
344 | sharpsl_charge_on(); | ||
345 | else if (sharpsl_pm.charge_mode == CHRG_ON) | ||
346 | sharpsl_charge_off(); | ||
347 | |||
348 | schedule_work(&sharpsl_bat); | ||
349 | } | ||
350 | |||
351 | |||
352 | static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp) | ||
353 | { | ||
354 | /* Delay the event slightly to debounce */ | ||
355 | /* Must be a smaller delay than the chrg_full_isr below */ | ||
356 | mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); | ||
357 | |||
358 | return IRQ_HANDLED; | ||
359 | } | ||
360 | |||
361 | static void sharpsl_chrg_full_timer(unsigned long data) | ||
362 | { | ||
363 | dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies); | ||
364 | |||
365 | sharpsl_pm.full_count++; | ||
366 | |||
367 | if (STATUS_AC_IN == 0) { | ||
368 | dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n"); | ||
369 | if (sharpsl_pm.charge_mode == CHRG_ON) | ||
370 | sharpsl_charge_off(); | ||
371 | } else if (sharpsl_pm.full_count < 2) { | ||
372 | dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n"); | ||
373 | schedule_work(&toggle_charger); | ||
374 | } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) { | ||
375 | dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n"); | ||
376 | schedule_work(&toggle_charger); | ||
377 | } else { | ||
378 | sharpsl_charge_off(); | ||
379 | sharpsl_pm.charge_mode = CHRG_DONE; | ||
380 | dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n"); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /* Charging Finished Interrupt (Not present on Corgi) */ | ||
385 | /* Can trigger at the same time as an AC staus change so | ||
386 | delay until after that has been processed */ | ||
387 | static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp) | ||
388 | { | ||
389 | if (sharpsl_pm.flags & SHARPSL_SUSPENDED) | ||
390 | return IRQ_HANDLED; | ||
391 | |||
392 | /* delay until after any ac interrupt */ | ||
393 | mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500)); | ||
394 | |||
395 | return IRQ_HANDLED; | ||
396 | } | ||
397 | |||
398 | static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp) | ||
399 | { | ||
400 | int is_fatal = 0; | ||
401 | |||
402 | if (STATUS_BATT_LOCKED == 0) { | ||
403 | dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n"); | ||
404 | is_fatal = 1; | ||
405 | } | ||
406 | |||
407 | if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL == 0)) { | ||
408 | dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n"); | ||
409 | is_fatal = 1; | ||
410 | } | ||
411 | |||
412 | if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) { | ||
413 | sharpsl_pm.flags |= SHARPSL_APM_QUEUED; | ||
414 | apm_queue_event(APM_CRITICAL_SUSPEND); | ||
415 | } | ||
416 | |||
417 | return IRQ_HANDLED; | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * Maintain an average of the last 10 readings | ||
422 | */ | ||
423 | #define SHARPSL_CNV_VALUE_NUM 10 | ||
424 | static int sharpsl_ad_index; | ||
425 | |||
426 | static void sharpsl_average_clear(void) | ||
427 | { | ||
428 | sharpsl_ad_index = 0; | ||
429 | } | ||
430 | |||
431 | static int sharpsl_average_value(int ad) | ||
432 | { | ||
433 | int i, ad_val = 0; | ||
434 | static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1]; | ||
435 | |||
436 | if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) { | ||
437 | sharpsl_ad_index = 0; | ||
438 | return ad; | ||
439 | } | ||
440 | |||
441 | sharpsl_ad[sharpsl_ad_index] = ad; | ||
442 | sharpsl_ad_index++; | ||
443 | if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) { | ||
444 | for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++) | ||
445 | sharpsl_ad[i] = sharpsl_ad[i+1]; | ||
446 | sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1; | ||
447 | } | ||
448 | for (i=0; i < sharpsl_ad_index; i++) | ||
449 | ad_val += sharpsl_ad[i]; | ||
450 | |||
451 | return (ad_val / sharpsl_ad_index); | ||
452 | } | ||
453 | |||
454 | |||
455 | /* | ||
456 | * Read MAX1111 ADC | ||
457 | */ | ||
458 | static int read_max1111(int channel) | ||
459 | { | ||
460 | return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1 | ||
461 | | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR); | ||
462 | } | ||
463 | |||
464 | static int sharpsl_read_MainBattery(void) | ||
465 | { | ||
466 | return read_max1111(BATT_AD); | ||
467 | } | ||
468 | |||
469 | static int sharpsl_read_Temp(void) | ||
470 | { | ||
471 | int temp; | ||
472 | |||
473 | sharpsl_pm.machinfo->measure_temp(1); | ||
474 | |||
475 | mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); | ||
476 | temp = read_max1111(BATT_THM); | ||
477 | |||
478 | sharpsl_pm.machinfo->measure_temp(0); | ||
479 | |||
480 | return temp; | ||
481 | } | ||
482 | |||
483 | static int sharpsl_read_jkvad(void) | ||
484 | { | ||
485 | return read_max1111(JK_VAD); | ||
486 | } | ||
487 | |||
488 | /* | ||
489 | * Take an array of 5 integers, remove the maximum and minimum values | ||
490 | * and return the average. | ||
491 | */ | ||
492 | static int get_select_val(int *val) | ||
493 | { | ||
494 | int i, j, k, temp, sum = 0; | ||
495 | |||
496 | /* Find MAX val */ | ||
497 | temp = val[0]; | ||
498 | j=0; | ||
499 | for (i=1; i<5; i++) { | ||
500 | if (temp < val[i]) { | ||
501 | temp = val[i]; | ||
502 | j = i; | ||
503 | } | ||
504 | } | ||
505 | |||
506 | /* Find MIN val */ | ||
507 | temp = val[4]; | ||
508 | k=4; | ||
509 | for (i=3; i>=0; i--) { | ||
510 | if (temp > val[i]) { | ||
511 | temp = val[i]; | ||
512 | k = i; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | for (i=0; i<5; i++) | ||
517 | if (i != j && i != k ) | ||
518 | sum += val[i]; | ||
519 | |||
520 | dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]); | ||
521 | |||
522 | return (sum/3); | ||
523 | } | ||
524 | |||
525 | /* mode 0 - Check temperature and voltage | ||
526 | * 1 - Check temperature only */ | ||
527 | static int sharpsl_check_battery(int mode) | ||
528 | { | ||
529 | int val, i, buff[5]; | ||
530 | |||
531 | /* Check battery temperature */ | ||
532 | for (i=0; i<5; i++) { | ||
533 | mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); | ||
534 | buff[i] = sharpsl_read_Temp(); | ||
535 | } | ||
536 | |||
537 | val = get_select_val(buff); | ||
538 | |||
539 | dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val); | ||
540 | if (val > SHARPSL_CHARGE_ON_TEMP) | ||
541 | return -1; | ||
542 | if (mode == 1) | ||
543 | return 0; | ||
544 | |||
545 | /* disable charge, enable discharge */ | ||
546 | CHARGE_OFF(); | ||
547 | DISCHARGE_ON(); | ||
548 | mdelay(SHARPSL_WAIT_DISCHARGE_ON); | ||
549 | |||
550 | if (sharpsl_pm.machinfo->discharge1) | ||
551 | sharpsl_pm.machinfo->discharge1(1); | ||
552 | |||
553 | /* Check battery voltage */ | ||
554 | for (i=0; i<5; i++) { | ||
555 | buff[i] = sharpsl_read_MainBattery(); | ||
556 | mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); | ||
557 | } | ||
558 | |||
559 | if (sharpsl_pm.machinfo->discharge1) | ||
560 | sharpsl_pm.machinfo->discharge1(0); | ||
561 | |||
562 | DISCHARGE_OFF(); | ||
563 | |||
564 | val = get_select_val(buff); | ||
565 | dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val); | ||
566 | |||
567 | if (val < SHARPSL_CHARGE_ON_VOLT) | ||
568 | return -1; | ||
569 | |||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | static int sharpsl_ac_check(void) | ||
574 | { | ||
575 | int temp, i, buff[5]; | ||
576 | |||
577 | for (i=0; i<5; i++) { | ||
578 | buff[i] = sharpsl_read_jkvad(); | ||
579 | mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD); | ||
580 | } | ||
581 | |||
582 | temp = get_select_val(buff); | ||
583 | dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp); | ||
584 | |||
585 | if ((temp > SHARPSL_CHARGE_ON_JKVAD_HIGH) || (temp < SHARPSL_CHARGE_ON_JKVAD_LOW)) { | ||
586 | dev_err(sharpsl_pm.dev, "Error: AC check failed.\n"); | ||
587 | return -1; | ||
588 | } | ||
589 | |||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | #ifdef CONFIG_PM | ||
594 | static int sharpsl_pm_suspend(struct device *dev, pm_message_t state) | ||
595 | { | ||
596 | sharpsl_pm.flags |= SHARPSL_SUSPENDED; | ||
597 | flush_scheduled_work(); | ||
598 | |||
599 | if (sharpsl_pm.charge_mode == CHRG_ON) | ||
600 | sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG; | ||
601 | else | ||
602 | sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; | ||
603 | |||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | static int sharpsl_pm_resume(struct device *dev) | ||
608 | { | ||
609 | /* Clear the reset source indicators as they break the bootloader upon reboot */ | ||
610 | RCSR = 0x0f; | ||
611 | sharpsl_average_clear(); | ||
612 | sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED; | ||
613 | sharpsl_pm.flags &= ~SHARPSL_SUSPENDED; | ||
614 | |||
615 | return 0; | ||
616 | } | ||
617 | |||
618 | static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) | ||
619 | { | ||
620 | dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR); | ||
621 | |||
622 | dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG); | ||
623 | /* not charging and AC-IN! */ | ||
624 | |||
625 | if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN != 0)) { | ||
626 | dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n"); | ||
627 | sharpsl_pm.charge_mode = CHRG_OFF; | ||
628 | sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; | ||
629 | sharpsl_off_charge_battery(); | ||
630 | } | ||
631 | |||
632 | sharpsl_pm.machinfo->presuspend(); | ||
633 | |||
634 | PEDR = 0xffffffff; /* clear it */ | ||
635 | |||
636 | sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE; | ||
637 | if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) { | ||
638 | RTSR &= RTSR_ALE; | ||
639 | RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND; | ||
640 | dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR); | ||
641 | sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE; | ||
642 | } else if (alarm_enable) { | ||
643 | RTSR &= RTSR_ALE; | ||
644 | RTAR = alarm_time; | ||
645 | dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR); | ||
646 | } else { | ||
647 | dev_dbg(sharpsl_pm.dev, "No alarms set.\n"); | ||
648 | } | ||
649 | |||
650 | pxa_pm_enter(state); | ||
651 | |||
652 | sharpsl_pm.machinfo->postsuspend(); | ||
653 | |||
654 | dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR); | ||
655 | } | ||
656 | |||
657 | static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) | ||
658 | { | ||
659 | if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) ) | ||
660 | { | ||
661 | if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) { | ||
662 | dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n"); | ||
663 | corgi_goto_sleep(alarm_time, alarm_enable, state); | ||
664 | return 1; | ||
665 | } | ||
666 | if(sharpsl_off_charge_battery()) { | ||
667 | dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n"); | ||
668 | corgi_goto_sleep(alarm_time, alarm_enable, state); | ||
669 | return 1; | ||
670 | } | ||
671 | dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); | ||
672 | } | ||
673 | |||
674 | if ((STATUS_BATT_LOCKED == 0) || (sharpsl_fatal_check() < 0) ) | ||
675 | { | ||
676 | dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); | ||
677 | corgi_goto_sleep(alarm_time, alarm_enable, state); | ||
678 | return 1; | ||
679 | } | ||
680 | |||
681 | return 0; | ||
682 | } | ||
683 | |||
684 | static int corgi_pxa_pm_enter(suspend_state_t state) | ||
685 | { | ||
686 | unsigned long alarm_time = RTAR; | ||
687 | unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0); | ||
688 | |||
689 | dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n"); | ||
690 | |||
691 | corgi_goto_sleep(alarm_time, alarm_status, state); | ||
692 | |||
693 | while (corgi_enter_suspend(alarm_time,alarm_status,state)) | ||
694 | {} | ||
695 | |||
696 | dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n"); | ||
697 | |||
698 | return 0; | ||
699 | } | ||
700 | #endif | ||
701 | |||
702 | |||
703 | /* | ||
704 | * Check for fatal battery errors | ||
705 | * Fatal returns -1 | ||
706 | */ | ||
707 | static int sharpsl_fatal_check(void) | ||
708 | { | ||
709 | int buff[5], temp, i, acin; | ||
710 | |||
711 | dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n"); | ||
712 | |||
713 | /* Check AC-Adapter */ | ||
714 | acin = STATUS_AC_IN; | ||
715 | |||
716 | if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { | ||
717 | CHARGE_OFF(); | ||
718 | udelay(100); | ||
719 | DISCHARGE_ON(); /* enable discharge */ | ||
720 | mdelay(SHARPSL_WAIT_DISCHARGE_ON); | ||
721 | } | ||
722 | |||
723 | if (sharpsl_pm.machinfo->discharge1) | ||
724 | sharpsl_pm.machinfo->discharge1(1); | ||
725 | |||
726 | /* Check battery : check inserting battery ? */ | ||
727 | for (i=0; i<5; i++) { | ||
728 | buff[i] = sharpsl_read_MainBattery(); | ||
729 | mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); | ||
730 | } | ||
731 | |||
732 | if (sharpsl_pm.machinfo->discharge1) | ||
733 | sharpsl_pm.machinfo->discharge1(0); | ||
734 | |||
735 | if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { | ||
736 | udelay(100); | ||
737 | CHARGE_ON(); | ||
738 | DISCHARGE_OFF(); | ||
739 | } | ||
740 | |||
741 | temp = get_select_val(buff); | ||
742 | dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_MainBattery()); | ||
743 | |||
744 | if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) || | ||
745 | (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT))) | ||
746 | return -1; | ||
747 | return 0; | ||
748 | } | ||
749 | |||
750 | static int sharpsl_off_charge_error(void) | ||
751 | { | ||
752 | dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n"); | ||
753 | CHARGE_OFF(); | ||
754 | CHARGE_LED_ERR(); | ||
755 | sharpsl_pm.charge_mode = CHRG_ERROR; | ||
756 | return 1; | ||
757 | } | ||
758 | |||
759 | /* | ||
760 | * Charging Control while suspended | ||
761 | * Return 1 - go straight to sleep | ||
762 | * Return 0 - sleep or wakeup depending on other factors | ||
763 | */ | ||
764 | static int sharpsl_off_charge_battery(void) | ||
765 | { | ||
766 | int time; | ||
767 | |||
768 | dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode); | ||
769 | |||
770 | if (sharpsl_pm.charge_mode == CHRG_OFF) { | ||
771 | dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n"); | ||
772 | |||
773 | /* AC Check */ | ||
774 | if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery(1) < 0)) | ||
775 | return sharpsl_off_charge_error(); | ||
776 | |||
777 | /* Start Charging */ | ||
778 | CHARGE_LED_ON(); | ||
779 | CHARGE_OFF(); | ||
780 | mdelay(SHARPSL_CHARGE_WAIT_TIME); | ||
781 | CHARGE_ON(); | ||
782 | |||
783 | sharpsl_pm.charge_mode = CHRG_ON; | ||
784 | sharpsl_pm.full_count = 0; | ||
785 | |||
786 | return 1; | ||
787 | } else if (sharpsl_pm.charge_mode != CHRG_ON) { | ||
788 | return 1; | ||
789 | } | ||
790 | |||
791 | if (sharpsl_pm.full_count == 0) { | ||
792 | int time; | ||
793 | |||
794 | dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n"); | ||
795 | |||
796 | if (sharpsl_check_battery(0) < 0) | ||
797 | return sharpsl_off_charge_error(); | ||
798 | |||
799 | CHARGE_OFF(); | ||
800 | mdelay(SHARPSL_CHARGE_WAIT_TIME); | ||
801 | CHARGE_ON(); | ||
802 | sharpsl_pm.charge_mode = CHRG_ON; | ||
803 | |||
804 | mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); | ||
805 | |||
806 | time = RCNR; | ||
807 | while(1) { | ||
808 | /* Check if any wakeup event had occured */ | ||
809 | if (sharpsl_pm.machinfo->charger_wakeup() != 0) | ||
810 | return 0; | ||
811 | /* Check for timeout */ | ||
812 | if ((RCNR - time) > SHARPSL_WAIT_CO_TIME) | ||
813 | return 1; | ||
814 | if (STATUS_CHRG_FULL) { | ||
815 | dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n"); | ||
816 | sharpsl_pm.full_count++; | ||
817 | CHARGE_OFF(); | ||
818 | mdelay(SHARPSL_CHARGE_WAIT_TIME); | ||
819 | CHARGE_ON(); | ||
820 | return 1; | ||
821 | } | ||
822 | } | ||
823 | } | ||
824 | |||
825 | dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n"); | ||
826 | |||
827 | mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); | ||
828 | |||
829 | time = RCNR; | ||
830 | while(1) { | ||
831 | /* Check if any wakeup event had occured */ | ||
832 | if (sharpsl_pm.machinfo->charger_wakeup() != 0) | ||
833 | return 0; | ||
834 | /* Check for timeout */ | ||
835 | if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) { | ||
836 | if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) { | ||
837 | dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n"); | ||
838 | sharpsl_pm.full_count = 0; | ||
839 | } | ||
840 | sharpsl_pm.full_count++; | ||
841 | return 1; | ||
842 | } | ||
843 | if (STATUS_CHRG_FULL) { | ||
844 | dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n"); | ||
845 | CHARGE_LED_OFF(); | ||
846 | CHARGE_OFF(); | ||
847 | sharpsl_pm.charge_mode = CHRG_DONE; | ||
848 | return 1; | ||
849 | } | ||
850 | } | ||
851 | } | ||
852 | |||
853 | |||
854 | static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
855 | { | ||
856 | return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent); | ||
857 | } | ||
858 | |||
859 | static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
860 | { | ||
861 | return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage); | ||
862 | } | ||
863 | |||
864 | static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL); | ||
865 | static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL); | ||
866 | |||
867 | extern void (*apm_get_power_status)(struct apm_power_info *); | ||
868 | |||
869 | static void sharpsl_apm_get_power_status(struct apm_power_info *info) | ||
870 | { | ||
871 | info->ac_line_status = sharpsl_pm.battstat.ac_status; | ||
872 | |||
873 | if (sharpsl_pm.charge_mode == CHRG_ON) | ||
874 | info->battery_status = APM_BATTERY_STATUS_CHARGING; | ||
875 | else | ||
876 | info->battery_status = sharpsl_pm.battstat.mainbat_status; | ||
877 | |||
878 | info->battery_flag = (1 << info->battery_status); | ||
879 | info->battery_life = sharpsl_pm.battstat.mainbat_percent; | ||
880 | } | ||
881 | |||
882 | static struct pm_ops sharpsl_pm_ops = { | ||
883 | .pm_disk_mode = PM_DISK_FIRMWARE, | ||
884 | .prepare = pxa_pm_prepare, | ||
885 | .enter = corgi_pxa_pm_enter, | ||
886 | .finish = pxa_pm_finish, | ||
887 | }; | ||
888 | |||
889 | static int __init sharpsl_pm_probe(struct device *dev) | ||
890 | { | ||
891 | if (!dev->platform_data) | ||
892 | return -EINVAL; | ||
893 | |||
894 | sharpsl_pm.dev = dev; | ||
895 | sharpsl_pm.machinfo = dev->platform_data; | ||
896 | sharpsl_pm.charge_mode = CHRG_OFF; | ||
897 | sharpsl_pm.flags = 0; | ||
898 | |||
899 | sharpsl_pm.machinfo->init(); | ||
900 | |||
901 | init_timer(&sharpsl_pm.ac_timer); | ||
902 | sharpsl_pm.ac_timer.function = sharpsl_ac_timer; | ||
903 | |||
904 | init_timer(&sharpsl_pm.chrg_full_timer); | ||
905 | sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; | ||
906 | |||
907 | pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN); | ||
908 | pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN); | ||
909 | pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN); | ||
910 | |||
911 | /* Register interrupt handlers */ | ||
912 | if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, SA_INTERRUPT, "AC Input Detect", sharpsl_ac_isr)) { | ||
913 | dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin)); | ||
914 | } | ||
915 | else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE); | ||
916 | |||
917 | if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, SA_INTERRUPT, "Battery Cover", sharpsl_fatal_isr)) { | ||
918 | dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock)); | ||
919 | } | ||
920 | else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING); | ||
921 | |||
922 | if (sharpsl_pm.machinfo->gpio_fatal) { | ||
923 | if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, SA_INTERRUPT, "Fatal Battery", sharpsl_fatal_isr)) { | ||
924 | dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal)); | ||
925 | } | ||
926 | else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING); | ||
927 | } | ||
928 | |||
929 | if (!machine_is_corgi()) | ||
930 | { | ||
931 | /* Register interrupt handler. */ | ||
932 | if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, SA_INTERRUPT, "CO", sharpsl_chrg_full_isr)) { | ||
933 | dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull)); | ||
934 | } | ||
935 | else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING); | ||
936 | } | ||
937 | |||
938 | device_create_file(dev, &dev_attr_battery_percentage); | ||
939 | device_create_file(dev, &dev_attr_battery_voltage); | ||
940 | |||
941 | apm_get_power_status = sharpsl_apm_get_power_status; | ||
942 | |||
943 | pm_set_ops(&sharpsl_pm_ops); | ||
944 | |||
945 | mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); | ||
946 | |||
947 | return 0; | ||
948 | } | ||
949 | |||
950 | static int sharpsl_pm_remove(struct device *dev) | ||
951 | { | ||
952 | pm_set_ops(NULL); | ||
953 | |||
954 | device_remove_file(dev, &dev_attr_battery_percentage); | ||
955 | device_remove_file(dev, &dev_attr_battery_voltage); | ||
956 | |||
957 | free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); | ||
958 | free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); | ||
959 | |||
960 | if (sharpsl_pm.machinfo->gpio_fatal) | ||
961 | free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr); | ||
962 | |||
963 | if (!machine_is_corgi()) | ||
964 | free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); | ||
965 | |||
966 | del_timer_sync(&sharpsl_pm.chrg_full_timer); | ||
967 | del_timer_sync(&sharpsl_pm.ac_timer); | ||
968 | |||
969 | return 0; | ||
970 | } | ||
971 | |||
972 | static struct device_driver sharpsl_pm_driver = { | ||
973 | .name = "sharpsl-pm", | ||
974 | .bus = &platform_bus_type, | ||
975 | .probe = sharpsl_pm_probe, | ||
976 | .remove = sharpsl_pm_remove, | ||
977 | .suspend = sharpsl_pm_suspend, | ||
978 | .resume = sharpsl_pm_resume, | ||
979 | }; | ||
980 | |||
981 | static int __devinit sharpsl_pm_init(void) | ||
982 | { | ||
983 | return driver_register(&sharpsl_pm_driver); | ||
984 | } | ||
985 | |||
986 | static void sharpsl_pm_exit(void) | ||
987 | { | ||
988 | driver_unregister(&sharpsl_pm_driver); | ||
989 | } | ||
990 | |||
991 | late_initcall(sharpsl_pm_init); | ||
992 | module_exit(sharpsl_pm_exit); | ||
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c index 4d826c021315..a68b30eff4d2 100644 --- a/arch/arm/mach-pxa/ssp.c +++ b/arch/arm/mach-pxa/ssp.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * 22nd Aug 2003 Initial version. | 19 | * 22nd Aug 2003 Initial version. |
20 | * 20th Dec 2004 Added ssp_config for changing port config without | 20 | * 20th Dec 2004 Added ssp_config for changing port config without |
21 | * closing the port. | 21 | * closing the port. |
22 | * 4th Aug 2005 Added option to disable irq handler registration and | ||
23 | * cleaned up irq and clock detection. | ||
22 | */ | 24 | */ |
23 | 25 | ||
24 | #include <linux/module.h> | 26 | #include <linux/module.h> |
@@ -37,6 +39,26 @@ | |||
37 | 39 | ||
38 | #define PXA_SSP_PORTS 3 | 40 | #define PXA_SSP_PORTS 3 |
39 | 41 | ||
42 | struct ssp_info_ { | ||
43 | int irq; | ||
44 | u32 clock; | ||
45 | }; | ||
46 | |||
47 | /* | ||
48 | * SSP port clock and IRQ settings | ||
49 | */ | ||
50 | static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = { | ||
51 | #if defined (CONFIG_PXA27x) | ||
52 | {IRQ_SSP, CKEN23_SSP1}, | ||
53 | {IRQ_SSP2, CKEN3_SSP2}, | ||
54 | {IRQ_SSP3, CKEN4_SSP3}, | ||
55 | #else | ||
56 | {IRQ_SSP, CKEN3_SSP}, | ||
57 | {IRQ_NSSP, CKEN9_NSSP}, | ||
58 | {IRQ_ASSP, CKEN10_ASSP}, | ||
59 | #endif | ||
60 | }; | ||
61 | |||
40 | static DECLARE_MUTEX(sem); | 62 | static DECLARE_MUTEX(sem); |
41 | static int use_count[PXA_SSP_PORTS] = {0, 0, 0}; | 63 | static int use_count[PXA_SSP_PORTS] = {0, 0, 0}; |
42 | 64 | ||
@@ -210,9 +232,9 @@ int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 spee | |||
210 | * %-EBUSY if the resources are already in use | 232 | * %-EBUSY if the resources are already in use |
211 | * %0 on success | 233 | * %0 on success |
212 | */ | 234 | */ |
213 | int ssp_init(struct ssp_dev *dev, u32 port) | 235 | int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags) |
214 | { | 236 | { |
215 | int ret, irq; | 237 | int ret; |
216 | 238 | ||
217 | if (port > PXA_SSP_PORTS || port == 0) | 239 | if (port > PXA_SSP_PORTS || port == 0) |
218 | return -ENODEV; | 240 | return -ENODEV; |
@@ -229,61 +251,20 @@ int ssp_init(struct ssp_dev *dev, u32 port) | |||
229 | up(&sem); | 251 | up(&sem); |
230 | return -EBUSY; | 252 | return -EBUSY; |
231 | } | 253 | } |
232 | |||
233 | switch (port) { | ||
234 | case 1: | ||
235 | irq = IRQ_SSP; | ||
236 | break; | ||
237 | #if defined (CONFIG_PXA27x) | ||
238 | case 2: | ||
239 | irq = IRQ_SSP2; | ||
240 | break; | ||
241 | case 3: | ||
242 | irq = IRQ_SSP3; | ||
243 | break; | ||
244 | #else | ||
245 | case 2: | ||
246 | irq = IRQ_NSSP; | ||
247 | break; | ||
248 | case 3: | ||
249 | irq = IRQ_ASSP; | ||
250 | break; | ||
251 | #endif | ||
252 | default: | ||
253 | return -ENODEV; | ||
254 | } | ||
255 | |||
256 | dev->port = port; | 254 | dev->port = port; |
257 | 255 | ||
258 | ret = request_irq(irq, ssp_interrupt, 0, "SSP", dev); | 256 | /* do we need to get irq */ |
259 | if (ret) | 257 | if (!(init_flags & SSP_NO_IRQ)) { |
260 | goto out_region; | 258 | ret = request_irq(ssp_info[port-1].irq, ssp_interrupt, |
259 | 0, "SSP", dev); | ||
260 | if (ret) | ||
261 | goto out_region; | ||
262 | dev->irq = ssp_info[port-1].irq; | ||
263 | } else | ||
264 | dev->irq = 0; | ||
261 | 265 | ||
262 | /* turn on SSP port clock */ | 266 | /* turn on SSP port clock */ |
263 | switch (dev->port) { | 267 | pxa_set_cken(ssp_info[port-1].clock, 1); |
264 | #if defined (CONFIG_PXA27x) | ||
265 | case 1: | ||
266 | pxa_set_cken(CKEN23_SSP1, 1); | ||
267 | break; | ||
268 | case 2: | ||
269 | pxa_set_cken(CKEN3_SSP2, 1); | ||
270 | break; | ||
271 | case 3: | ||
272 | pxa_set_cken(CKEN4_SSP3, 1); | ||
273 | break; | ||
274 | #else | ||
275 | case 1: | ||
276 | pxa_set_cken(CKEN3_SSP, 1); | ||
277 | break; | ||
278 | case 2: | ||
279 | pxa_set_cken(CKEN9_NSSP, 1); | ||
280 | break; | ||
281 | case 3: | ||
282 | pxa_set_cken(CKEN10_ASSP, 1); | ||
283 | break; | ||
284 | #endif | ||
285 | } | ||
286 | |||
287 | up(&sem); | 268 | up(&sem); |
288 | return 0; | 269 | return 0; |
289 | 270 | ||
@@ -301,46 +282,17 @@ out_region: | |||
301 | */ | 282 | */ |
302 | void ssp_exit(struct ssp_dev *dev) | 283 | void ssp_exit(struct ssp_dev *dev) |
303 | { | 284 | { |
304 | int irq; | ||
305 | |||
306 | down(&sem); | 285 | down(&sem); |
307 | SSCR0_P(dev->port) &= ~SSCR0_SSE; | 286 | SSCR0_P(dev->port) &= ~SSCR0_SSE; |
308 | 287 | ||
309 | /* find irq, save power and turn off SSP port clock */ | 288 | if (dev->port > PXA_SSP_PORTS || dev->port == 0) { |
310 | switch (dev->port) { | 289 | printk(KERN_WARNING "SSP: tried to close invalid port\n"); |
311 | #if defined (CONFIG_PXA27x) | 290 | return; |
312 | case 1: | ||
313 | irq = IRQ_SSP; | ||
314 | pxa_set_cken(CKEN23_SSP1, 0); | ||
315 | break; | ||
316 | case 2: | ||
317 | irq = IRQ_SSP2; | ||
318 | pxa_set_cken(CKEN3_SSP2, 0); | ||
319 | break; | ||
320 | case 3: | ||
321 | irq = IRQ_SSP3; | ||
322 | pxa_set_cken(CKEN4_SSP3, 0); | ||
323 | break; | ||
324 | #else | ||
325 | case 1: | ||
326 | irq = IRQ_SSP; | ||
327 | pxa_set_cken(CKEN3_SSP, 0); | ||
328 | break; | ||
329 | case 2: | ||
330 | irq = IRQ_NSSP; | ||
331 | pxa_set_cken(CKEN9_NSSP, 0); | ||
332 | break; | ||
333 | case 3: | ||
334 | irq = IRQ_ASSP; | ||
335 | pxa_set_cken(CKEN10_ASSP, 0); | ||
336 | break; | ||
337 | #endif | ||
338 | default: | ||
339 | printk(KERN_WARNING "SSP: tried to close invalid port\n"); | ||
340 | return; | ||
341 | } | 291 | } |
342 | 292 | ||
343 | free_irq(irq, dev); | 293 | pxa_set_cken(ssp_info[dev->port-1].clock, 0); |
294 | if (dev->irq) | ||
295 | free_irq(dev->irq, dev); | ||
344 | release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c); | 296 | release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c); |
345 | use_count[dev->port - 1]--; | 297 | use_count[dev->port - 1]--; |
346 | up(&sem); | 298 | up(&sem); |
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile index 011a85c10627..36e76ba937fc 100644 --- a/arch/arm/mach-realview/Makefile +++ b/arch/arm/mach-realview/Makefile | |||
@@ -5,3 +5,5 @@ | |||
5 | obj-y := core.o clock.o | 5 | obj-y := core.o clock.o |
6 | obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o | 6 | obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o |
7 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 7 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
8 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | ||
9 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | ||
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 4ea60d8b6e36..e2c6fa23d3cd 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -550,7 +550,7 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_reg | |||
550 | 550 | ||
551 | timer_tick(regs); | 551 | timer_tick(regs); |
552 | 552 | ||
553 | #ifdef CONFIG_SMP | 553 | #if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS) |
554 | smp_send_timer(); | 554 | smp_send_timer(); |
555 | update_process_times(user_mode(regs)); | 555 | update_process_times(user_mode(regs)); |
556 | #endif | 556 | #endif |
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c new file mode 100644 index 000000000000..09748cbcd10e --- /dev/null +++ b/arch/arm/mach-realview/hotplug.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-realview/hotplug.c | ||
3 | * | ||
4 | * Copyright (C) 2002 ARM Ltd. | ||
5 | * All Rights Reserved | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/smp.h> | ||
14 | #include <linux/completion.h> | ||
15 | |||
16 | extern volatile int pen_release; | ||
17 | |||
18 | static DECLARE_COMPLETION(cpu_killed); | ||
19 | |||
20 | static inline void cpu_enter_lowpower(void) | ||
21 | { | ||
22 | unsigned int v; | ||
23 | |||
24 | asm volatile( "mcr p15, 0, %1, c7, c14, 0\n" | ||
25 | " mcr p15, 0, %1, c7, c5, 0\n" | ||
26 | " mcr p15, 0, %1, c7, c10, 4\n" | ||
27 | /* | ||
28 | * Turn off coherency | ||
29 | */ | ||
30 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
31 | " bic %0, %0, #0x20\n" | ||
32 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
33 | " mrc p15, 0, %0, c1, c0, 0\n" | ||
34 | " bic %0, %0, #0x04\n" | ||
35 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
36 | : "=&r" (v) | ||
37 | : "r" (0) | ||
38 | : "cc"); | ||
39 | } | ||
40 | |||
41 | static inline void cpu_leave_lowpower(void) | ||
42 | { | ||
43 | unsigned int v; | ||
44 | |||
45 | asm volatile( "mrc p15, 0, %0, c1, c0, 0\n" | ||
46 | " orr %0, %0, #0x04\n" | ||
47 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
48 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
49 | " orr %0, %0, #0x20\n" | ||
50 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
51 | : "=&r" (v) | ||
52 | : | ||
53 | : "cc"); | ||
54 | } | ||
55 | |||
56 | static inline void platform_do_lowpower(unsigned int cpu) | ||
57 | { | ||
58 | /* | ||
59 | * there is no power-control hardware on this platform, so all | ||
60 | * we can do is put the core into WFI; this is safe as the calling | ||
61 | * code will have already disabled interrupts | ||
62 | */ | ||
63 | for (;;) { | ||
64 | /* | ||
65 | * here's the WFI | ||
66 | */ | ||
67 | asm(".word 0xe320f003\n" | ||
68 | : | ||
69 | : | ||
70 | : "memory", "cc"); | ||
71 | |||
72 | if (pen_release == cpu) { | ||
73 | /* | ||
74 | * OK, proper wakeup, we're done | ||
75 | */ | ||
76 | break; | ||
77 | } | ||
78 | |||
79 | /* | ||
80 | * getting here, means that we have come out of WFI without | ||
81 | * having been woken up - this shouldn't happen | ||
82 | * | ||
83 | * The trouble is, letting people know about this is not really | ||
84 | * possible, since we are currently running incoherently, and | ||
85 | * therefore cannot safely call printk() or anything else | ||
86 | */ | ||
87 | #ifdef DEBUG | ||
88 | printk("CPU%u: spurious wakeup call\n", cpu); | ||
89 | #endif | ||
90 | } | ||
91 | } | ||
92 | |||
93 | int platform_cpu_kill(unsigned int cpu) | ||
94 | { | ||
95 | return wait_for_completion_timeout(&cpu_killed, 5000); | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * platform-specific code to shutdown a CPU | ||
100 | * | ||
101 | * Called with IRQs disabled | ||
102 | */ | ||
103 | void platform_cpu_die(unsigned int cpu) | ||
104 | { | ||
105 | #ifdef DEBUG | ||
106 | unsigned int this_cpu = hard_smp_processor_id(); | ||
107 | |||
108 | if (cpu != this_cpu) { | ||
109 | printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n", | ||
110 | this_cpu, cpu); | ||
111 | BUG(); | ||
112 | } | ||
113 | #endif | ||
114 | |||
115 | printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); | ||
116 | complete(&cpu_killed); | ||
117 | |||
118 | /* | ||
119 | * we're ready for shutdown now, so do it | ||
120 | */ | ||
121 | cpu_enter_lowpower(); | ||
122 | platform_do_lowpower(cpu); | ||
123 | |||
124 | /* | ||
125 | * bring this CPU back into the world of cache | ||
126 | * coherency, and then restore interrupts | ||
127 | */ | ||
128 | cpu_leave_lowpower(); | ||
129 | } | ||
130 | |||
131 | int mach_cpu_disable(unsigned int cpu) | ||
132 | { | ||
133 | /* | ||
134 | * we don't allow CPU 0 to be shutdown (it is still too special | ||
135 | * e.g. clock tick interrupts) | ||
136 | */ | ||
137 | return cpu == 0 ? -EPERM : 0; | ||
138 | } | ||
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c new file mode 100644 index 000000000000..5e917e37d095 --- /dev/null +++ b/arch/arm/mach-realview/localtimer.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-realview/localtimer.c | ||
3 | * | ||
4 | * Copyright (C) 2002 ARM Ltd. | ||
5 | * All Rights Reserved | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/smp.h> | ||
16 | |||
17 | #include <asm/mach/time.h> | ||
18 | #include <asm/hardware/arm_twd.h> | ||
19 | #include <asm/hardware/gic.h> | ||
20 | #include <asm/hardware.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/irq.h> | ||
23 | |||
24 | #include "core.h" | ||
25 | |||
26 | #define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \ | ||
27 | ((cpu) * REALVIEW_TWD_SIZE)) | ||
28 | |||
29 | static unsigned long mpcore_timer_rate; | ||
30 | |||
31 | /* | ||
32 | * local_timer_ack: checks for a local timer interrupt. | ||
33 | * | ||
34 | * If a local timer interrupt has occured, acknowledge and return 1. | ||
35 | * Otherwise, return 0. | ||
36 | */ | ||
37 | int local_timer_ack(void) | ||
38 | { | ||
39 | void __iomem *base = TWD_BASE(smp_processor_id()); | ||
40 | |||
41 | if (__raw_readl(base + TWD_TIMER_INTSTAT)) { | ||
42 | __raw_writel(1, base + TWD_TIMER_INTSTAT); | ||
43 | return 1; | ||
44 | } | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | void __cpuinit local_timer_setup(unsigned int cpu) | ||
50 | { | ||
51 | void __iomem *base = TWD_BASE(cpu); | ||
52 | unsigned int load, offset; | ||
53 | u64 waitjiffies; | ||
54 | unsigned int count; | ||
55 | |||
56 | /* | ||
57 | * If this is the first time round, we need to work out how fast | ||
58 | * the timer ticks | ||
59 | */ | ||
60 | if (mpcore_timer_rate == 0) { | ||
61 | printk("Calibrating local timer... "); | ||
62 | |||
63 | /* Wait for a tick to start */ | ||
64 | waitjiffies = get_jiffies_64() + 1; | ||
65 | |||
66 | while (get_jiffies_64() < waitjiffies) | ||
67 | udelay(10); | ||
68 | |||
69 | /* OK, now the tick has started, let's get the timer going */ | ||
70 | waitjiffies += 5; | ||
71 | |||
72 | /* enable, no interrupt or reload */ | ||
73 | __raw_writel(0x1, base + TWD_TIMER_CONTROL); | ||
74 | |||
75 | /* maximum value */ | ||
76 | __raw_writel(0xFFFFFFFFU, base + TWD_TIMER_COUNTER); | ||
77 | |||
78 | while (get_jiffies_64() < waitjiffies) | ||
79 | udelay(10); | ||
80 | |||
81 | count = __raw_readl(base + TWD_TIMER_COUNTER); | ||
82 | |||
83 | mpcore_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); | ||
84 | |||
85 | printk("%lu.%02luMHz.\n", mpcore_timer_rate / 1000000, | ||
86 | (mpcore_timer_rate / 100000) % 100); | ||
87 | } | ||
88 | |||
89 | load = mpcore_timer_rate / HZ; | ||
90 | |||
91 | __raw_writel(load, base + TWD_TIMER_LOAD); | ||
92 | __raw_writel(0x7, base + TWD_TIMER_CONTROL); | ||
93 | |||
94 | /* | ||
95 | * Now maneuver our local tick into the right part of the jiffy. | ||
96 | * Start by working out where within the tick our local timer | ||
97 | * interrupt should go. | ||
98 | */ | ||
99 | offset = ((mpcore_timer_rate / HZ) / (NR_CPUS + 1)) * (cpu + 1); | ||
100 | |||
101 | /* | ||
102 | * gettimeoffset() will return a number of us since the last tick. | ||
103 | * Convert this number of us to a local timer tick count. | ||
104 | * Be careful of integer overflow whilst keeping maximum precision. | ||
105 | * | ||
106 | * with HZ=100 and 1MHz (fpga) ~ 1GHz processor: | ||
107 | * load = 1 ~ 10,000 | ||
108 | * mpcore_timer_rate/10000 = 100 ~ 100,000 | ||
109 | * | ||
110 | * so the multiply value will be less than 10^9 always. | ||
111 | */ | ||
112 | load = (system_timer->offset() * (mpcore_timer_rate / 10000)) / 100; | ||
113 | |||
114 | /* Add on our offset to get the load value */ | ||
115 | load = (load + offset) % (mpcore_timer_rate / HZ); | ||
116 | |||
117 | __raw_writel(load, base + TWD_TIMER_COUNTER); | ||
118 | |||
119 | /* Make sure our local interrupt controller has this enabled */ | ||
120 | __raw_writel(1 << IRQ_LOCALTIMER, | ||
121 | __io_address(REALVIEW_GIC_DIST_BASE) + GIC_DIST_ENABLE_SET); | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * take a local timer down | ||
126 | */ | ||
127 | void __cpuexit local_timer_stop(unsigned int cpu) | ||
128 | { | ||
129 | __raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL); | ||
130 | } | ||
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index 09b35f62247a..0c7d4ac9a7b3 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c | |||
@@ -175,6 +175,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
175 | max_cpus = ncores; | 175 | max_cpus = ncores; |
176 | 176 | ||
177 | /* | 177 | /* |
178 | * Enable the local timer for primary CPU | ||
179 | */ | ||
180 | local_timer_setup(cpu); | ||
181 | |||
182 | /* | ||
178 | * Initialise the possible/present maps. | 183 | * Initialise the possible/present maps. |
179 | * cpu_possible_map describes the set of CPUs which may be present | 184 | * cpu_possible_map describes the set of CPUs which may be present |
180 | * cpu_present_map describes the set of CPUs populated | 185 | * cpu_present_map describes the set of CPUs populated |
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c index 8390b685c2b6..0f81fc0c2f7f 100644 --- a/arch/arm/mach-s3c2410/mach-anubis.c +++ b/arch/arm/mach-s3c2410/mach-anubis.c | |||
@@ -56,8 +56,16 @@ | |||
56 | static struct map_desc anubis_iodesc[] __initdata = { | 56 | static struct map_desc anubis_iodesc[] __initdata = { |
57 | /* ISA IO areas */ | 57 | /* ISA IO areas */ |
58 | 58 | ||
59 | { (u32)S3C24XX_VA_ISA_BYTE, 0x0, SZ_16M, MT_DEVICE }, | 59 | { |
60 | { (u32)S3C24XX_VA_ISA_WORD, 0x0, SZ_16M, MT_DEVICE }, | 60 | .virtual = (u32)S3C24XX_VA_ISA_BYTE, |
61 | .pfn = __phys_to_pfn(0x0), | ||
62 | .length = SZ_4M, | ||
63 | .type = MT_DEVICE | ||
64 | }, { | ||
65 | .virtual = (u32)S3C24XX_VA_ISA_WORD, | ||
66 | .pfn = __phys_to_pfn(0x0), | ||
67 | .length = SZ_4M, MT_DEVICE | ||
68 | }, | ||
61 | 69 | ||
62 | /* we could possibly compress the next set down into a set of smaller tables | 70 | /* we could possibly compress the next set down into a set of smaller tables |
63 | * pagetables, but that would mean using an L2 section, and it still means | 71 | * pagetables, but that would mean using an L2 section, and it still means |
@@ -66,16 +74,41 @@ static struct map_desc anubis_iodesc[] __initdata = { | |||
66 | 74 | ||
67 | /* CPLD control registers */ | 75 | /* CPLD control registers */ |
68 | 76 | ||
69 | { (u32)ANUBIS_VA_CTRL1, ANUBIS_PA_CTRL1, SZ_4K, MT_DEVICE }, | 77 | { |
70 | { (u32)ANUBIS_VA_CTRL2, ANUBIS_PA_CTRL2, SZ_4K, MT_DEVICE }, | 78 | .virtual = (u32)ANUBIS_VA_CTRL1, |
79 | .pfn = __phys_to_pfn(ANUBIS_PA_CTRL1), | ||
80 | .length = SZ_4K, | ||
81 | .type = MT_DEVICE | ||
82 | }, { | ||
83 | .virtual = (u32)ANUBIS_VA_CTRL2, | ||
84 | .pfn = __phys_to_pfn(ANUBIS_PA_CTRL2), | ||
85 | .length = SZ_4K, | ||
86 | .type =MT_DEVICE | ||
87 | }, | ||
71 | 88 | ||
72 | /* IDE drives */ | 89 | /* IDE drives */ |
73 | 90 | ||
74 | { (u32)ANUBIS_IDEPRI, S3C2410_CS3, SZ_1M, MT_DEVICE }, | 91 | { |
75 | { (u32)ANUBIS_IDEPRIAUX, S3C2410_CS3+(1<<26), SZ_1M, MT_DEVICE }, | 92 | .virtual = (u32)ANUBIS_IDEPRI, |
76 | 93 | .pfn = __phys_to_pfn(S3C2410_CS3), | |
77 | { (u32)ANUBIS_IDESEC, S3C2410_CS4, SZ_1M, MT_DEVICE }, | 94 | .length = SZ_1M, |
78 | { (u32)ANUBIS_IDESECAUX, S3C2410_CS4+(1<<26), SZ_1M, MT_DEVICE }, | 95 | .type = MT_DEVICE |
96 | }, { | ||
97 | .virtual = (u32)ANUBIS_IDEPRIAUX, | ||
98 | .pfn = __phys_to_pfn(S3C2410_CS3+(1<<26)), | ||
99 | .length = SZ_1M, | ||
100 | .type = MT_DEVICE | ||
101 | }, { | ||
102 | .virtual = (u32)ANUBIS_IDESEC, | ||
103 | .pfn = __phys_to_pfn(S3C2410_CS4), | ||
104 | .length = SZ_1M, | ||
105 | .type = MT_DEVICE | ||
106 | }, { | ||
107 | .virtual = (u32)ANUBIS_IDESECAUX, | ||
108 | .pfn = __phys_to_pfn(S3C2410_CS4+(1<<26)), | ||
109 | .length = SZ_1M, | ||
110 | .type = MT_DEVICE | ||
111 | }, | ||
79 | }; | 112 | }; |
80 | 113 | ||
81 | #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK | 114 | #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK |
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c index 24d69019a843..f8d86d1e16b6 100644 --- a/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/arch/arm/mach-s3c2410/mach-rx3715.c | |||
@@ -56,8 +56,17 @@ | |||
56 | static struct map_desc rx3715_iodesc[] __initdata = { | 56 | static struct map_desc rx3715_iodesc[] __initdata = { |
57 | /* dump ISA space somewhere unused */ | 57 | /* dump ISA space somewhere unused */ |
58 | 58 | ||
59 | { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS3, SZ_16M, MT_DEVICE }, | 59 | { |
60 | { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS3, SZ_16M, MT_DEVICE }, | 60 | .virtual = (u32)S3C24XX_VA_ISA_WORD, |
61 | .pfn = __phys_to_pfn(S3C2410_CS3), | ||
62 | .length = SZ_1M, | ||
63 | .type = MT_DEVICE, | ||
64 | }, { | ||
65 | .virtual = (u32)S3C24XX_VA_ISA_BYTE, | ||
66 | .pfn = __phys_to_pfn(S3C2410_CS3), | ||
67 | .length = SZ_1M, | ||
68 | .type = MT_DEVICE, | ||
69 | }, | ||
61 | }; | 70 | }; |
62 | 71 | ||
63 | 72 | ||
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index d666c621ad06..4e31118533e6 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c | |||
@@ -58,8 +58,27 @@ | |||
58 | static struct map_desc smdk2440_iodesc[] __initdata = { | 58 | static struct map_desc smdk2440_iodesc[] __initdata = { |
59 | /* ISA IO Space map (memory space selected by A24) */ | 59 | /* ISA IO Space map (memory space selected by A24) */ |
60 | 60 | ||
61 | { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS2, SZ_16M, MT_DEVICE }, | 61 | { |
62 | { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS2, SZ_16M, MT_DEVICE }, | 62 | .virtual = (u32)S3C24XX_VA_ISA_WORD, |
63 | .pfn = __phys_to_pfn(S3C2410_CS2), | ||
64 | .length = 0x10000, | ||
65 | .type = MT_DEVICE, | ||
66 | }, { | ||
67 | .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000, | ||
68 | .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)), | ||
69 | .length = SZ_4M, | ||
70 | .type = MT_DEVICE, | ||
71 | }, { | ||
72 | .virtual = (u32)S3C24XX_VA_ISA_BYTE, | ||
73 | .pfn = __phys_to_pfn(S3C2410_CS2), | ||
74 | .length = 0x10000, | ||
75 | .type = MT_DEVICE, | ||
76 | }, { | ||
77 | .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000, | ||
78 | .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)), | ||
79 | .length = SZ_4M, | ||
80 | .type = MT_DEVICE, | ||
81 | } | ||
63 | }; | 82 | }; |
64 | 83 | ||
65 | #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK | 84 | #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index e3c14d6b4328..e84fdde6edf8 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -102,8 +102,8 @@ config CPU_ARM922T | |||
102 | # ARM925T | 102 | # ARM925T |
103 | config CPU_ARM925T | 103 | config CPU_ARM925T |
104 | bool "Support ARM925T processor" if ARCH_OMAP1 | 104 | bool "Support ARM925T processor" if ARCH_OMAP1 |
105 | depends on ARCH_OMAP1510 | 105 | depends on ARCH_OMAP15XX |
106 | default y if ARCH_OMAP1510 | 106 | default y if ARCH_OMAP15XX |
107 | select CPU_32v4 | 107 | select CPU_32v4 |
108 | select CPU_ABRT_EV4T | 108 | select CPU_ABRT_EV4T |
109 | select CPU_CACHE_V4WT | 109 | select CPU_CACHE_V4WT |
@@ -242,7 +242,7 @@ config CPU_XSCALE | |||
242 | # ARMv6 | 242 | # ARMv6 |
243 | config CPU_V6 | 243 | config CPU_V6 |
244 | bool "Support ARM V6 processor" | 244 | bool "Support ARM V6 processor" |
245 | depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB | 245 | depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 |
246 | select CPU_32v6 | 246 | select CPU_32v6 |
247 | select CPU_ABRT_EV6 | 247 | select CPU_ABRT_EV6 |
248 | select CPU_CACHE_V6 | 248 | select CPU_CACHE_V6 |
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 7e144f9cad1c..9ccf1943fc94 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := common.o sram.o sram-fn.o clock.o dma.o mux.o gpio.o mcbsp.o usb.o | 6 | obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o |
7 | obj-m := | 7 | obj-m := |
8 | obj-n := | 8 | obj-n := |
9 | obj- := | 9 | obj- := |
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index a020fe16428f..7ce39b986e23 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c | |||
@@ -1,15 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/plat-omap/clock.c | 2 | * linux/arch/arm/plat-omap/clock.c |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Nokia corporation | 4 | * Copyright (C) 2004 - 2005 Nokia corporation |
5 | * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> | 5 | * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> |
6 | * | 6 | * |
7 | * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com> | ||
8 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
10 | */ | 12 | */ |
11 | #include <linux/module.h> | 13 | #include <linux/version.h> |
14 | #include <linux/config.h> | ||
12 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | ||
17 | #include <linux/module.h> | ||
13 | #include <linux/list.h> | 18 | #include <linux/list.h> |
14 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
15 | #include <linux/err.h> | 20 | #include <linux/err.h> |
@@ -18,562 +23,20 @@ | |||
18 | #include <asm/io.h> | 23 | #include <asm/io.h> |
19 | #include <asm/semaphore.h> | 24 | #include <asm/semaphore.h> |
20 | #include <asm/hardware/clock.h> | 25 | #include <asm/hardware/clock.h> |
21 | #include <asm/arch/board.h> | ||
22 | #include <asm/arch/usb.h> | ||
23 | 26 | ||
24 | #include "clock.h" | 27 | #include <asm/arch/clock.h> |
25 | #include "sram.h" | ||
26 | 28 | ||
27 | static LIST_HEAD(clocks); | 29 | LIST_HEAD(clocks); |
28 | static DECLARE_MUTEX(clocks_sem); | 30 | static DECLARE_MUTEX(clocks_sem); |
29 | static DEFINE_SPINLOCK(clockfw_lock); | 31 | DEFINE_SPINLOCK(clockfw_lock); |
30 | static void propagate_rate(struct clk * clk); | ||
31 | /* UART clock function */ | ||
32 | static int set_uart_rate(struct clk * clk, unsigned long rate); | ||
33 | /* External clock (MCLK & BCLK) functions */ | ||
34 | static int set_ext_clk_rate(struct clk * clk, unsigned long rate); | ||
35 | static long round_ext_clk_rate(struct clk * clk, unsigned long rate); | ||
36 | static void init_ext_clk(struct clk * clk); | ||
37 | /* MPU virtual clock functions */ | ||
38 | static int select_table_rate(struct clk * clk, unsigned long rate); | ||
39 | static long round_to_table_rate(struct clk * clk, unsigned long rate); | ||
40 | void clk_setdpll(__u16, __u16); | ||
41 | |||
42 | static struct mpu_rate rate_table[] = { | ||
43 | /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL | ||
44 | * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv | ||
45 | */ | ||
46 | #if defined(CONFIG_OMAP_ARM_216MHZ) | ||
47 | { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */ | ||
48 | #endif | ||
49 | #if defined(CONFIG_OMAP_ARM_195MHZ) | ||
50 | { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */ | ||
51 | #endif | ||
52 | #if defined(CONFIG_OMAP_ARM_192MHZ) | ||
53 | { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */ | ||
54 | { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */ | ||
55 | { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */ | ||
56 | { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/8/4/4/8/8 */ | ||
57 | { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */ | ||
58 | #endif | ||
59 | #if defined(CONFIG_OMAP_ARM_182MHZ) | ||
60 | { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */ | ||
61 | #endif | ||
62 | #if defined(CONFIG_OMAP_ARM_168MHZ) | ||
63 | { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */ | ||
64 | #endif | ||
65 | #if defined(CONFIG_OMAP_ARM_150MHZ) | ||
66 | { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */ | ||
67 | #endif | ||
68 | #if defined(CONFIG_OMAP_ARM_120MHZ) | ||
69 | { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */ | ||
70 | #endif | ||
71 | #if defined(CONFIG_OMAP_ARM_96MHZ) | ||
72 | { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */ | ||
73 | #endif | ||
74 | #if defined(CONFIG_OMAP_ARM_60MHZ) | ||
75 | { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */ | ||
76 | #endif | ||
77 | #if defined(CONFIG_OMAP_ARM_30MHZ) | ||
78 | { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */ | ||
79 | #endif | ||
80 | { 0, 0, 0, 0, 0 }, | ||
81 | }; | ||
82 | |||
83 | |||
84 | static void ckctl_recalc(struct clk * clk); | ||
85 | int __clk_enable(struct clk *clk); | ||
86 | void __clk_disable(struct clk *clk); | ||
87 | void __clk_unuse(struct clk *clk); | ||
88 | int __clk_use(struct clk *clk); | ||
89 | |||
90 | |||
91 | static void followparent_recalc(struct clk * clk) | ||
92 | { | ||
93 | clk->rate = clk->parent->rate; | ||
94 | } | ||
95 | |||
96 | |||
97 | static void watchdog_recalc(struct clk * clk) | ||
98 | { | ||
99 | clk->rate = clk->parent->rate / 14; | ||
100 | } | ||
101 | |||
102 | static void uart_recalc(struct clk * clk) | ||
103 | { | ||
104 | unsigned int val = omap_readl(clk->enable_reg); | ||
105 | if (val & clk->enable_bit) | ||
106 | clk->rate = 48000000; | ||
107 | else | ||
108 | clk->rate = 12000000; | ||
109 | } | ||
110 | |||
111 | static struct clk ck_ref = { | ||
112 | .name = "ck_ref", | ||
113 | .rate = 12000000, | ||
114 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
115 | ALWAYS_ENABLED, | ||
116 | }; | ||
117 | |||
118 | static struct clk ck_dpll1 = { | ||
119 | .name = "ck_dpll1", | ||
120 | .parent = &ck_ref, | ||
121 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
122 | RATE_PROPAGATES | ALWAYS_ENABLED, | ||
123 | }; | ||
124 | |||
125 | static struct clk ck_dpll1out = { | ||
126 | .name = "ck_dpll1out", | ||
127 | .parent = &ck_dpll1, | ||
128 | .flags = CLOCK_IN_OMAP16XX, | ||
129 | .enable_reg = ARM_IDLECT2, | ||
130 | .enable_bit = EN_CKOUT_ARM, | ||
131 | .recalc = &followparent_recalc, | ||
132 | }; | ||
133 | |||
134 | static struct clk arm_ck = { | ||
135 | .name = "arm_ck", | ||
136 | .parent = &ck_dpll1, | ||
137 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
138 | RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, | ||
139 | .rate_offset = CKCTL_ARMDIV_OFFSET, | ||
140 | .recalc = &ckctl_recalc, | ||
141 | }; | ||
142 | |||
143 | static struct clk armper_ck = { | ||
144 | .name = "armper_ck", | ||
145 | .parent = &ck_dpll1, | ||
146 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
147 | RATE_CKCTL, | ||
148 | .enable_reg = ARM_IDLECT2, | ||
149 | .enable_bit = EN_PERCK, | ||
150 | .rate_offset = CKCTL_PERDIV_OFFSET, | ||
151 | .recalc = &ckctl_recalc, | ||
152 | }; | ||
153 | |||
154 | static struct clk arm_gpio_ck = { | ||
155 | .name = "arm_gpio_ck", | ||
156 | .parent = &ck_dpll1, | ||
157 | .flags = CLOCK_IN_OMAP1510, | ||
158 | .enable_reg = ARM_IDLECT2, | ||
159 | .enable_bit = EN_GPIOCK, | ||
160 | .recalc = &followparent_recalc, | ||
161 | }; | ||
162 | |||
163 | static struct clk armxor_ck = { | ||
164 | .name = "armxor_ck", | ||
165 | .parent = &ck_ref, | ||
166 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, | ||
167 | .enable_reg = ARM_IDLECT2, | ||
168 | .enable_bit = EN_XORPCK, | ||
169 | .recalc = &followparent_recalc, | ||
170 | }; | ||
171 | |||
172 | static struct clk armtim_ck = { | ||
173 | .name = "armtim_ck", | ||
174 | .parent = &ck_ref, | ||
175 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, | ||
176 | .enable_reg = ARM_IDLECT2, | ||
177 | .enable_bit = EN_TIMCK, | ||
178 | .recalc = &followparent_recalc, | ||
179 | }; | ||
180 | |||
181 | static struct clk armwdt_ck = { | ||
182 | .name = "armwdt_ck", | ||
183 | .parent = &ck_ref, | ||
184 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, | ||
185 | .enable_reg = ARM_IDLECT2, | ||
186 | .enable_bit = EN_WDTCK, | ||
187 | .recalc = &watchdog_recalc, | ||
188 | }; | ||
189 | |||
190 | static struct clk arminth_ck16xx = { | ||
191 | .name = "arminth_ck", | ||
192 | .parent = &arm_ck, | ||
193 | .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, | ||
194 | .recalc = &followparent_recalc, | ||
195 | /* Note: On 16xx the frequency can be divided by 2 by programming | ||
196 | * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 | ||
197 | * | ||
198 | * 1510 version is in TC clocks. | ||
199 | */ | ||
200 | }; | ||
201 | |||
202 | static struct clk dsp_ck = { | ||
203 | .name = "dsp_ck", | ||
204 | .parent = &ck_dpll1, | ||
205 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
206 | RATE_CKCTL, | ||
207 | .enable_reg = ARM_CKCTL, | ||
208 | .enable_bit = EN_DSPCK, | ||
209 | .rate_offset = CKCTL_DSPDIV_OFFSET, | ||
210 | .recalc = &ckctl_recalc, | ||
211 | }; | ||
212 | |||
213 | static struct clk dspmmu_ck = { | ||
214 | .name = "dspmmu_ck", | ||
215 | .parent = &ck_dpll1, | ||
216 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
217 | RATE_CKCTL | ALWAYS_ENABLED, | ||
218 | .rate_offset = CKCTL_DSPMMUDIV_OFFSET, | ||
219 | .recalc = &ckctl_recalc, | ||
220 | }; | ||
221 | |||
222 | static struct clk dspper_ck = { | ||
223 | .name = "dspper_ck", | ||
224 | .parent = &ck_dpll1, | ||
225 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
226 | RATE_CKCTL | DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS, | ||
227 | .enable_reg = DSP_IDLECT2, | ||
228 | .enable_bit = EN_PERCK, | ||
229 | .rate_offset = CKCTL_PERDIV_OFFSET, | ||
230 | .recalc = &followparent_recalc, | ||
231 | //.recalc = &ckctl_recalc, | ||
232 | }; | ||
233 | |||
234 | static struct clk dspxor_ck = { | ||
235 | .name = "dspxor_ck", | ||
236 | .parent = &ck_ref, | ||
237 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
238 | DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS, | ||
239 | .enable_reg = DSP_IDLECT2, | ||
240 | .enable_bit = EN_XORPCK, | ||
241 | .recalc = &followparent_recalc, | ||
242 | }; | ||
243 | |||
244 | static struct clk dsptim_ck = { | ||
245 | .name = "dsptim_ck", | ||
246 | .parent = &ck_ref, | ||
247 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
248 | DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS, | ||
249 | .enable_reg = DSP_IDLECT2, | ||
250 | .enable_bit = EN_DSPTIMCK, | ||
251 | .recalc = &followparent_recalc, | ||
252 | }; | ||
253 | |||
254 | static struct clk tc_ck = { | ||
255 | .name = "tc_ck", | ||
256 | .parent = &ck_dpll1, | ||
257 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | | ||
258 | RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, | ||
259 | .rate_offset = CKCTL_TCDIV_OFFSET, | ||
260 | .recalc = &ckctl_recalc, | ||
261 | }; | ||
262 | |||
263 | static struct clk arminth_ck1510 = { | ||
264 | .name = "arminth_ck", | ||
265 | .parent = &tc_ck, | ||
266 | .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, | ||
267 | .recalc = &followparent_recalc, | ||
268 | /* Note: On 1510 the frequency follows TC_CK | ||
269 | * | ||
270 | * 16xx version is in MPU clocks. | ||
271 | */ | ||
272 | }; | ||
273 | |||
274 | static struct clk tipb_ck = { | ||
275 | .name = "tibp_ck", | ||
276 | .parent = &tc_ck, | ||
277 | .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, | ||
278 | .recalc = &followparent_recalc, | ||
279 | }; | ||
280 | |||
281 | static struct clk l3_ocpi_ck = { | ||
282 | .name = "l3_ocpi_ck", | ||
283 | .parent = &tc_ck, | ||
284 | .flags = CLOCK_IN_OMAP16XX, | ||
285 | .enable_reg = ARM_IDLECT3, | ||
286 | .enable_bit = EN_OCPI_CK, | ||
287 | .recalc = &followparent_recalc, | ||
288 | }; | ||
289 | 32 | ||
290 | static struct clk tc1_ck = { | 33 | static struct clk_functions *arch_clock; |
291 | .name = "tc1_ck", | ||
292 | .parent = &tc_ck, | ||
293 | .flags = CLOCK_IN_OMAP16XX, | ||
294 | .enable_reg = ARM_IDLECT3, | ||
295 | .enable_bit = EN_TC1_CK, | ||
296 | .recalc = &followparent_recalc, | ||
297 | }; | ||
298 | 34 | ||
299 | static struct clk tc2_ck = { | 35 | /*------------------------------------------------------------------------- |
300 | .name = "tc2_ck", | 36 | * Standard clock functions defined in asm/hardware/clock.h |
301 | .parent = &tc_ck, | 37 | *-------------------------------------------------------------------------*/ |
302 | .flags = CLOCK_IN_OMAP16XX, | ||
303 | .enable_reg = ARM_IDLECT3, | ||
304 | .enable_bit = EN_TC2_CK, | ||
305 | .recalc = &followparent_recalc, | ||
306 | }; | ||
307 | 38 | ||
308 | static struct clk dma_ck = { | 39 | struct clk * clk_get(struct device *dev, const char *id) |
309 | .name = "dma_ck", | ||
310 | .parent = &tc_ck, | ||
311 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
312 | ALWAYS_ENABLED, | ||
313 | .recalc = &followparent_recalc, | ||
314 | }; | ||
315 | |||
316 | static struct clk dma_lcdfree_ck = { | ||
317 | .name = "dma_lcdfree_ck", | ||
318 | .parent = &tc_ck, | ||
319 | .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, | ||
320 | .recalc = &followparent_recalc, | ||
321 | }; | ||
322 | |||
323 | static struct clk api_ck = { | ||
324 | .name = "api_ck", | ||
325 | .parent = &tc_ck, | ||
326 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, | ||
327 | .enable_reg = ARM_IDLECT2, | ||
328 | .enable_bit = EN_APICK, | ||
329 | .recalc = &followparent_recalc, | ||
330 | }; | ||
331 | |||
332 | static struct clk lb_ck = { | ||
333 | .name = "lb_ck", | ||
334 | .parent = &tc_ck, | ||
335 | .flags = CLOCK_IN_OMAP1510, | ||
336 | .enable_reg = ARM_IDLECT2, | ||
337 | .enable_bit = EN_LBCK, | ||
338 | .recalc = &followparent_recalc, | ||
339 | }; | ||
340 | |||
341 | static struct clk rhea1_ck = { | ||
342 | .name = "rhea1_ck", | ||
343 | .parent = &tc_ck, | ||
344 | .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, | ||
345 | .recalc = &followparent_recalc, | ||
346 | }; | ||
347 | |||
348 | static struct clk rhea2_ck = { | ||
349 | .name = "rhea2_ck", | ||
350 | .parent = &tc_ck, | ||
351 | .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, | ||
352 | .recalc = &followparent_recalc, | ||
353 | }; | ||
354 | |||
355 | static struct clk lcd_ck = { | ||
356 | .name = "lcd_ck", | ||
357 | .parent = &ck_dpll1, | ||
358 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | | ||
359 | RATE_CKCTL, | ||
360 | .enable_reg = ARM_IDLECT2, | ||
361 | .enable_bit = EN_LCDCK, | ||
362 | .rate_offset = CKCTL_LCDDIV_OFFSET, | ||
363 | .recalc = &ckctl_recalc, | ||
364 | }; | ||
365 | |||
366 | static struct clk uart1_1510 = { | ||
367 | .name = "uart1_ck", | ||
368 | /* Direct from ULPD, no parent */ | ||
369 | .rate = 12000000, | ||
370 | .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED, | ||
371 | .enable_reg = MOD_CONF_CTRL_0, | ||
372 | .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ | ||
373 | .set_rate = &set_uart_rate, | ||
374 | .recalc = &uart_recalc, | ||
375 | }; | ||
376 | |||
377 | static struct clk uart1_16xx = { | ||
378 | .name = "uart1_ck", | ||
379 | /* Direct from ULPD, no parent */ | ||
380 | .rate = 48000000, | ||
381 | .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT, | ||
382 | .enable_reg = MOD_CONF_CTRL_0, | ||
383 | .enable_bit = 29, | ||
384 | }; | ||
385 | |||
386 | static struct clk uart2_ck = { | ||
387 | .name = "uart2_ck", | ||
388 | /* Direct from ULPD, no parent */ | ||
389 | .rate = 12000000, | ||
390 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT | | ||
391 | ALWAYS_ENABLED, | ||
392 | .enable_reg = MOD_CONF_CTRL_0, | ||
393 | .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ | ||
394 | .set_rate = &set_uart_rate, | ||
395 | .recalc = &uart_recalc, | ||
396 | }; | ||
397 | |||
398 | static struct clk uart3_1510 = { | ||
399 | .name = "uart3_ck", | ||
400 | /* Direct from ULPD, no parent */ | ||
401 | .rate = 12000000, | ||
402 | .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED, | ||
403 | .enable_reg = MOD_CONF_CTRL_0, | ||
404 | .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ | ||
405 | .set_rate = &set_uart_rate, | ||
406 | .recalc = &uart_recalc, | ||
407 | }; | ||
408 | |||
409 | static struct clk uart3_16xx = { | ||
410 | .name = "uart3_ck", | ||
411 | /* Direct from ULPD, no parent */ | ||
412 | .rate = 48000000, | ||
413 | .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT, | ||
414 | .enable_reg = MOD_CONF_CTRL_0, | ||
415 | .enable_bit = 31, | ||
416 | }; | ||
417 | |||
418 | static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */ | ||
419 | .name = "usb_clko", | ||
420 | /* Direct from ULPD, no parent */ | ||
421 | .rate = 6000000, | ||
422 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
423 | RATE_FIXED | ENABLE_REG_32BIT, | ||
424 | .enable_reg = ULPD_CLOCK_CTRL, | ||
425 | .enable_bit = USB_MCLK_EN_BIT, | ||
426 | }; | ||
427 | |||
428 | static struct clk usb_hhc_ck1510 = { | ||
429 | .name = "usb_hhc_ck", | ||
430 | /* Direct from ULPD, no parent */ | ||
431 | .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ | ||
432 | .flags = CLOCK_IN_OMAP1510 | | ||
433 | RATE_FIXED | ENABLE_REG_32BIT, | ||
434 | .enable_reg = MOD_CONF_CTRL_0, | ||
435 | .enable_bit = USB_HOST_HHC_UHOST_EN, | ||
436 | }; | ||
437 | |||
438 | static struct clk usb_hhc_ck16xx = { | ||
439 | .name = "usb_hhc_ck", | ||
440 | /* Direct from ULPD, no parent */ | ||
441 | .rate = 48000000, | ||
442 | /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ | ||
443 | .flags = CLOCK_IN_OMAP16XX | | ||
444 | RATE_FIXED | ENABLE_REG_32BIT, | ||
445 | .enable_reg = OTG_BASE + 0x08 /* OTG_SYSCON_2 */, | ||
446 | .enable_bit = 8 /* UHOST_EN */, | ||
447 | }; | ||
448 | |||
449 | static struct clk usb_dc_ck = { | ||
450 | .name = "usb_dc_ck", | ||
451 | /* Direct from ULPD, no parent */ | ||
452 | .rate = 48000000, | ||
453 | .flags = CLOCK_IN_OMAP16XX | RATE_FIXED, | ||
454 | .enable_reg = SOFT_REQ_REG, | ||
455 | .enable_bit = 4, | ||
456 | }; | ||
457 | |||
458 | static struct clk mclk_1510 = { | ||
459 | .name = "mclk", | ||
460 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | ||
461 | .rate = 12000000, | ||
462 | .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, | ||
463 | }; | ||
464 | |||
465 | static struct clk mclk_16xx = { | ||
466 | .name = "mclk", | ||
467 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | ||
468 | .flags = CLOCK_IN_OMAP16XX, | ||
469 | .enable_reg = COM_CLK_DIV_CTRL_SEL, | ||
470 | .enable_bit = COM_ULPD_PLL_CLK_REQ, | ||
471 | .set_rate = &set_ext_clk_rate, | ||
472 | .round_rate = &round_ext_clk_rate, | ||
473 | .init = &init_ext_clk, | ||
474 | }; | ||
475 | |||
476 | static struct clk bclk_1510 = { | ||
477 | .name = "bclk", | ||
478 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | ||
479 | .rate = 12000000, | ||
480 | .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, | ||
481 | }; | ||
482 | |||
483 | static struct clk bclk_16xx = { | ||
484 | .name = "bclk", | ||
485 | /* Direct from ULPD, no parent. May be enabled by ext hardware. */ | ||
486 | .flags = CLOCK_IN_OMAP16XX, | ||
487 | .enable_reg = SWD_CLK_DIV_CTRL_SEL, | ||
488 | .enable_bit = SWD_ULPD_PLL_CLK_REQ, | ||
489 | .set_rate = &set_ext_clk_rate, | ||
490 | .round_rate = &round_ext_clk_rate, | ||
491 | .init = &init_ext_clk, | ||
492 | }; | ||
493 | |||
494 | static struct clk mmc1_ck = { | ||
495 | .name = "mmc1_ck", | ||
496 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ | ||
497 | .parent = &armper_ck, | ||
498 | .rate = 48000000, | ||
499 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
500 | RATE_FIXED | ENABLE_REG_32BIT, | ||
501 | .enable_reg = MOD_CONF_CTRL_0, | ||
502 | .enable_bit = 23, | ||
503 | }; | ||
504 | |||
505 | static struct clk mmc2_ck = { | ||
506 | .name = "mmc2_ck", | ||
507 | /* Functional clock is direct from ULPD, interface clock is ARMPER */ | ||
508 | .parent = &armper_ck, | ||
509 | .rate = 48000000, | ||
510 | .flags = CLOCK_IN_OMAP16XX | | ||
511 | RATE_FIXED | ENABLE_REG_32BIT, | ||
512 | .enable_reg = MOD_CONF_CTRL_0, | ||
513 | .enable_bit = 20, | ||
514 | }; | ||
515 | |||
516 | static struct clk virtual_ck_mpu = { | ||
517 | .name = "mpu", | ||
518 | .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | | ||
519 | VIRTUAL_CLOCK | ALWAYS_ENABLED, | ||
520 | .parent = &arm_ck, /* Is smarter alias for */ | ||
521 | .recalc = &followparent_recalc, | ||
522 | .set_rate = &select_table_rate, | ||
523 | .round_rate = &round_to_table_rate, | ||
524 | }; | ||
525 | |||
526 | |||
527 | static struct clk * onchip_clks[] = { | ||
528 | /* non-ULPD clocks */ | ||
529 | &ck_ref, | ||
530 | &ck_dpll1, | ||
531 | /* CK_GEN1 clocks */ | ||
532 | &ck_dpll1out, | ||
533 | &arm_ck, | ||
534 | &armper_ck, | ||
535 | &arm_gpio_ck, | ||
536 | &armxor_ck, | ||
537 | &armtim_ck, | ||
538 | &armwdt_ck, | ||
539 | &arminth_ck1510, &arminth_ck16xx, | ||
540 | /* CK_GEN2 clocks */ | ||
541 | &dsp_ck, | ||
542 | &dspmmu_ck, | ||
543 | &dspper_ck, | ||
544 | &dspxor_ck, | ||
545 | &dsptim_ck, | ||
546 | /* CK_GEN3 clocks */ | ||
547 | &tc_ck, | ||
548 | &tipb_ck, | ||
549 | &l3_ocpi_ck, | ||
550 | &tc1_ck, | ||
551 | &tc2_ck, | ||
552 | &dma_ck, | ||
553 | &dma_lcdfree_ck, | ||
554 | &api_ck, | ||
555 | &lb_ck, | ||
556 | &rhea1_ck, | ||
557 | &rhea2_ck, | ||
558 | &lcd_ck, | ||
559 | /* ULPD clocks */ | ||
560 | &uart1_1510, | ||
561 | &uart1_16xx, | ||
562 | &uart2_ck, | ||
563 | &uart3_1510, | ||
564 | &uart3_16xx, | ||
565 | &usb_clko, | ||
566 | &usb_hhc_ck1510, &usb_hhc_ck16xx, | ||
567 | &usb_dc_ck, | ||
568 | &mclk_1510, &mclk_16xx, | ||
569 | &bclk_1510, &bclk_16xx, | ||
570 | &mmc1_ck, | ||
571 | &mmc2_ck, | ||
572 | /* Virtual clocks */ | ||
573 | &virtual_ck_mpu, | ||
574 | }; | ||
575 | |||
576 | struct clk *clk_get(struct device *dev, const char *id) | ||
577 | { | 40 | { |
578 | struct clk *p, *clk = ERR_PTR(-ENOENT); | 41 | struct clk *p, *clk = ERR_PTR(-ENOENT); |
579 | 42 | ||
@@ -590,534 +53,200 @@ struct clk *clk_get(struct device *dev, const char *id) | |||
590 | } | 53 | } |
591 | EXPORT_SYMBOL(clk_get); | 54 | EXPORT_SYMBOL(clk_get); |
592 | 55 | ||
593 | |||
594 | void clk_put(struct clk *clk) | ||
595 | { | ||
596 | if (clk && !IS_ERR(clk)) | ||
597 | module_put(clk->owner); | ||
598 | } | ||
599 | EXPORT_SYMBOL(clk_put); | ||
600 | |||
601 | |||
602 | int __clk_enable(struct clk *clk) | ||
603 | { | ||
604 | __u16 regval16; | ||
605 | __u32 regval32; | ||
606 | |||
607 | if (clk->flags & ALWAYS_ENABLED) | ||
608 | return 0; | ||
609 | |||
610 | if (unlikely(clk->enable_reg == 0)) { | ||
611 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", | ||
612 | clk->name); | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | if (clk->flags & DSP_DOMAIN_CLOCK) { | ||
617 | __clk_use(&api_ck); | ||
618 | } | ||
619 | |||
620 | if (clk->flags & ENABLE_REG_32BIT) { | ||
621 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | ||
622 | regval32 = __raw_readl(clk->enable_reg); | ||
623 | regval32 |= (1 << clk->enable_bit); | ||
624 | __raw_writel(regval32, clk->enable_reg); | ||
625 | } else { | ||
626 | regval32 = omap_readl(clk->enable_reg); | ||
627 | regval32 |= (1 << clk->enable_bit); | ||
628 | omap_writel(regval32, clk->enable_reg); | ||
629 | } | ||
630 | } else { | ||
631 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | ||
632 | regval16 = __raw_readw(clk->enable_reg); | ||
633 | regval16 |= (1 << clk->enable_bit); | ||
634 | __raw_writew(regval16, clk->enable_reg); | ||
635 | } else { | ||
636 | regval16 = omap_readw(clk->enable_reg); | ||
637 | regval16 |= (1 << clk->enable_bit); | ||
638 | omap_writew(regval16, clk->enable_reg); | ||
639 | } | ||
640 | } | ||
641 | |||
642 | if (clk->flags & DSP_DOMAIN_CLOCK) { | ||
643 | __clk_unuse(&api_ck); | ||
644 | } | ||
645 | |||
646 | return 0; | ||
647 | } | ||
648 | |||
649 | |||
650 | void __clk_disable(struct clk *clk) | ||
651 | { | ||
652 | __u16 regval16; | ||
653 | __u32 regval32; | ||
654 | |||
655 | if (clk->enable_reg == 0) | ||
656 | return; | ||
657 | |||
658 | if (clk->flags & DSP_DOMAIN_CLOCK) { | ||
659 | __clk_use(&api_ck); | ||
660 | } | ||
661 | |||
662 | if (clk->flags & ENABLE_REG_32BIT) { | ||
663 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | ||
664 | regval32 = __raw_readl(clk->enable_reg); | ||
665 | regval32 &= ~(1 << clk->enable_bit); | ||
666 | __raw_writel(regval32, clk->enable_reg); | ||
667 | } else { | ||
668 | regval32 = omap_readl(clk->enable_reg); | ||
669 | regval32 &= ~(1 << clk->enable_bit); | ||
670 | omap_writel(regval32, clk->enable_reg); | ||
671 | } | ||
672 | } else { | ||
673 | if (clk->flags & VIRTUAL_IO_ADDRESS) { | ||
674 | regval16 = __raw_readw(clk->enable_reg); | ||
675 | regval16 &= ~(1 << clk->enable_bit); | ||
676 | __raw_writew(regval16, clk->enable_reg); | ||
677 | } else { | ||
678 | regval16 = omap_readw(clk->enable_reg); | ||
679 | regval16 &= ~(1 << clk->enable_bit); | ||
680 | omap_writew(regval16, clk->enable_reg); | ||
681 | } | ||
682 | } | ||
683 | |||
684 | if (clk->flags & DSP_DOMAIN_CLOCK) { | ||
685 | __clk_unuse(&api_ck); | ||
686 | } | ||
687 | } | ||
688 | |||
689 | |||
690 | void __clk_unuse(struct clk *clk) | ||
691 | { | ||
692 | if (clk->usecount > 0 && !(--clk->usecount)) { | ||
693 | __clk_disable(clk); | ||
694 | if (likely(clk->parent)) | ||
695 | __clk_unuse(clk->parent); | ||
696 | } | ||
697 | } | ||
698 | |||
699 | |||
700 | int __clk_use(struct clk *clk) | ||
701 | { | ||
702 | int ret = 0; | ||
703 | if (clk->usecount++ == 0) { | ||
704 | if (likely(clk->parent)) | ||
705 | ret = __clk_use(clk->parent); | ||
706 | |||
707 | if (unlikely(ret != 0)) { | ||
708 | clk->usecount--; | ||
709 | return ret; | ||
710 | } | ||
711 | |||
712 | ret = __clk_enable(clk); | ||
713 | |||
714 | if (unlikely(ret != 0) && clk->parent) { | ||
715 | __clk_unuse(clk->parent); | ||
716 | clk->usecount--; | ||
717 | } | ||
718 | } | ||
719 | |||
720 | return ret; | ||
721 | } | ||
722 | |||
723 | |||
724 | int clk_enable(struct clk *clk) | 56 | int clk_enable(struct clk *clk) |
725 | { | 57 | { |
726 | unsigned long flags; | 58 | unsigned long flags; |
727 | int ret; | 59 | int ret = 0; |
728 | 60 | ||
729 | spin_lock_irqsave(&clockfw_lock, flags); | 61 | spin_lock_irqsave(&clockfw_lock, flags); |
730 | ret = __clk_enable(clk); | 62 | if (clk->enable) |
63 | ret = clk->enable(clk); | ||
64 | else if (arch_clock->clk_enable) | ||
65 | ret = arch_clock->clk_enable(clk); | ||
66 | else | ||
67 | printk(KERN_ERR "Could not enable clock %s\n", clk->name); | ||
731 | spin_unlock_irqrestore(&clockfw_lock, flags); | 68 | spin_unlock_irqrestore(&clockfw_lock, flags); |
69 | |||
732 | return ret; | 70 | return ret; |
733 | } | 71 | } |
734 | EXPORT_SYMBOL(clk_enable); | 72 | EXPORT_SYMBOL(clk_enable); |
735 | 73 | ||
736 | |||
737 | void clk_disable(struct clk *clk) | 74 | void clk_disable(struct clk *clk) |
738 | { | 75 | { |
739 | unsigned long flags; | 76 | unsigned long flags; |
740 | 77 | ||
741 | spin_lock_irqsave(&clockfw_lock, flags); | 78 | spin_lock_irqsave(&clockfw_lock, flags); |
742 | __clk_disable(clk); | 79 | if (clk->disable) |
80 | clk->disable(clk); | ||
81 | else if (arch_clock->clk_disable) | ||
82 | arch_clock->clk_disable(clk); | ||
83 | else | ||
84 | printk(KERN_ERR "Could not disable clock %s\n", clk->name); | ||
743 | spin_unlock_irqrestore(&clockfw_lock, flags); | 85 | spin_unlock_irqrestore(&clockfw_lock, flags); |
744 | } | 86 | } |
745 | EXPORT_SYMBOL(clk_disable); | 87 | EXPORT_SYMBOL(clk_disable); |
746 | 88 | ||
747 | |||
748 | int clk_use(struct clk *clk) | 89 | int clk_use(struct clk *clk) |
749 | { | 90 | { |
750 | unsigned long flags; | 91 | unsigned long flags; |
751 | int ret = 0; | 92 | int ret = 0; |
752 | 93 | ||
753 | spin_lock_irqsave(&clockfw_lock, flags); | 94 | spin_lock_irqsave(&clockfw_lock, flags); |
754 | ret = __clk_use(clk); | 95 | if (arch_clock->clk_use) |
96 | ret = arch_clock->clk_use(clk); | ||
755 | spin_unlock_irqrestore(&clockfw_lock, flags); | 97 | spin_unlock_irqrestore(&clockfw_lock, flags); |
98 | |||
756 | return ret; | 99 | return ret; |
757 | } | 100 | } |
758 | EXPORT_SYMBOL(clk_use); | 101 | EXPORT_SYMBOL(clk_use); |
759 | 102 | ||
760 | |||
761 | void clk_unuse(struct clk *clk) | 103 | void clk_unuse(struct clk *clk) |
762 | { | 104 | { |
763 | unsigned long flags; | 105 | unsigned long flags; |
764 | 106 | ||
765 | spin_lock_irqsave(&clockfw_lock, flags); | 107 | spin_lock_irqsave(&clockfw_lock, flags); |
766 | __clk_unuse(clk); | 108 | if (arch_clock->clk_unuse) |
109 | arch_clock->clk_unuse(clk); | ||
767 | spin_unlock_irqrestore(&clockfw_lock, flags); | 110 | spin_unlock_irqrestore(&clockfw_lock, flags); |
768 | } | 111 | } |
769 | EXPORT_SYMBOL(clk_unuse); | 112 | EXPORT_SYMBOL(clk_unuse); |
770 | 113 | ||
771 | |||
772 | int clk_get_usecount(struct clk *clk) | 114 | int clk_get_usecount(struct clk *clk) |
773 | { | 115 | { |
774 | return clk->usecount; | 116 | unsigned long flags; |
775 | } | 117 | int ret = 0; |
776 | EXPORT_SYMBOL(clk_get_usecount); | ||
777 | |||
778 | |||
779 | unsigned long clk_get_rate(struct clk *clk) | ||
780 | { | ||
781 | return clk->rate; | ||
782 | } | ||
783 | EXPORT_SYMBOL(clk_get_rate); | ||
784 | |||
785 | |||
786 | static __u16 verify_ckctl_value(__u16 newval) | ||
787 | { | ||
788 | /* This function checks for following limitations set | ||
789 | * by the hardware (all conditions must be true): | ||
790 | * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2 | ||
791 | * ARM_CK >= TC_CK | ||
792 | * DSP_CK >= TC_CK | ||
793 | * DSPMMU_CK >= TC_CK | ||
794 | * | ||
795 | * In addition following rules are enforced: | ||
796 | * LCD_CK <= TC_CK | ||
797 | * ARMPER_CK <= TC_CK | ||
798 | * | ||
799 | * However, maximum frequencies are not checked for! | ||
800 | */ | ||
801 | __u8 per_exp; | ||
802 | __u8 lcd_exp; | ||
803 | __u8 arm_exp; | ||
804 | __u8 dsp_exp; | ||
805 | __u8 tc_exp; | ||
806 | __u8 dspmmu_exp; | ||
807 | |||
808 | per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3; | ||
809 | lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3; | ||
810 | arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3; | ||
811 | dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3; | ||
812 | tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3; | ||
813 | dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3; | ||
814 | |||
815 | if (dspmmu_exp < dsp_exp) | ||
816 | dspmmu_exp = dsp_exp; | ||
817 | if (dspmmu_exp > dsp_exp+1) | ||
818 | dspmmu_exp = dsp_exp+1; | ||
819 | if (tc_exp < arm_exp) | ||
820 | tc_exp = arm_exp; | ||
821 | if (tc_exp < dspmmu_exp) | ||
822 | tc_exp = dspmmu_exp; | ||
823 | if (tc_exp > lcd_exp) | ||
824 | lcd_exp = tc_exp; | ||
825 | if (tc_exp > per_exp) | ||
826 | per_exp = tc_exp; | ||
827 | 118 | ||
828 | newval &= 0xf000; | 119 | spin_lock_irqsave(&clockfw_lock, flags); |
829 | newval |= per_exp << CKCTL_PERDIV_OFFSET; | 120 | ret = clk->usecount; |
830 | newval |= lcd_exp << CKCTL_LCDDIV_OFFSET; | 121 | spin_unlock_irqrestore(&clockfw_lock, flags); |
831 | newval |= arm_exp << CKCTL_ARMDIV_OFFSET; | ||
832 | newval |= dsp_exp << CKCTL_DSPDIV_OFFSET; | ||
833 | newval |= tc_exp << CKCTL_TCDIV_OFFSET; | ||
834 | newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET; | ||
835 | 122 | ||
836 | return newval; | 123 | return ret; |
837 | } | 124 | } |
125 | EXPORT_SYMBOL(clk_get_usecount); | ||
838 | 126 | ||
839 | 127 | unsigned long clk_get_rate(struct clk *clk) | |
840 | static int calc_dsor_exp(struct clk *clk, unsigned long rate) | ||
841 | { | 128 | { |
842 | /* Note: If target frequency is too low, this function will return 4, | 129 | unsigned long flags; |
843 | * which is invalid value. Caller must check for this value and act | 130 | unsigned long ret = 0; |
844 | * accordingly. | ||
845 | * | ||
846 | * Note: This function does not check for following limitations set | ||
847 | * by the hardware (all conditions must be true): | ||
848 | * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2 | ||
849 | * ARM_CK >= TC_CK | ||
850 | * DSP_CK >= TC_CK | ||
851 | * DSPMMU_CK >= TC_CK | ||
852 | */ | ||
853 | unsigned long realrate; | ||
854 | struct clk * parent; | ||
855 | unsigned dsor_exp; | ||
856 | |||
857 | if (unlikely(!(clk->flags & RATE_CKCTL))) | ||
858 | return -EINVAL; | ||
859 | |||
860 | parent = clk->parent; | ||
861 | if (unlikely(parent == 0)) | ||
862 | return -EIO; | ||
863 | |||
864 | realrate = parent->rate; | ||
865 | for (dsor_exp=0; dsor_exp<4; dsor_exp++) { | ||
866 | if (realrate <= rate) | ||
867 | break; | ||
868 | 131 | ||
869 | realrate /= 2; | 132 | spin_lock_irqsave(&clockfw_lock, flags); |
870 | } | 133 | ret = clk->rate; |
134 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
871 | 135 | ||
872 | return dsor_exp; | 136 | return ret; |
873 | } | 137 | } |
138 | EXPORT_SYMBOL(clk_get_rate); | ||
874 | 139 | ||
875 | 140 | void clk_put(struct clk *clk) | |
876 | static void ckctl_recalc(struct clk * clk) | ||
877 | { | 141 | { |
878 | int dsor; | 142 | if (clk && !IS_ERR(clk)) |
879 | 143 | module_put(clk->owner); | |
880 | /* Calculate divisor encoded as 2-bit exponent */ | ||
881 | if (clk->flags & DSP_DOMAIN_CLOCK) { | ||
882 | /* The clock control bits are in DSP domain, | ||
883 | * so api_ck is needed for access. | ||
884 | * Note that DSP_CKCTL virt addr = phys addr, so | ||
885 | * we must use __raw_readw() instead of omap_readw(). | ||
886 | */ | ||
887 | __clk_use(&api_ck); | ||
888 | dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset)); | ||
889 | __clk_unuse(&api_ck); | ||
890 | } else { | ||
891 | dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); | ||
892 | } | ||
893 | if (unlikely(clk->rate == clk->parent->rate / dsor)) | ||
894 | return; /* No change, quick exit */ | ||
895 | clk->rate = clk->parent->rate / dsor; | ||
896 | |||
897 | if (unlikely(clk->flags & RATE_PROPAGATES)) | ||
898 | propagate_rate(clk); | ||
899 | } | 144 | } |
145 | EXPORT_SYMBOL(clk_put); | ||
900 | 146 | ||
147 | /*------------------------------------------------------------------------- | ||
148 | * Optional clock functions defined in asm/hardware/clock.h | ||
149 | *-------------------------------------------------------------------------*/ | ||
901 | 150 | ||
902 | long clk_round_rate(struct clk *clk, unsigned long rate) | 151 | long clk_round_rate(struct clk *clk, unsigned long rate) |
903 | { | 152 | { |
904 | int dsor_exp; | 153 | unsigned long flags; |
905 | 154 | long ret = 0; | |
906 | if (clk->flags & RATE_FIXED) | ||
907 | return clk->rate; | ||
908 | |||
909 | if (clk->flags & RATE_CKCTL) { | ||
910 | dsor_exp = calc_dsor_exp(clk, rate); | ||
911 | if (dsor_exp < 0) | ||
912 | return dsor_exp; | ||
913 | if (dsor_exp > 3) | ||
914 | dsor_exp = 3; | ||
915 | return clk->parent->rate / (1 << dsor_exp); | ||
916 | } | ||
917 | 155 | ||
918 | if(clk->round_rate != 0) | 156 | spin_lock_irqsave(&clockfw_lock, flags); |
919 | return clk->round_rate(clk, rate); | 157 | if (arch_clock->clk_round_rate) |
158 | ret = arch_clock->clk_round_rate(clk, rate); | ||
159 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
920 | 160 | ||
921 | return clk->rate; | 161 | return ret; |
922 | } | 162 | } |
923 | EXPORT_SYMBOL(clk_round_rate); | 163 | EXPORT_SYMBOL(clk_round_rate); |
924 | 164 | ||
925 | 165 | int clk_set_rate(struct clk *clk, unsigned long rate) | |
926 | static void propagate_rate(struct clk * clk) | ||
927 | { | ||
928 | struct clk ** clkp; | ||
929 | |||
930 | for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) { | ||
931 | if (likely((*clkp)->parent != clk)) continue; | ||
932 | if (likely((*clkp)->recalc)) | ||
933 | (*clkp)->recalc(*clkp); | ||
934 | } | ||
935 | } | ||
936 | |||
937 | |||
938 | static int select_table_rate(struct clk * clk, unsigned long rate) | ||
939 | { | 166 | { |
940 | /* Find the highest supported frequency <= rate and switch to it */ | 167 | unsigned long flags; |
941 | struct mpu_rate * ptr; | 168 | int ret = 0; |
942 | |||
943 | if (clk != &virtual_ck_mpu) | ||
944 | return -EINVAL; | ||
945 | |||
946 | for (ptr = rate_table; ptr->rate; ptr++) { | ||
947 | if (ptr->xtal != ck_ref.rate) | ||
948 | continue; | ||
949 | |||
950 | /* DPLL1 cannot be reprogrammed without risking system crash */ | ||
951 | if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate) | ||
952 | continue; | ||
953 | |||
954 | /* Can check only after xtal frequency check */ | ||
955 | if (ptr->rate <= rate) | ||
956 | break; | ||
957 | } | ||
958 | |||
959 | if (!ptr->rate) | ||
960 | return -EINVAL; | ||
961 | 169 | ||
962 | /* | 170 | spin_lock_irqsave(&clockfw_lock, flags); |
963 | * In most cases we should not need to reprogram DPLL. | 171 | if (arch_clock->clk_set_rate) |
964 | * Reprogramming the DPLL is tricky, it must be done from SRAM. | 172 | ret = arch_clock->clk_set_rate(clk, rate); |
965 | */ | 173 | spin_unlock_irqrestore(&clockfw_lock, flags); |
966 | omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); | ||
967 | 174 | ||
968 | ck_dpll1.rate = ptr->pll_rate; | 175 | return ret; |
969 | propagate_rate(&ck_dpll1); | ||
970 | return 0; | ||
971 | } | 176 | } |
177 | EXPORT_SYMBOL(clk_set_rate); | ||
972 | 178 | ||
973 | 179 | int clk_set_parent(struct clk *clk, struct clk *parent) | |
974 | static long round_to_table_rate(struct clk * clk, unsigned long rate) | ||
975 | { | 180 | { |
976 | /* Find the highest supported frequency <= rate */ | 181 | unsigned long flags; |
977 | struct mpu_rate * ptr; | 182 | int ret = 0; |
978 | long highest_rate; | ||
979 | |||
980 | if (clk != &virtual_ck_mpu) | ||
981 | return -EINVAL; | ||
982 | |||
983 | highest_rate = -EINVAL; | ||
984 | |||
985 | for (ptr = rate_table; ptr->rate; ptr++) { | ||
986 | if (ptr->xtal != ck_ref.rate) | ||
987 | continue; | ||
988 | |||
989 | highest_rate = ptr->rate; | ||
990 | 183 | ||
991 | /* Can check only after xtal frequency check */ | 184 | spin_lock_irqsave(&clockfw_lock, flags); |
992 | if (ptr->rate <= rate) | 185 | if (arch_clock->clk_set_parent) |
993 | break; | 186 | ret = arch_clock->clk_set_parent(clk, parent); |
994 | } | 187 | spin_unlock_irqrestore(&clockfw_lock, flags); |
995 | 188 | ||
996 | return highest_rate; | 189 | return ret; |
997 | } | 190 | } |
191 | EXPORT_SYMBOL(clk_set_parent); | ||
998 | 192 | ||
999 | 193 | struct clk *clk_get_parent(struct clk *clk) | |
1000 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
1001 | { | 194 | { |
1002 | int ret = -EINVAL; | 195 | unsigned long flags; |
1003 | int dsor_exp; | 196 | struct clk * ret = NULL; |
1004 | __u16 regval; | ||
1005 | unsigned long flags; | ||
1006 | |||
1007 | if (clk->flags & RATE_CKCTL) { | ||
1008 | dsor_exp = calc_dsor_exp(clk, rate); | ||
1009 | if (dsor_exp > 3) | ||
1010 | dsor_exp = -EINVAL; | ||
1011 | if (dsor_exp < 0) | ||
1012 | return dsor_exp; | ||
1013 | |||
1014 | spin_lock_irqsave(&clockfw_lock, flags); | ||
1015 | regval = omap_readw(ARM_CKCTL); | ||
1016 | regval &= ~(3 << clk->rate_offset); | ||
1017 | regval |= dsor_exp << clk->rate_offset; | ||
1018 | regval = verify_ckctl_value(regval); | ||
1019 | omap_writew(regval, ARM_CKCTL); | ||
1020 | clk->rate = clk->parent->rate / (1 << dsor_exp); | ||
1021 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
1022 | ret = 0; | ||
1023 | } else if(clk->set_rate != 0) { | ||
1024 | spin_lock_irqsave(&clockfw_lock, flags); | ||
1025 | ret = clk->set_rate(clk, rate); | ||
1026 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
1027 | } | ||
1028 | 197 | ||
1029 | if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) | 198 | spin_lock_irqsave(&clockfw_lock, flags); |
1030 | propagate_rate(clk); | 199 | if (arch_clock->clk_get_parent) |
200 | ret = arch_clock->clk_get_parent(clk); | ||
201 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
1031 | 202 | ||
1032 | return ret; | 203 | return ret; |
1033 | } | 204 | } |
1034 | EXPORT_SYMBOL(clk_set_rate); | 205 | EXPORT_SYMBOL(clk_get_parent); |
1035 | 206 | ||
207 | /*------------------------------------------------------------------------- | ||
208 | * OMAP specific clock functions shared between omap1 and omap2 | ||
209 | *-------------------------------------------------------------------------*/ | ||
1036 | 210 | ||
1037 | static unsigned calc_ext_dsor(unsigned long rate) | 211 | unsigned int __initdata mpurate; |
1038 | { | ||
1039 | unsigned dsor; | ||
1040 | 212 | ||
1041 | /* MCLK and BCLK divisor selection is not linear: | 213 | /* |
1042 | * freq = 96MHz / dsor | 214 | * By default we use the rate set by the bootloader. |
1043 | * | 215 | * You can override this with mpurate= cmdline option. |
1044 | * RATIO_SEL range: dsor <-> RATIO_SEL | 216 | */ |
1045 | * 0..6: (RATIO_SEL+2) <-> (dsor-2) | 217 | static int __init omap_clk_setup(char *str) |
1046 | * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6) | ||
1047 | * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9 | ||
1048 | * can not be used. | ||
1049 | */ | ||
1050 | for (dsor = 2; dsor < 96; ++dsor) { | ||
1051 | if ((dsor & 1) && dsor > 8) | ||
1052 | continue; | ||
1053 | if (rate >= 96000000 / dsor) | ||
1054 | break; | ||
1055 | } | ||
1056 | return dsor; | ||
1057 | } | ||
1058 | |||
1059 | /* Only needed on 1510 */ | ||
1060 | static int set_uart_rate(struct clk * clk, unsigned long rate) | ||
1061 | { | ||
1062 | unsigned int val; | ||
1063 | |||
1064 | val = omap_readl(clk->enable_reg); | ||
1065 | if (rate == 12000000) | ||
1066 | val &= ~(1 << clk->enable_bit); | ||
1067 | else if (rate == 48000000) | ||
1068 | val |= (1 << clk->enable_bit); | ||
1069 | else | ||
1070 | return -EINVAL; | ||
1071 | omap_writel(val, clk->enable_reg); | ||
1072 | clk->rate = rate; | ||
1073 | |||
1074 | return 0; | ||
1075 | } | ||
1076 | |||
1077 | static int set_ext_clk_rate(struct clk * clk, unsigned long rate) | ||
1078 | { | 218 | { |
1079 | unsigned dsor; | 219 | get_option(&str, &mpurate); |
1080 | __u16 ratio_bits; | ||
1081 | 220 | ||
1082 | dsor = calc_ext_dsor(rate); | 221 | if (!mpurate) |
1083 | clk->rate = 96000000 / dsor; | 222 | return 1; |
1084 | if (dsor > 8) | ||
1085 | ratio_bits = ((dsor - 8) / 2 + 6) << 2; | ||
1086 | else | ||
1087 | ratio_bits = (dsor - 2) << 2; | ||
1088 | 223 | ||
1089 | ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd; | 224 | if (mpurate < 1000) |
1090 | omap_writew(ratio_bits, clk->enable_reg); | 225 | mpurate *= 1000000; |
1091 | 226 | ||
1092 | return 0; | 227 | return 1; |
1093 | } | 228 | } |
229 | __setup("mpurate=", omap_clk_setup); | ||
1094 | 230 | ||
1095 | 231 | /* Used for clocks that always have same value as the parent clock */ | |
1096 | static long round_ext_clk_rate(struct clk * clk, unsigned long rate) | 232 | void followparent_recalc(struct clk *clk) |
1097 | { | 233 | { |
1098 | return 96000000 / calc_ext_dsor(rate); | 234 | clk->rate = clk->parent->rate; |
1099 | } | 235 | } |
1100 | 236 | ||
1101 | 237 | /* Propagate rate to children */ | |
1102 | static void init_ext_clk(struct clk * clk) | 238 | void propagate_rate(struct clk * tclk) |
1103 | { | 239 | { |
1104 | unsigned dsor; | 240 | struct clk *clkp; |
1105 | __u16 ratio_bits; | ||
1106 | 241 | ||
1107 | /* Determine current rate and ensure clock is based on 96MHz APLL */ | 242 | list_for_each_entry(clkp, &clocks, node) { |
1108 | ratio_bits = omap_readw(clk->enable_reg) & ~1; | 243 | if (likely(clkp->parent != tclk)) |
1109 | omap_writew(ratio_bits, clk->enable_reg); | 244 | continue; |
1110 | 245 | if (likely((u32)clkp->recalc)) | |
1111 | ratio_bits = (ratio_bits & 0xfc) >> 2; | 246 | clkp->recalc(clkp); |
1112 | if (ratio_bits > 6) | 247 | } |
1113 | dsor = (ratio_bits - 6) * 2 + 8; | ||
1114 | else | ||
1115 | dsor = ratio_bits + 2; | ||
1116 | |||
1117 | clk-> rate = 96000000 / dsor; | ||
1118 | } | 248 | } |
1119 | 249 | ||
1120 | |||
1121 | int clk_register(struct clk *clk) | 250 | int clk_register(struct clk *clk) |
1122 | { | 251 | { |
1123 | down(&clocks_sem); | 252 | down(&clocks_sem); |
@@ -1125,6 +254,7 @@ int clk_register(struct clk *clk) | |||
1125 | if (clk->init) | 254 | if (clk->init) |
1126 | clk->init(clk); | 255 | clk->init(clk); |
1127 | up(&clocks_sem); | 256 | up(&clocks_sem); |
257 | |||
1128 | return 0; | 258 | return 0; |
1129 | } | 259 | } |
1130 | EXPORT_SYMBOL(clk_register); | 260 | EXPORT_SYMBOL(clk_register); |
@@ -1137,203 +267,38 @@ void clk_unregister(struct clk *clk) | |||
1137 | } | 267 | } |
1138 | EXPORT_SYMBOL(clk_unregister); | 268 | EXPORT_SYMBOL(clk_unregister); |
1139 | 269 | ||
1140 | #ifdef CONFIG_OMAP_RESET_CLOCKS | 270 | void clk_deny_idle(struct clk *clk) |
1141 | /* | ||
1142 | * Resets some clocks that may be left on from bootloader, | ||
1143 | * but leaves serial clocks on. See also omap_late_clk_reset(). | ||
1144 | */ | ||
1145 | static inline void omap_early_clk_reset(void) | ||
1146 | { | 271 | { |
1147 | //omap_writel(0x3 << 29, MOD_CONF_CTRL_0); | 272 | unsigned long flags; |
273 | |||
274 | spin_lock_irqsave(&clockfw_lock, flags); | ||
275 | if (arch_clock->clk_deny_idle) | ||
276 | arch_clock->clk_deny_idle(clk); | ||
277 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
1148 | } | 278 | } |
1149 | #else | 279 | EXPORT_SYMBOL(clk_deny_idle); |
1150 | #define omap_early_clk_reset() {} | ||
1151 | #endif | ||
1152 | 280 | ||
1153 | int __init clk_init(void) | 281 | void clk_allow_idle(struct clk *clk) |
1154 | { | 282 | { |
1155 | struct clk ** clkp; | 283 | unsigned long flags; |
1156 | const struct omap_clock_config *info; | ||
1157 | int crystal_type = 0; /* Default 12 MHz */ | ||
1158 | |||
1159 | omap_early_clk_reset(); | ||
1160 | |||
1161 | for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) { | ||
1162 | if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) { | ||
1163 | clk_register(*clkp); | ||
1164 | continue; | ||
1165 | } | ||
1166 | |||
1167 | if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) { | ||
1168 | clk_register(*clkp); | ||
1169 | continue; | ||
1170 | } | ||
1171 | |||
1172 | if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) { | ||
1173 | clk_register(*clkp); | ||
1174 | continue; | ||
1175 | } | ||
1176 | } | ||
1177 | |||
1178 | info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); | ||
1179 | if (info != NULL) { | ||
1180 | if (!cpu_is_omap1510()) | ||
1181 | crystal_type = info->system_clock_type; | ||
1182 | } | ||
1183 | |||
1184 | #if defined(CONFIG_ARCH_OMAP730) | ||
1185 | ck_ref.rate = 13000000; | ||
1186 | #elif defined(CONFIG_ARCH_OMAP16XX) | ||
1187 | if (crystal_type == 2) | ||
1188 | ck_ref.rate = 19200000; | ||
1189 | #endif | ||
1190 | |||
1191 | printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n", | ||
1192 | omap_readw(ARM_SYSST), omap_readw(DPLL_CTL), | ||
1193 | omap_readw(ARM_CKCTL)); | ||
1194 | |||
1195 | /* We want to be in syncronous scalable mode */ | ||
1196 | omap_writew(0x1000, ARM_SYSST); | ||
1197 | |||
1198 | #ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER | ||
1199 | /* Use values set by bootloader. Determine PLL rate and recalculate | ||
1200 | * dependent clocks as if kernel had changed PLL or divisors. | ||
1201 | */ | ||
1202 | { | ||
1203 | unsigned pll_ctl_val = omap_readw(DPLL_CTL); | ||
1204 | |||
1205 | ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */ | ||
1206 | if (pll_ctl_val & 0x10) { | ||
1207 | /* PLL enabled, apply multiplier and divisor */ | ||
1208 | if (pll_ctl_val & 0xf80) | ||
1209 | ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7; | ||
1210 | ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1; | ||
1211 | } else { | ||
1212 | /* PLL disabled, apply bypass divisor */ | ||
1213 | switch (pll_ctl_val & 0xc) { | ||
1214 | case 0: | ||
1215 | break; | ||
1216 | case 0x4: | ||
1217 | ck_dpll1.rate /= 2; | ||
1218 | break; | ||
1219 | default: | ||
1220 | ck_dpll1.rate /= 4; | ||
1221 | break; | ||
1222 | } | ||
1223 | } | ||
1224 | } | ||
1225 | propagate_rate(&ck_dpll1); | ||
1226 | #else | ||
1227 | /* Find the highest supported frequency and enable it */ | ||
1228 | if (select_table_rate(&virtual_ck_mpu, ~0)) { | ||
1229 | printk(KERN_ERR "System frequencies not set. Check your config.\n"); | ||
1230 | /* Guess sane values (60MHz) */ | ||
1231 | omap_writew(0x2290, DPLL_CTL); | ||
1232 | omap_writew(0x1005, ARM_CKCTL); | ||
1233 | ck_dpll1.rate = 60000000; | ||
1234 | propagate_rate(&ck_dpll1); | ||
1235 | } | ||
1236 | #endif | ||
1237 | /* Cache rates for clocks connected to ck_ref (not dpll1) */ | ||
1238 | propagate_rate(&ck_ref); | ||
1239 | printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): " | ||
1240 | "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n", | ||
1241 | ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, | ||
1242 | ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, | ||
1243 | arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); | ||
1244 | |||
1245 | #ifdef CONFIG_MACH_OMAP_PERSEUS2 | ||
1246 | /* Select slicer output as OMAP input clock */ | ||
1247 | omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); | ||
1248 | #endif | ||
1249 | |||
1250 | /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ | ||
1251 | omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL); | ||
1252 | |||
1253 | /* Put DSP/MPUI into reset until needed */ | ||
1254 | omap_writew(0, ARM_RSTCT1); | ||
1255 | omap_writew(1, ARM_RSTCT2); | ||
1256 | omap_writew(0x400, ARM_IDLECT1); | ||
1257 | |||
1258 | /* | ||
1259 | * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8) | ||
1260 | * of the ARM_IDLECT2 register must be set to zero. The power-on | ||
1261 | * default value of this bit is one. | ||
1262 | */ | ||
1263 | omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */ | ||
1264 | |||
1265 | /* | ||
1266 | * Only enable those clocks we will need, let the drivers | ||
1267 | * enable other clocks as necessary | ||
1268 | */ | ||
1269 | clk_use(&armper_ck); | ||
1270 | clk_use(&armxor_ck); | ||
1271 | clk_use(&armtim_ck); | ||
1272 | |||
1273 | if (cpu_is_omap1510()) | ||
1274 | clk_enable(&arm_gpio_ck); | ||
1275 | 284 | ||
1276 | return 0; | 285 | spin_lock_irqsave(&clockfw_lock, flags); |
286 | if (arch_clock->clk_allow_idle) | ||
287 | arch_clock->clk_allow_idle(clk); | ||
288 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
1277 | } | 289 | } |
290 | EXPORT_SYMBOL(clk_allow_idle); | ||
1278 | 291 | ||
292 | /*-------------------------------------------------------------------------*/ | ||
1279 | 293 | ||
1280 | #ifdef CONFIG_OMAP_RESET_CLOCKS | 294 | int __init clk_init(struct clk_functions * custom_clocks) |
1281 | |||
1282 | static int __init omap_late_clk_reset(void) | ||
1283 | { | 295 | { |
1284 | /* Turn off all unused clocks */ | 296 | if (!custom_clocks) { |
1285 | struct clk *p; | 297 | printk(KERN_ERR "No custom clock functions registered\n"); |
1286 | __u32 regval32; | 298 | BUG(); |
1287 | |||
1288 | /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ | ||
1289 | regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4); | ||
1290 | omap_writew(regval32, SOFT_REQ_REG); | ||
1291 | omap_writew(0, SOFT_REQ_REG2); | ||
1292 | |||
1293 | list_for_each_entry(p, &clocks, node) { | ||
1294 | if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) || | ||
1295 | p->enable_reg == 0) | ||
1296 | continue; | ||
1297 | |||
1298 | /* Assume no DSP clocks have been activated by bootloader */ | ||
1299 | if (p->flags & DSP_DOMAIN_CLOCK) | ||
1300 | continue; | ||
1301 | |||
1302 | /* Is the clock already disabled? */ | ||
1303 | if (p->flags & ENABLE_REG_32BIT) { | ||
1304 | if (p->flags & VIRTUAL_IO_ADDRESS) | ||
1305 | regval32 = __raw_readl(p->enable_reg); | ||
1306 | else | ||
1307 | regval32 = omap_readl(p->enable_reg); | ||
1308 | } else { | ||
1309 | if (p->flags & VIRTUAL_IO_ADDRESS) | ||
1310 | regval32 = __raw_readw(p->enable_reg); | ||
1311 | else | ||
1312 | regval32 = omap_readw(p->enable_reg); | ||
1313 | } | ||
1314 | |||
1315 | if ((regval32 & (1 << p->enable_bit)) == 0) | ||
1316 | continue; | ||
1317 | |||
1318 | /* FIXME: This clock seems to be necessary but no-one | ||
1319 | * has asked for its activation. */ | ||
1320 | if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera | ||
1321 | || p == &ck_dpll1out // FIX: SoSSI, SSR | ||
1322 | || p == &arm_gpio_ck // FIX: GPIO code for 1510 | ||
1323 | ) { | ||
1324 | printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", | ||
1325 | p->name); | ||
1326 | continue; | ||
1327 | } | ||
1328 | |||
1329 | printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); | ||
1330 | __clk_disable(p); | ||
1331 | printk(" done\n"); | ||
1332 | } | 299 | } |
1333 | 300 | ||
301 | arch_clock = custom_clocks; | ||
302 | |||
1334 | return 0; | 303 | return 0; |
1335 | } | 304 | } |
1336 | |||
1337 | late_initcall(omap_late_clk_reset); | ||
1338 | |||
1339 | #endif | ||
diff --git a/arch/arm/plat-omap/clock.h b/arch/arm/plat-omap/clock.h deleted file mode 100644 index a89e1e8c2519..000000000000 --- a/arch/arm/plat-omap/clock.h +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/plat-omap/clock.h | ||
3 | * | ||
4 | * Copyright (C) 2004 Nokia corporation | ||
5 | * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> | ||
6 | * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ARCH_ARM_OMAP_CLOCK_H | ||
14 | #define __ARCH_ARM_OMAP_CLOCK_H | ||
15 | |||
16 | struct module; | ||
17 | |||
18 | struct clk { | ||
19 | struct list_head node; | ||
20 | struct module *owner; | ||
21 | const char *name; | ||
22 | struct clk *parent; | ||
23 | unsigned long rate; | ||
24 | __s8 usecount; | ||
25 | __u16 flags; | ||
26 | __u32 enable_reg; | ||
27 | __u8 enable_bit; | ||
28 | __u8 rate_offset; | ||
29 | void (*recalc)(struct clk *); | ||
30 | int (*set_rate)(struct clk *, unsigned long); | ||
31 | long (*round_rate)(struct clk *, unsigned long); | ||
32 | void (*init)(struct clk *); | ||
33 | }; | ||
34 | |||
35 | |||
36 | struct mpu_rate { | ||
37 | unsigned long rate; | ||
38 | unsigned long xtal; | ||
39 | unsigned long pll_rate; | ||
40 | __u16 ckctl_val; | ||
41 | __u16 dpllctl_val; | ||
42 | }; | ||
43 | |||
44 | |||
45 | /* Clock flags */ | ||
46 | #define RATE_CKCTL 1 | ||
47 | #define RATE_FIXED 2 | ||
48 | #define RATE_PROPAGATES 4 | ||
49 | #define VIRTUAL_CLOCK 8 | ||
50 | #define ALWAYS_ENABLED 16 | ||
51 | #define ENABLE_REG_32BIT 32 | ||
52 | #define CLOCK_IN_OMAP16XX 64 | ||
53 | #define CLOCK_IN_OMAP1510 128 | ||
54 | #define CLOCK_IN_OMAP730 256 | ||
55 | #define DSP_DOMAIN_CLOCK 512 | ||
56 | #define VIRTUAL_IO_ADDRESS 1024 | ||
57 | |||
58 | /* ARM_CKCTL bit shifts */ | ||
59 | #define CKCTL_PERDIV_OFFSET 0 | ||
60 | #define CKCTL_LCDDIV_OFFSET 2 | ||
61 | #define CKCTL_ARMDIV_OFFSET 4 | ||
62 | #define CKCTL_DSPDIV_OFFSET 6 | ||
63 | #define CKCTL_TCDIV_OFFSET 8 | ||
64 | #define CKCTL_DSPMMUDIV_OFFSET 10 | ||
65 | /*#define ARM_TIMXO 12*/ | ||
66 | #define EN_DSPCK 13 | ||
67 | /*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */ | ||
68 | /* DSP_CKCTL bit shifts */ | ||
69 | #define CKCTL_DSPPERDIV_OFFSET 0 | ||
70 | |||
71 | /* ARM_IDLECT1 bit shifts */ | ||
72 | /*#define IDLWDT_ARM 0*/ | ||
73 | /*#define IDLXORP_ARM 1*/ | ||
74 | /*#define IDLPER_ARM 2*/ | ||
75 | /*#define IDLLCD_ARM 3*/ | ||
76 | /*#define IDLLB_ARM 4*/ | ||
77 | /*#define IDLHSAB_ARM 5*/ | ||
78 | /*#define IDLIF_ARM 6*/ | ||
79 | /*#define IDLDPLL_ARM 7*/ | ||
80 | /*#define IDLAPI_ARM 8*/ | ||
81 | /*#define IDLTIM_ARM 9*/ | ||
82 | /*#define SETARM_IDLE 11*/ | ||
83 | |||
84 | /* ARM_IDLECT2 bit shifts */ | ||
85 | #define EN_WDTCK 0 | ||
86 | #define EN_XORPCK 1 | ||
87 | #define EN_PERCK 2 | ||
88 | #define EN_LCDCK 3 | ||
89 | #define EN_LBCK 4 /* Not on 1610/1710 */ | ||
90 | /*#define EN_HSABCK 5*/ | ||
91 | #define EN_APICK 6 | ||
92 | #define EN_TIMCK 7 | ||
93 | #define DMACK_REQ 8 | ||
94 | #define EN_GPIOCK 9 /* Not on 1610/1710 */ | ||
95 | /*#define EN_LBFREECK 10*/ | ||
96 | #define EN_CKOUT_ARM 11 | ||
97 | |||
98 | /* ARM_IDLECT3 bit shifts */ | ||
99 | #define EN_OCPI_CK 0 | ||
100 | #define EN_TC1_CK 2 | ||
101 | #define EN_TC2_CK 4 | ||
102 | |||
103 | /* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */ | ||
104 | #define EN_DSPTIMCK 5 | ||
105 | |||
106 | /* Various register defines for clock controls scattered around OMAP chip */ | ||
107 | #define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ | ||
108 | #define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ | ||
109 | #define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ | ||
110 | #define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */ | ||
111 | #define SWD_CLK_DIV_CTRL_SEL 0xfffe0874 | ||
112 | #define COM_CLK_DIV_CTRL_SEL 0xfffe0878 | ||
113 | #define SOFT_REQ_REG 0xfffe0834 | ||
114 | #define SOFT_REQ_REG2 0xfffe0880 | ||
115 | |||
116 | int clk_register(struct clk *clk); | ||
117 | void clk_unregister(struct clk *clk); | ||
118 | int clk_init(void); | ||
119 | |||
120 | #endif | ||
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index 02bcc6c1cd1b..ccdb452630cf 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <asm/arch/mux.h> | 31 | #include <asm/arch/mux.h> |
32 | #include <asm/arch/fpga.h> | 32 | #include <asm/arch/fpga.h> |
33 | 33 | ||
34 | #include "clock.h" | 34 | #include <asm/arch/clock.h> |
35 | 35 | ||
36 | #define NO_LENGTH_CHECK 0xffffffff | 36 | #define NO_LENGTH_CHECK 0xffffffff |
37 | 37 | ||
@@ -117,19 +117,43 @@ EXPORT_SYMBOL(omap_get_var_config); | |||
117 | 117 | ||
118 | static int __init omap_add_serial_console(void) | 118 | static int __init omap_add_serial_console(void) |
119 | { | 119 | { |
120 | const struct omap_serial_console_config *info; | 120 | const struct omap_serial_console_config *con_info; |
121 | 121 | const struct omap_uart_config *uart_info; | |
122 | info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE, | 122 | static char speed[11], *opt = NULL; |
123 | struct omap_serial_console_config); | 123 | int line, i, uart_idx; |
124 | if (info != NULL && info->console_uart) { | 124 | |
125 | static char speed[11], *opt = NULL; | 125 | uart_info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config); |
126 | con_info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE, | ||
127 | struct omap_serial_console_config); | ||
128 | if (uart_info == NULL || con_info == NULL) | ||
129 | return 0; | ||
130 | |||
131 | if (con_info->console_uart == 0) | ||
132 | return 0; | ||
133 | |||
134 | if (con_info->console_speed) { | ||
135 | snprintf(speed, sizeof(speed), "%u", con_info->console_speed); | ||
136 | opt = speed; | ||
137 | } | ||
126 | 138 | ||
127 | if (info->console_speed) { | 139 | uart_idx = con_info->console_uart - 1; |
128 | snprintf(speed, sizeof(speed), "%u", info->console_speed); | 140 | if (uart_idx >= OMAP_MAX_NR_PORTS) { |
129 | opt = speed; | 141 | printk(KERN_INFO "Console: external UART#%d. " |
130 | } | 142 | "Not adding it as console this time.\n", |
131 | return add_preferred_console("ttyS", info->console_uart - 1, opt); | 143 | uart_idx + 1); |
144 | return 0; | ||
145 | } | ||
146 | if (!(uart_info->enabled_uarts & (1 << uart_idx))) { | ||
147 | printk(KERN_ERR "Console: Selected UART#%d is " | ||
148 | "not enabled for this platform\n", | ||
149 | uart_idx + 1); | ||
150 | return -1; | ||
151 | } | ||
152 | line = 0; | ||
153 | for (i = 0; i < uart_idx; i++) { | ||
154 | if (uart_info->enabled_uarts & (1 << i)) | ||
155 | line++; | ||
132 | } | 156 | } |
133 | return 0; | 157 | return add_preferred_console("ttyS", line, opt); |
134 | } | 158 | } |
135 | console_initcall(omap_add_serial_console); | 159 | console_initcall(omap_add_serial_console); |
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c new file mode 100644 index 000000000000..9dcce904b608 --- /dev/null +++ b/arch/arm/plat-omap/devices.c | |||
@@ -0,0 +1,381 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/plat-omap/devices.c | ||
3 | * | ||
4 | * Common platform device setup/initialization for OMAP1 and OMAP2 | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include <asm/hardware.h> | ||
19 | #include <asm/io.h> | ||
20 | #include <asm/mach-types.h> | ||
21 | #include <asm/mach/map.h> | ||
22 | |||
23 | #include <asm/arch/tc.h> | ||
24 | #include <asm/arch/board.h> | ||
25 | #include <asm/arch/mux.h> | ||
26 | #include <asm/arch/gpio.h> | ||
27 | |||
28 | |||
29 | void omap_nop_release(struct device *dev) | ||
30 | { | ||
31 | /* Nothing */ | ||
32 | } | ||
33 | |||
34 | /*-------------------------------------------------------------------------*/ | ||
35 | |||
36 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) | ||
37 | |||
38 | #define OMAP1_I2C_BASE 0xfffb3800 | ||
39 | #define OMAP2_I2C_BASE1 0x48070000 | ||
40 | #define OMAP_I2C_SIZE 0x3f | ||
41 | #define OMAP1_I2C_INT INT_I2C | ||
42 | #define OMAP2_I2C_INT1 56 | ||
43 | |||
44 | static struct resource i2c_resources1[] = { | ||
45 | { | ||
46 | .start = 0, | ||
47 | .end = 0, | ||
48 | .flags = IORESOURCE_MEM, | ||
49 | }, | ||
50 | { | ||
51 | .start = 0, | ||
52 | .flags = IORESOURCE_IRQ, | ||
53 | }, | ||
54 | }; | ||
55 | |||
56 | /* DMA not used; works around erratum writing to non-empty i2c fifo */ | ||
57 | |||
58 | static struct platform_device omap_i2c_device1 = { | ||
59 | .name = "i2c_omap", | ||
60 | .id = 1, | ||
61 | .dev = { | ||
62 | .release = omap_nop_release, | ||
63 | }, | ||
64 | .num_resources = ARRAY_SIZE(i2c_resources1), | ||
65 | .resource = i2c_resources1, | ||
66 | }; | ||
67 | |||
68 | /* See also arch/arm/mach-omap2/devices.c for second I2C on 24xx */ | ||
69 | static void omap_init_i2c(void) | ||
70 | { | ||
71 | if (cpu_is_omap24xx()) { | ||
72 | i2c_resources1[0].start = OMAP2_I2C_BASE1; | ||
73 | i2c_resources1[0].end = OMAP2_I2C_BASE1 + OMAP_I2C_SIZE; | ||
74 | i2c_resources1[1].start = OMAP2_I2C_INT1; | ||
75 | } else { | ||
76 | i2c_resources1[0].start = OMAP1_I2C_BASE; | ||
77 | i2c_resources1[0].end = OMAP1_I2C_BASE + OMAP_I2C_SIZE; | ||
78 | i2c_resources1[1].start = OMAP1_I2C_INT; | ||
79 | } | ||
80 | |||
81 | /* FIXME define and use a boot tag, in case of boards that | ||
82 | * either don't wire up I2C, or chips that mux it differently... | ||
83 | * it can include clocking and address info, maybe more. | ||
84 | */ | ||
85 | if (cpu_is_omap24xx()) { | ||
86 | omap_cfg_reg(M19_24XX_I2C1_SCL); | ||
87 | omap_cfg_reg(L15_24XX_I2C1_SDA); | ||
88 | } else { | ||
89 | omap_cfg_reg(I2C_SCL); | ||
90 | omap_cfg_reg(I2C_SDA); | ||
91 | } | ||
92 | |||
93 | (void) platform_device_register(&omap_i2c_device1); | ||
94 | } | ||
95 | |||
96 | #else | ||
97 | static inline void omap_init_i2c(void) {} | ||
98 | #endif | ||
99 | |||
100 | /*-------------------------------------------------------------------------*/ | ||
101 | |||
102 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) | ||
103 | |||
104 | #ifdef CONFIG_ARCH_OMAP24XX | ||
105 | #define OMAP_MMC1_BASE 0x4809c000 | ||
106 | #define OMAP_MMC1_INT 83 | ||
107 | #else | ||
108 | #define OMAP_MMC1_BASE 0xfffb7800 | ||
109 | #define OMAP_MMC1_INT INT_MMC | ||
110 | #endif | ||
111 | #define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */ | ||
112 | |||
113 | static struct omap_mmc_conf mmc1_conf; | ||
114 | |||
115 | static u64 mmc1_dmamask = 0xffffffff; | ||
116 | |||
117 | static struct resource mmc1_resources[] = { | ||
118 | { | ||
119 | .start = IO_ADDRESS(OMAP_MMC1_BASE), | ||
120 | .end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f, | ||
121 | .flags = IORESOURCE_MEM, | ||
122 | }, | ||
123 | { | ||
124 | .start = OMAP_MMC1_INT, | ||
125 | .flags = IORESOURCE_IRQ, | ||
126 | }, | ||
127 | }; | ||
128 | |||
129 | static struct platform_device mmc_omap_device1 = { | ||
130 | .name = "mmci-omap", | ||
131 | .id = 1, | ||
132 | .dev = { | ||
133 | .release = omap_nop_release, | ||
134 | .dma_mask = &mmc1_dmamask, | ||
135 | .platform_data = &mmc1_conf, | ||
136 | }, | ||
137 | .num_resources = ARRAY_SIZE(mmc1_resources), | ||
138 | .resource = mmc1_resources, | ||
139 | }; | ||
140 | |||
141 | #ifdef CONFIG_ARCH_OMAP16XX | ||
142 | |||
143 | static struct omap_mmc_conf mmc2_conf; | ||
144 | |||
145 | static u64 mmc2_dmamask = 0xffffffff; | ||
146 | |||
147 | static struct resource mmc2_resources[] = { | ||
148 | { | ||
149 | .start = IO_ADDRESS(OMAP_MMC2_BASE), | ||
150 | .end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f, | ||
151 | .flags = IORESOURCE_MEM, | ||
152 | }, | ||
153 | { | ||
154 | .start = INT_1610_MMC2, | ||
155 | .flags = IORESOURCE_IRQ, | ||
156 | }, | ||
157 | }; | ||
158 | |||
159 | static struct platform_device mmc_omap_device2 = { | ||
160 | .name = "mmci-omap", | ||
161 | .id = 2, | ||
162 | .dev = { | ||
163 | .release = omap_nop_release, | ||
164 | .dma_mask = &mmc2_dmamask, | ||
165 | .platform_data = &mmc2_conf, | ||
166 | }, | ||
167 | .num_resources = ARRAY_SIZE(mmc2_resources), | ||
168 | .resource = mmc2_resources, | ||
169 | }; | ||
170 | #endif | ||
171 | |||
172 | static void __init omap_init_mmc(void) | ||
173 | { | ||
174 | const struct omap_mmc_config *mmc_conf; | ||
175 | const struct omap_mmc_conf *mmc; | ||
176 | |||
177 | /* NOTE: assumes MMC was never (wrongly) enabled */ | ||
178 | mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config); | ||
179 | if (!mmc_conf) | ||
180 | return; | ||
181 | |||
182 | /* block 1 is always available and has just one pinout option */ | ||
183 | mmc = &mmc_conf->mmc[0]; | ||
184 | if (mmc->enabled) { | ||
185 | if (!cpu_is_omap24xx()) { | ||
186 | omap_cfg_reg(MMC_CMD); | ||
187 | omap_cfg_reg(MMC_CLK); | ||
188 | omap_cfg_reg(MMC_DAT0); | ||
189 | if (cpu_is_omap1710()) { | ||
190 | omap_cfg_reg(M15_1710_MMC_CLKI); | ||
191 | omap_cfg_reg(P19_1710_MMC_CMDDIR); | ||
192 | omap_cfg_reg(P20_1710_MMC_DATDIR0); | ||
193 | } | ||
194 | } | ||
195 | if (mmc->wire4) { | ||
196 | if (!cpu_is_omap24xx()) { | ||
197 | omap_cfg_reg(MMC_DAT1); | ||
198 | /* NOTE: DAT2 can be on W10 (here) or M15 */ | ||
199 | if (!mmc->nomux) | ||
200 | omap_cfg_reg(MMC_DAT2); | ||
201 | omap_cfg_reg(MMC_DAT3); | ||
202 | } | ||
203 | } | ||
204 | mmc1_conf = *mmc; | ||
205 | (void) platform_device_register(&mmc_omap_device1); | ||
206 | } | ||
207 | |||
208 | #ifdef CONFIG_ARCH_OMAP16XX | ||
209 | /* block 2 is on newer chips, and has many pinout options */ | ||
210 | mmc = &mmc_conf->mmc[1]; | ||
211 | if (mmc->enabled) { | ||
212 | if (!mmc->nomux) { | ||
213 | omap_cfg_reg(Y8_1610_MMC2_CMD); | ||
214 | omap_cfg_reg(Y10_1610_MMC2_CLK); | ||
215 | omap_cfg_reg(R18_1610_MMC2_CLKIN); | ||
216 | omap_cfg_reg(W8_1610_MMC2_DAT0); | ||
217 | if (mmc->wire4) { | ||
218 | omap_cfg_reg(V8_1610_MMC2_DAT1); | ||
219 | omap_cfg_reg(W15_1610_MMC2_DAT2); | ||
220 | omap_cfg_reg(R10_1610_MMC2_DAT3); | ||
221 | } | ||
222 | |||
223 | /* These are needed for the level shifter */ | ||
224 | omap_cfg_reg(V9_1610_MMC2_CMDDIR); | ||
225 | omap_cfg_reg(V5_1610_MMC2_DATDIR0); | ||
226 | omap_cfg_reg(W19_1610_MMC2_DATDIR1); | ||
227 | } | ||
228 | |||
229 | /* Feedback clock must be set on OMAP-1710 MMC2 */ | ||
230 | if (cpu_is_omap1710()) | ||
231 | omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24), | ||
232 | MOD_CONF_CTRL_1); | ||
233 | mmc2_conf = *mmc; | ||
234 | (void) platform_device_register(&mmc_omap_device2); | ||
235 | } | ||
236 | #endif | ||
237 | return; | ||
238 | } | ||
239 | #else | ||
240 | static inline void omap_init_mmc(void) {} | ||
241 | #endif | ||
242 | |||
243 | #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) | ||
244 | |||
245 | #ifdef CONFIG_ARCH_OMAP24XX | ||
246 | #define OMAP_WDT_BASE 0x48022000 | ||
247 | #else | ||
248 | #define OMAP_WDT_BASE 0xfffeb000 | ||
249 | #endif | ||
250 | |||
251 | static struct resource wdt_resources[] = { | ||
252 | { | ||
253 | .start = OMAP_WDT_BASE, | ||
254 | .end = OMAP_WDT_BASE + 0x4f, | ||
255 | .flags = IORESOURCE_MEM, | ||
256 | }, | ||
257 | }; | ||
258 | |||
259 | static struct platform_device omap_wdt_device = { | ||
260 | .name = "omap_wdt", | ||
261 | .id = -1, | ||
262 | .dev = { | ||
263 | .release = omap_nop_release, | ||
264 | }, | ||
265 | .num_resources = ARRAY_SIZE(wdt_resources), | ||
266 | .resource = wdt_resources, | ||
267 | }; | ||
268 | |||
269 | static void omap_init_wdt(void) | ||
270 | { | ||
271 | (void) platform_device_register(&omap_wdt_device); | ||
272 | } | ||
273 | #else | ||
274 | static inline void omap_init_wdt(void) {} | ||
275 | #endif | ||
276 | |||
277 | /*-------------------------------------------------------------------------*/ | ||
278 | |||
279 | #if defined(CONFIG_OMAP_RNG) || defined(CONFIG_OMAP_RNG_MODULE) | ||
280 | |||
281 | #ifdef CONFIG_ARCH_OMAP24XX | ||
282 | #define OMAP_RNG_BASE 0x480A0000 | ||
283 | #else | ||
284 | #define OMAP_RNG_BASE 0xfffe5000 | ||
285 | #endif | ||
286 | |||
287 | static struct resource rng_resources[] = { | ||
288 | { | ||
289 | .start = OMAP_RNG_BASE, | ||
290 | .end = OMAP_RNG_BASE + 0x4f, | ||
291 | .flags = IORESOURCE_MEM, | ||
292 | }, | ||
293 | }; | ||
294 | |||
295 | static struct platform_device omap_rng_device = { | ||
296 | .name = "omap_rng", | ||
297 | .id = -1, | ||
298 | .dev = { | ||
299 | .release = omap_nop_release, | ||
300 | }, | ||
301 | .num_resources = ARRAY_SIZE(rng_resources), | ||
302 | .resource = rng_resources, | ||
303 | }; | ||
304 | |||
305 | static void omap_init_rng(void) | ||
306 | { | ||
307 | (void) platform_device_register(&omap_rng_device); | ||
308 | } | ||
309 | #else | ||
310 | static inline void omap_init_rng(void) {} | ||
311 | #endif | ||
312 | |||
313 | #if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE) | ||
314 | |||
315 | static struct omap_lcd_config omap_fb_conf; | ||
316 | |||
317 | static u64 omap_fb_dma_mask = ~(u32)0; | ||
318 | |||
319 | static struct platform_device omap_fb_device = { | ||
320 | .name = "omapfb", | ||
321 | .id = -1, | ||
322 | .dev = { | ||
323 | .release = omap_nop_release, | ||
324 | .dma_mask = &omap_fb_dma_mask, | ||
325 | .coherent_dma_mask = ~(u32)0, | ||
326 | .platform_data = &omap_fb_conf, | ||
327 | }, | ||
328 | .num_resources = 0, | ||
329 | }; | ||
330 | |||
331 | static inline void omap_init_fb(void) | ||
332 | { | ||
333 | const struct omap_lcd_config *conf; | ||
334 | |||
335 | conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config); | ||
336 | if (conf != NULL) | ||
337 | omap_fb_conf = *conf; | ||
338 | platform_device_register(&omap_fb_device); | ||
339 | } | ||
340 | |||
341 | #else | ||
342 | |||
343 | static inline void omap_init_fb(void) {} | ||
344 | |||
345 | #endif | ||
346 | |||
347 | /* | ||
348 | * This gets called after board-specific INIT_MACHINE, and initializes most | ||
349 | * on-chip peripherals accessible on this board (except for few like USB): | ||
350 | * | ||
351 | * (a) Does any "standard config" pin muxing needed. Board-specific | ||
352 | * code will have muxed GPIO pins and done "nonstandard" setup; | ||
353 | * that code could live in the boot loader. | ||
354 | * (b) Populating board-specific platform_data with the data drivers | ||
355 | * rely on to handle wiring variations. | ||
356 | * (c) Creating platform devices as meaningful on this board and | ||
357 | * with this kernel configuration. | ||
358 | * | ||
359 | * Claiming GPIOs, and setting their direction and initial values, is the | ||
360 | * responsibility of the device drivers. So is responding to probe(). | ||
361 | * | ||
362 | * Board-specific knowlege like creating devices or pin setup is to be | ||
363 | * kept out of drivers as much as possible. In particular, pin setup | ||
364 | * may be handled by the boot loader, and drivers should expect it will | ||
365 | * normally have been done by the time they're probed. | ||
366 | */ | ||
367 | static int __init omap_init_devices(void) | ||
368 | { | ||
369 | /* please keep these calls, and their implementations above, | ||
370 | * in alphabetical order so they're easier to sort through. | ||
371 | */ | ||
372 | omap_init_fb(); | ||
373 | omap_init_i2c(); | ||
374 | omap_init_mmc(); | ||
375 | omap_init_wdt(); | ||
376 | omap_init_rng(); | ||
377 | |||
378 | return 0; | ||
379 | } | ||
380 | arch_initcall(omap_init_devices); | ||
381 | |||
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index da7b65145658..f5cc21ad0956 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c | |||
@@ -6,6 +6,8 @@ | |||
6 | * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> | 6 | * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> |
7 | * Graphics DMA and LCD DMA graphics tranformations | 7 | * Graphics DMA and LCD DMA graphics tranformations |
8 | * by Imre Deak <imre.deak@nokia.com> | 8 | * by Imre Deak <imre.deak@nokia.com> |
9 | * OMAP2 support Copyright (C) 2004-2005 Texas Instruments, Inc. | ||
10 | * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com> | ||
9 | * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. | 11 | * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. |
10 | * | 12 | * |
11 | * Support functions for the OMAP internal DMA channels. | 13 | * Support functions for the OMAP internal DMA channels. |
@@ -31,8 +33,15 @@ | |||
31 | 33 | ||
32 | #include <asm/arch/tc.h> | 34 | #include <asm/arch/tc.h> |
33 | 35 | ||
34 | #define OMAP_DMA_ACTIVE 0x01 | 36 | #define DEBUG_PRINTS |
37 | #undef DEBUG_PRINTS | ||
38 | #ifdef DEBUG_PRINTS | ||
39 | #define debug_printk(x) printk x | ||
40 | #else | ||
41 | #define debug_printk(x) | ||
42 | #endif | ||
35 | 43 | ||
44 | #define OMAP_DMA_ACTIVE 0x01 | ||
36 | #define OMAP_DMA_CCR_EN (1 << 7) | 45 | #define OMAP_DMA_CCR_EN (1 << 7) |
37 | 46 | ||
38 | #define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) | 47 | #define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) |
@@ -55,7 +64,7 @@ static int dma_chan_count; | |||
55 | static spinlock_t dma_chan_lock; | 64 | static spinlock_t dma_chan_lock; |
56 | static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT]; | 65 | static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT]; |
57 | 66 | ||
58 | const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = { | 67 | const static u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = { |
59 | INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3, | 68 | INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3, |
60 | INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7, | 69 | INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7, |
61 | INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10, | 70 | INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10, |
@@ -63,6 +72,20 @@ const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = { | |||
63 | INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD | 72 | INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD |
64 | }; | 73 | }; |
65 | 74 | ||
75 | #define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \ | ||
76 | __FUNCTION__); | ||
77 | |||
78 | #ifdef CONFIG_ARCH_OMAP15XX | ||
79 | /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */ | ||
80 | int omap_dma_in_1510_mode(void) | ||
81 | { | ||
82 | return enable_1510_mode; | ||
83 | } | ||
84 | #else | ||
85 | #define omap_dma_in_1510_mode() 0 | ||
86 | #endif | ||
87 | |||
88 | #ifdef CONFIG_ARCH_OMAP1 | ||
66 | static inline int get_gdma_dev(int req) | 89 | static inline int get_gdma_dev(int req) |
67 | { | 90 | { |
68 | u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4; | 91 | u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4; |
@@ -82,6 +105,9 @@ static inline void set_gdma_dev(int req, int dev) | |||
82 | l |= (dev - 1) << shift; | 105 | l |= (dev - 1) << shift; |
83 | omap_writel(l, reg); | 106 | omap_writel(l, reg); |
84 | } | 107 | } |
108 | #else | ||
109 | #define set_gdma_dev(req, dev) do {} while (0) | ||
110 | #endif | ||
85 | 111 | ||
86 | static void clear_lch_regs(int lch) | 112 | static void clear_lch_regs(int lch) |
87 | { | 113 | { |
@@ -121,38 +147,62 @@ void omap_set_dma_priority(int dst_port, int priority) | |||
121 | } | 147 | } |
122 | 148 | ||
123 | void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, | 149 | void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, |
124 | int frame_count, int sync_mode) | 150 | int frame_count, int sync_mode, |
151 | int dma_trigger, int src_or_dst_synch) | ||
125 | { | 152 | { |
126 | u16 w; | 153 | OMAP_DMA_CSDP_REG(lch) &= ~0x03; |
154 | OMAP_DMA_CSDP_REG(lch) |= data_type; | ||
127 | 155 | ||
128 | w = omap_readw(OMAP_DMA_CSDP(lch)); | 156 | if (cpu_class_is_omap1()) { |
129 | w &= ~0x03; | 157 | OMAP_DMA_CCR_REG(lch) &= ~(1 << 5); |
130 | w |= data_type; | 158 | if (sync_mode == OMAP_DMA_SYNC_FRAME) |
131 | omap_writew(w, OMAP_DMA_CSDP(lch)); | 159 | OMAP_DMA_CCR_REG(lch) |= 1 << 5; |
160 | |||
161 | OMAP1_DMA_CCR2_REG(lch) &= ~(1 << 2); | ||
162 | if (sync_mode == OMAP_DMA_SYNC_BLOCK) | ||
163 | OMAP1_DMA_CCR2_REG(lch) |= 1 << 2; | ||
164 | } | ||
165 | |||
166 | if (cpu_is_omap24xx() && dma_trigger) { | ||
167 | u32 val = OMAP_DMA_CCR_REG(lch); | ||
168 | |||
169 | if (dma_trigger > 63) | ||
170 | val |= 1 << 20; | ||
171 | if (dma_trigger > 31) | ||
172 | val |= 1 << 19; | ||
132 | 173 | ||
133 | w = omap_readw(OMAP_DMA_CCR(lch)); | 174 | val |= (dma_trigger & 0x1f); |
134 | w &= ~(1 << 5); | ||
135 | if (sync_mode == OMAP_DMA_SYNC_FRAME) | ||
136 | w |= 1 << 5; | ||
137 | omap_writew(w, OMAP_DMA_CCR(lch)); | ||
138 | 175 | ||
139 | w = omap_readw(OMAP_DMA_CCR2(lch)); | 176 | if (sync_mode & OMAP_DMA_SYNC_FRAME) |
140 | w &= ~(1 << 2); | 177 | val |= 1 << 5; |
141 | if (sync_mode == OMAP_DMA_SYNC_BLOCK) | ||
142 | w |= 1 << 2; | ||
143 | omap_writew(w, OMAP_DMA_CCR2(lch)); | ||
144 | 178 | ||
145 | omap_writew(elem_count, OMAP_DMA_CEN(lch)); | 179 | if (sync_mode & OMAP_DMA_SYNC_BLOCK) |
146 | omap_writew(frame_count, OMAP_DMA_CFN(lch)); | 180 | val |= 1 << 18; |
147 | 181 | ||
182 | if (src_or_dst_synch) | ||
183 | val |= 1 << 24; /* source synch */ | ||
184 | else | ||
185 | val &= ~(1 << 24); /* dest synch */ | ||
186 | |||
187 | OMAP_DMA_CCR_REG(lch) = val; | ||
188 | } | ||
189 | |||
190 | OMAP_DMA_CEN_REG(lch) = elem_count; | ||
191 | OMAP_DMA_CFN_REG(lch) = frame_count; | ||
148 | } | 192 | } |
193 | |||
149 | void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) | 194 | void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) |
150 | { | 195 | { |
151 | u16 w; | 196 | u16 w; |
152 | 197 | ||
153 | BUG_ON(omap_dma_in_1510_mode()); | 198 | BUG_ON(omap_dma_in_1510_mode()); |
154 | 199 | ||
155 | w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03; | 200 | if (cpu_is_omap24xx()) { |
201 | REVISIT_24XX(); | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | w = OMAP1_DMA_CCR2_REG(lch) & ~0x03; | ||
156 | switch (mode) { | 206 | switch (mode) { |
157 | case OMAP_DMA_CONSTANT_FILL: | 207 | case OMAP_DMA_CONSTANT_FILL: |
158 | w |= 0x01; | 208 | w |= 0x01; |
@@ -165,63 +215,84 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) | |||
165 | default: | 215 | default: |
166 | BUG(); | 216 | BUG(); |
167 | } | 217 | } |
168 | omap_writew(w, OMAP_DMA_CCR2(lch)); | 218 | OMAP1_DMA_CCR2_REG(lch) = w; |
169 | 219 | ||
170 | w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f; | 220 | w = OMAP1_DMA_LCH_CTRL_REG(lch) & ~0x0f; |
171 | /* Default is channel type 2D */ | 221 | /* Default is channel type 2D */ |
172 | if (mode) { | 222 | if (mode) { |
173 | omap_writew((u16)color, OMAP_DMA_COLOR_L(lch)); | 223 | OMAP1_DMA_COLOR_L_REG(lch) = (u16)color; |
174 | omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch)); | 224 | OMAP1_DMA_COLOR_U_REG(lch) = (u16)(color >> 16); |
175 | w |= 1; /* Channel type G */ | 225 | w |= 1; /* Channel type G */ |
176 | } | 226 | } |
177 | omap_writew(w, OMAP_DMA_LCH_CTRL(lch)); | 227 | OMAP1_DMA_LCH_CTRL_REG(lch) = w; |
178 | } | 228 | } |
179 | 229 | ||
180 | 230 | /* Note that src_port is only for omap1 */ | |
181 | void omap_set_dma_src_params(int lch, int src_port, int src_amode, | 231 | void omap_set_dma_src_params(int lch, int src_port, int src_amode, |
182 | unsigned long src_start) | 232 | unsigned long src_start, |
233 | int src_ei, int src_fi) | ||
183 | { | 234 | { |
184 | u16 w; | 235 | if (cpu_class_is_omap1()) { |
236 | OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 2); | ||
237 | OMAP_DMA_CSDP_REG(lch) |= src_port << 2; | ||
238 | } | ||
239 | |||
240 | OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 12); | ||
241 | OMAP_DMA_CCR_REG(lch) |= src_amode << 12; | ||
242 | |||
243 | if (cpu_class_is_omap1()) { | ||
244 | OMAP1_DMA_CSSA_U_REG(lch) = src_start >> 16; | ||
245 | OMAP1_DMA_CSSA_L_REG(lch) = src_start; | ||
246 | } | ||
185 | 247 | ||
186 | w = omap_readw(OMAP_DMA_CSDP(lch)); | 248 | if (cpu_is_omap24xx()) |
187 | w &= ~(0x1f << 2); | 249 | OMAP2_DMA_CSSA_REG(lch) = src_start; |
188 | w |= src_port << 2; | ||
189 | omap_writew(w, OMAP_DMA_CSDP(lch)); | ||
190 | 250 | ||
191 | w = omap_readw(OMAP_DMA_CCR(lch)); | 251 | OMAP_DMA_CSEI_REG(lch) = src_ei; |
192 | w &= ~(0x03 << 12); | 252 | OMAP_DMA_CSFI_REG(lch) = src_fi; |
193 | w |= src_amode << 12; | 253 | } |
194 | omap_writew(w, OMAP_DMA_CCR(lch)); | ||
195 | 254 | ||
196 | omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch)); | 255 | void omap_set_dma_params(int lch, struct omap_dma_channel_params * params) |
197 | omap_writew(src_start, OMAP_DMA_CSSA_L(lch)); | 256 | { |
257 | omap_set_dma_transfer_params(lch, params->data_type, | ||
258 | params->elem_count, params->frame_count, | ||
259 | params->sync_mode, params->trigger, | ||
260 | params->src_or_dst_synch); | ||
261 | omap_set_dma_src_params(lch, params->src_port, | ||
262 | params->src_amode, params->src_start, | ||
263 | params->src_ei, params->src_fi); | ||
264 | |||
265 | omap_set_dma_dest_params(lch, params->dst_port, | ||
266 | params->dst_amode, params->dst_start, | ||
267 | params->dst_ei, params->dst_fi); | ||
198 | } | 268 | } |
199 | 269 | ||
200 | void omap_set_dma_src_index(int lch, int eidx, int fidx) | 270 | void omap_set_dma_src_index(int lch, int eidx, int fidx) |
201 | { | 271 | { |
202 | omap_writew(eidx, OMAP_DMA_CSEI(lch)); | 272 | if (cpu_is_omap24xx()) { |
203 | omap_writew(fidx, OMAP_DMA_CSFI(lch)); | 273 | REVISIT_24XX(); |
274 | return; | ||
275 | } | ||
276 | OMAP_DMA_CSEI_REG(lch) = eidx; | ||
277 | OMAP_DMA_CSFI_REG(lch) = fidx; | ||
204 | } | 278 | } |
205 | 279 | ||
206 | void omap_set_dma_src_data_pack(int lch, int enable) | 280 | void omap_set_dma_src_data_pack(int lch, int enable) |
207 | { | 281 | { |
208 | u16 w; | 282 | OMAP_DMA_CSDP_REG(lch) &= ~(1 << 6); |
209 | 283 | if (enable) | |
210 | w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6); | 284 | OMAP_DMA_CSDP_REG(lch) |= (1 << 6); |
211 | w |= enable ? (1 << 6) : 0; | ||
212 | omap_writew(w, OMAP_DMA_CSDP(lch)); | ||
213 | } | 285 | } |
214 | 286 | ||
215 | void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) | 287 | void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) |
216 | { | 288 | { |
217 | u16 w; | 289 | OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7); |
218 | 290 | ||
219 | w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7); | ||
220 | switch (burst_mode) { | 291 | switch (burst_mode) { |
221 | case OMAP_DMA_DATA_BURST_DIS: | 292 | case OMAP_DMA_DATA_BURST_DIS: |
222 | break; | 293 | break; |
223 | case OMAP_DMA_DATA_BURST_4: | 294 | case OMAP_DMA_DATA_BURST_4: |
224 | w |= (0x01 << 7); | 295 | OMAP_DMA_CSDP_REG(lch) |= (0x02 << 7); |
225 | break; | 296 | break; |
226 | case OMAP_DMA_DATA_BURST_8: | 297 | case OMAP_DMA_DATA_BURST_8: |
227 | /* not supported by current hardware | 298 | /* not supported by current hardware |
@@ -231,110 +302,283 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) | |||
231 | default: | 302 | default: |
232 | BUG(); | 303 | BUG(); |
233 | } | 304 | } |
234 | omap_writew(w, OMAP_DMA_CSDP(lch)); | ||
235 | } | 305 | } |
236 | 306 | ||
307 | /* Note that dest_port is only for OMAP1 */ | ||
237 | void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, | 308 | void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, |
238 | unsigned long dest_start) | 309 | unsigned long dest_start, |
310 | int dst_ei, int dst_fi) | ||
239 | { | 311 | { |
240 | u16 w; | 312 | if (cpu_class_is_omap1()) { |
313 | OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 9); | ||
314 | OMAP_DMA_CSDP_REG(lch) |= dest_port << 9; | ||
315 | } | ||
241 | 316 | ||
242 | w = omap_readw(OMAP_DMA_CSDP(lch)); | 317 | OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 14); |
243 | w &= ~(0x1f << 9); | 318 | OMAP_DMA_CCR_REG(lch) |= dest_amode << 14; |
244 | w |= dest_port << 9; | 319 | |
245 | omap_writew(w, OMAP_DMA_CSDP(lch)); | 320 | if (cpu_class_is_omap1()) { |
321 | OMAP1_DMA_CDSA_U_REG(lch) = dest_start >> 16; | ||
322 | OMAP1_DMA_CDSA_L_REG(lch) = dest_start; | ||
323 | } | ||
246 | 324 | ||
247 | w = omap_readw(OMAP_DMA_CCR(lch)); | 325 | if (cpu_is_omap24xx()) |
248 | w &= ~(0x03 << 14); | 326 | OMAP2_DMA_CDSA_REG(lch) = dest_start; |
249 | w |= dest_amode << 14; | ||
250 | omap_writew(w, OMAP_DMA_CCR(lch)); | ||
251 | 327 | ||
252 | omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch)); | 328 | OMAP_DMA_CDEI_REG(lch) = dst_ei; |
253 | omap_writew(dest_start, OMAP_DMA_CDSA_L(lch)); | 329 | OMAP_DMA_CDFI_REG(lch) = dst_fi; |
254 | } | 330 | } |
255 | 331 | ||
256 | void omap_set_dma_dest_index(int lch, int eidx, int fidx) | 332 | void omap_set_dma_dest_index(int lch, int eidx, int fidx) |
257 | { | 333 | { |
258 | omap_writew(eidx, OMAP_DMA_CDEI(lch)); | 334 | if (cpu_is_omap24xx()) { |
259 | omap_writew(fidx, OMAP_DMA_CDFI(lch)); | 335 | REVISIT_24XX(); |
336 | return; | ||
337 | } | ||
338 | OMAP_DMA_CDEI_REG(lch) = eidx; | ||
339 | OMAP_DMA_CDFI_REG(lch) = fidx; | ||
260 | } | 340 | } |
261 | 341 | ||
262 | void omap_set_dma_dest_data_pack(int lch, int enable) | 342 | void omap_set_dma_dest_data_pack(int lch, int enable) |
263 | { | 343 | { |
264 | u16 w; | 344 | OMAP_DMA_CSDP_REG(lch) &= ~(1 << 13); |
265 | 345 | if (enable) | |
266 | w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13); | 346 | OMAP_DMA_CSDP_REG(lch) |= 1 << 13; |
267 | w |= enable ? (1 << 13) : 0; | ||
268 | omap_writew(w, OMAP_DMA_CSDP(lch)); | ||
269 | } | 347 | } |
270 | 348 | ||
271 | void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) | 349 | void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) |
272 | { | 350 | { |
273 | u16 w; | 351 | OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14); |
274 | 352 | ||
275 | w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14); | ||
276 | switch (burst_mode) { | 353 | switch (burst_mode) { |
277 | case OMAP_DMA_DATA_BURST_DIS: | 354 | case OMAP_DMA_DATA_BURST_DIS: |
278 | break; | 355 | break; |
279 | case OMAP_DMA_DATA_BURST_4: | 356 | case OMAP_DMA_DATA_BURST_4: |
280 | w |= (0x01 << 14); | 357 | OMAP_DMA_CSDP_REG(lch) |= (0x02 << 14); |
281 | break; | 358 | break; |
282 | case OMAP_DMA_DATA_BURST_8: | 359 | case OMAP_DMA_DATA_BURST_8: |
283 | w |= (0x03 << 14); | 360 | OMAP_DMA_CSDP_REG(lch) |= (0x03 << 14); |
284 | break; | 361 | break; |
285 | default: | 362 | default: |
286 | printk(KERN_ERR "Invalid DMA burst mode\n"); | 363 | printk(KERN_ERR "Invalid DMA burst mode\n"); |
287 | BUG(); | 364 | BUG(); |
288 | return; | 365 | return; |
289 | } | 366 | } |
290 | omap_writew(w, OMAP_DMA_CSDP(lch)); | ||
291 | } | 367 | } |
292 | 368 | ||
293 | static inline void init_intr(int lch) | 369 | static inline void omap_enable_channel_irq(int lch) |
294 | { | 370 | { |
295 | u16 w; | 371 | u32 status; |
296 | 372 | ||
297 | /* Read CSR to make sure it's cleared. */ | 373 | /* Read CSR to make sure it's cleared. */ |
298 | w = omap_readw(OMAP_DMA_CSR(lch)); | 374 | status = OMAP_DMA_CSR_REG(lch); |
375 | |||
299 | /* Enable some nice interrupts. */ | 376 | /* Enable some nice interrupts. */ |
300 | omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch)); | 377 | OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs; |
378 | |||
301 | dma_chan[lch].flags |= OMAP_DMA_ACTIVE; | 379 | dma_chan[lch].flags |= OMAP_DMA_ACTIVE; |
302 | } | 380 | } |
303 | 381 | ||
304 | static inline void enable_lnk(int lch) | 382 | static void omap_disable_channel_irq(int lch) |
305 | { | 383 | { |
306 | u16 w; | 384 | if (cpu_is_omap24xx()) |
385 | OMAP_DMA_CICR_REG(lch) = 0; | ||
386 | } | ||
387 | |||
388 | void omap_enable_dma_irq(int lch, u16 bits) | ||
389 | { | ||
390 | dma_chan[lch].enabled_irqs |= bits; | ||
391 | } | ||
307 | 392 | ||
308 | /* Clear the STOP_LNK bits */ | 393 | void omap_disable_dma_irq(int lch, u16 bits) |
309 | w = omap_readw(OMAP_DMA_CLNK_CTRL(lch)); | 394 | { |
310 | w &= ~(1 << 14); | 395 | dma_chan[lch].enabled_irqs &= ~bits; |
311 | omap_writew(w, OMAP_DMA_CLNK_CTRL(lch)); | 396 | } |
397 | |||
398 | static inline void enable_lnk(int lch) | ||
399 | { | ||
400 | if (cpu_class_is_omap1()) | ||
401 | OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 14); | ||
312 | 402 | ||
313 | /* And set the ENABLE_LNK bits */ | 403 | /* Set the ENABLE_LNK bits */ |
314 | if (dma_chan[lch].next_lch != -1) | 404 | if (dma_chan[lch].next_lch != -1) |
315 | omap_writew(dma_chan[lch].next_lch | (1 << 15), | 405 | OMAP_DMA_CLNK_CTRL_REG(lch) = |
316 | OMAP_DMA_CLNK_CTRL(lch)); | 406 | dma_chan[lch].next_lch | (1 << 15); |
317 | } | 407 | } |
318 | 408 | ||
319 | static inline void disable_lnk(int lch) | 409 | static inline void disable_lnk(int lch) |
320 | { | 410 | { |
321 | u16 w; | ||
322 | |||
323 | /* Disable interrupts */ | 411 | /* Disable interrupts */ |
324 | omap_writew(0, OMAP_DMA_CICR(lch)); | 412 | if (cpu_class_is_omap1()) { |
413 | OMAP_DMA_CICR_REG(lch) = 0; | ||
414 | /* Set the STOP_LNK bit */ | ||
415 | OMAP_DMA_CLNK_CTRL_REG(lch) |= 1 << 14; | ||
416 | } | ||
325 | 417 | ||
326 | /* Set the STOP_LNK bit */ | 418 | if (cpu_is_omap24xx()) { |
327 | w = omap_readw(OMAP_DMA_CLNK_CTRL(lch)); | 419 | omap_disable_channel_irq(lch); |
328 | w |= (1 << 14); | 420 | /* Clear the ENABLE_LNK bit */ |
329 | w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch)); | 421 | OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 15); |
422 | } | ||
330 | 423 | ||
331 | dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; | 424 | dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; |
332 | } | 425 | } |
333 | 426 | ||
334 | void omap_start_dma(int lch) | 427 | static inline void omap2_enable_irq_lch(int lch) |
335 | { | 428 | { |
336 | u16 w; | 429 | u32 val; |
430 | |||
431 | if (!cpu_is_omap24xx()) | ||
432 | return; | ||
433 | |||
434 | val = omap_readl(OMAP_DMA4_IRQENABLE_L0); | ||
435 | val |= 1 << lch; | ||
436 | omap_writel(val, OMAP_DMA4_IRQENABLE_L0); | ||
437 | } | ||
438 | |||
439 | int omap_request_dma(int dev_id, const char *dev_name, | ||
440 | void (* callback)(int lch, u16 ch_status, void *data), | ||
441 | void *data, int *dma_ch_out) | ||
442 | { | ||
443 | int ch, free_ch = -1; | ||
444 | unsigned long flags; | ||
445 | struct omap_dma_lch *chan; | ||
446 | |||
447 | spin_lock_irqsave(&dma_chan_lock, flags); | ||
448 | for (ch = 0; ch < dma_chan_count; ch++) { | ||
449 | if (free_ch == -1 && dma_chan[ch].dev_id == -1) { | ||
450 | free_ch = ch; | ||
451 | if (dev_id == 0) | ||
452 | break; | ||
453 | } | ||
454 | } | ||
455 | if (free_ch == -1) { | ||
456 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
457 | return -EBUSY; | ||
458 | } | ||
459 | chan = dma_chan + free_ch; | ||
460 | chan->dev_id = dev_id; | ||
461 | |||
462 | if (cpu_class_is_omap1()) | ||
463 | clear_lch_regs(free_ch); | ||
337 | 464 | ||
465 | if (cpu_is_omap24xx()) | ||
466 | omap_clear_dma(free_ch); | ||
467 | |||
468 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
469 | |||
470 | chan->dev_name = dev_name; | ||
471 | chan->callback = callback; | ||
472 | chan->data = data; | ||
473 | chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | | ||
474 | OMAP_DMA_BLOCK_IRQ; | ||
475 | |||
476 | if (cpu_is_omap24xx()) | ||
477 | chan->enabled_irqs |= OMAP2_DMA_TRANS_ERR_IRQ; | ||
478 | |||
479 | if (cpu_is_omap16xx()) { | ||
480 | /* If the sync device is set, configure it dynamically. */ | ||
481 | if (dev_id != 0) { | ||
482 | set_gdma_dev(free_ch + 1, dev_id); | ||
483 | dev_id = free_ch + 1; | ||
484 | } | ||
485 | /* Disable the 1510 compatibility mode and set the sync device | ||
486 | * id. */ | ||
487 | OMAP_DMA_CCR_REG(free_ch) = dev_id | (1 << 10); | ||
488 | } else if (cpu_is_omap730() || cpu_is_omap15xx()) { | ||
489 | OMAP_DMA_CCR_REG(free_ch) = dev_id; | ||
490 | } | ||
491 | |||
492 | if (cpu_is_omap24xx()) { | ||
493 | omap2_enable_irq_lch(free_ch); | ||
494 | |||
495 | omap_enable_channel_irq(free_ch); | ||
496 | /* Clear the CSR register and IRQ status register */ | ||
497 | OMAP_DMA_CSR_REG(free_ch) = 0x0; | ||
498 | omap_writel(~0x0, OMAP_DMA4_IRQSTATUS_L0); | ||
499 | } | ||
500 | |||
501 | *dma_ch_out = free_ch; | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | void omap_free_dma(int lch) | ||
507 | { | ||
508 | unsigned long flags; | ||
509 | |||
510 | spin_lock_irqsave(&dma_chan_lock, flags); | ||
511 | if (dma_chan[lch].dev_id == -1) { | ||
512 | printk("omap_dma: trying to free nonallocated DMA channel %d\n", | ||
513 | lch); | ||
514 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
515 | return; | ||
516 | } | ||
517 | dma_chan[lch].dev_id = -1; | ||
518 | dma_chan[lch].next_lch = -1; | ||
519 | dma_chan[lch].callback = NULL; | ||
520 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
521 | |||
522 | if (cpu_class_is_omap1()) { | ||
523 | /* Disable all DMA interrupts for the channel. */ | ||
524 | OMAP_DMA_CICR_REG(lch) = 0; | ||
525 | /* Make sure the DMA transfer is stopped. */ | ||
526 | OMAP_DMA_CCR_REG(lch) = 0; | ||
527 | } | ||
528 | |||
529 | if (cpu_is_omap24xx()) { | ||
530 | u32 val; | ||
531 | /* Disable interrupts */ | ||
532 | val = omap_readl(OMAP_DMA4_IRQENABLE_L0); | ||
533 | val &= ~(1 << lch); | ||
534 | omap_writel(val, OMAP_DMA4_IRQENABLE_L0); | ||
535 | |||
536 | /* Clear the CSR register and IRQ status register */ | ||
537 | OMAP_DMA_CSR_REG(lch) = 0x0; | ||
538 | |||
539 | val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); | ||
540 | val |= 1 << lch; | ||
541 | omap_writel(val, OMAP_DMA4_IRQSTATUS_L0); | ||
542 | |||
543 | /* Disable all DMA interrupts for the channel. */ | ||
544 | OMAP_DMA_CICR_REG(lch) = 0; | ||
545 | |||
546 | /* Make sure the DMA transfer is stopped. */ | ||
547 | OMAP_DMA_CCR_REG(lch) = 0; | ||
548 | omap_clear_dma(lch); | ||
549 | } | ||
550 | } | ||
551 | |||
552 | /* | ||
553 | * Clears any DMA state so the DMA engine is ready to restart with new buffers | ||
554 | * through omap_start_dma(). Any buffers in flight are discarded. | ||
555 | */ | ||
556 | void omap_clear_dma(int lch) | ||
557 | { | ||
558 | unsigned long flags; | ||
559 | |||
560 | local_irq_save(flags); | ||
561 | |||
562 | if (cpu_class_is_omap1()) { | ||
563 | int status; | ||
564 | OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN; | ||
565 | |||
566 | /* Clear pending interrupts */ | ||
567 | status = OMAP_DMA_CSR_REG(lch); | ||
568 | } | ||
569 | |||
570 | if (cpu_is_omap24xx()) { | ||
571 | int i; | ||
572 | u32 lch_base = OMAP24XX_DMA_BASE + lch * 0x60 + 0x80; | ||
573 | for (i = 0; i < 0x44; i += 4) | ||
574 | omap_writel(0, lch_base + i); | ||
575 | } | ||
576 | |||
577 | local_irq_restore(flags); | ||
578 | } | ||
579 | |||
580 | void omap_start_dma(int lch) | ||
581 | { | ||
338 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { | 582 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { |
339 | int next_lch, cur_lch; | 583 | int next_lch, cur_lch; |
340 | char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; | 584 | char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; |
@@ -348,31 +592,37 @@ void omap_start_dma(int lch) | |||
348 | do { | 592 | do { |
349 | next_lch = dma_chan[cur_lch].next_lch; | 593 | next_lch = dma_chan[cur_lch].next_lch; |
350 | 594 | ||
351 | /* The loop case: we've been here already */ | 595 | /* The loop case: we've been here already */ |
352 | if (dma_chan_link_map[cur_lch]) | 596 | if (dma_chan_link_map[cur_lch]) |
353 | break; | 597 | break; |
354 | /* Mark the current channel */ | 598 | /* Mark the current channel */ |
355 | dma_chan_link_map[cur_lch] = 1; | 599 | dma_chan_link_map[cur_lch] = 1; |
356 | 600 | ||
357 | enable_lnk(cur_lch); | 601 | enable_lnk(cur_lch); |
358 | init_intr(cur_lch); | 602 | omap_enable_channel_irq(cur_lch); |
359 | 603 | ||
360 | cur_lch = next_lch; | 604 | cur_lch = next_lch; |
361 | } while (next_lch != -1); | 605 | } while (next_lch != -1); |
606 | } else if (cpu_is_omap24xx()) { | ||
607 | /* Errata: Need to write lch even if not using chaining */ | ||
608 | OMAP_DMA_CLNK_CTRL_REG(lch) = lch; | ||
362 | } | 609 | } |
363 | 610 | ||
364 | init_intr(lch); | 611 | omap_enable_channel_irq(lch); |
612 | |||
613 | /* Errata: On ES2.0 BUFFERING disable must be set. | ||
614 | * This will always fail on ES1.0 */ | ||
615 | if (cpu_is_omap24xx()) { | ||
616 | OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN; | ||
617 | } | ||
618 | |||
619 | OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN; | ||
365 | 620 | ||
366 | w = omap_readw(OMAP_DMA_CCR(lch)); | ||
367 | w |= OMAP_DMA_CCR_EN; | ||
368 | omap_writew(w, OMAP_DMA_CCR(lch)); | ||
369 | dma_chan[lch].flags |= OMAP_DMA_ACTIVE; | 621 | dma_chan[lch].flags |= OMAP_DMA_ACTIVE; |
370 | } | 622 | } |
371 | 623 | ||
372 | void omap_stop_dma(int lch) | 624 | void omap_stop_dma(int lch) |
373 | { | 625 | { |
374 | u16 w; | ||
375 | |||
376 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { | 626 | if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { |
377 | int next_lch, cur_lch = lch; | 627 | int next_lch, cur_lch = lch; |
378 | char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; | 628 | char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; |
@@ -393,146 +643,83 @@ void omap_stop_dma(int lch) | |||
393 | 643 | ||
394 | return; | 644 | return; |
395 | } | 645 | } |
646 | |||
396 | /* Disable all interrupts on the channel */ | 647 | /* Disable all interrupts on the channel */ |
397 | omap_writew(0, OMAP_DMA_CICR(lch)); | 648 | if (cpu_class_is_omap1()) |
649 | OMAP_DMA_CICR_REG(lch) = 0; | ||
398 | 650 | ||
399 | w = omap_readw(OMAP_DMA_CCR(lch)); | 651 | OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN; |
400 | w &= ~OMAP_DMA_CCR_EN; | ||
401 | omap_writew(w, OMAP_DMA_CCR(lch)); | ||
402 | dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; | 652 | dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; |
403 | } | 653 | } |
404 | 654 | ||
405 | void omap_enable_dma_irq(int lch, u16 bits) | 655 | /* |
656 | * Returns current physical source address for the given DMA channel. | ||
657 | * If the channel is running the caller must disable interrupts prior calling | ||
658 | * this function and process the returned value before re-enabling interrupt to | ||
659 | * prevent races with the interrupt handler. Note that in continuous mode there | ||
660 | * is a chance for CSSA_L register overflow inbetween the two reads resulting | ||
661 | * in incorrect return value. | ||
662 | */ | ||
663 | dma_addr_t omap_get_dma_src_pos(int lch) | ||
406 | { | 664 | { |
407 | dma_chan[lch].enabled_irqs |= bits; | 665 | dma_addr_t offset; |
408 | } | ||
409 | 666 | ||
410 | void omap_disable_dma_irq(int lch, u16 bits) | 667 | if (cpu_class_is_omap1()) |
411 | { | 668 | offset = (dma_addr_t) (OMAP1_DMA_CSSA_L_REG(lch) | |
412 | dma_chan[lch].enabled_irqs &= ~bits; | 669 | (OMAP1_DMA_CSSA_U_REG(lch) << 16)); |
413 | } | ||
414 | 670 | ||
415 | static int dma_handle_ch(int ch) | 671 | if (cpu_is_omap24xx()) |
416 | { | 672 | offset = OMAP_DMA_CSAC_REG(lch); |
417 | u16 csr; | ||
418 | 673 | ||
419 | if (enable_1510_mode && ch >= 6) { | 674 | return offset; |
420 | csr = dma_chan[ch].saved_csr; | ||
421 | dma_chan[ch].saved_csr = 0; | ||
422 | } else | ||
423 | csr = omap_readw(OMAP_DMA_CSR(ch)); | ||
424 | if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) { | ||
425 | dma_chan[ch + 6].saved_csr = csr >> 7; | ||
426 | csr &= 0x7f; | ||
427 | } | ||
428 | if ((csr & 0x3f) == 0) | ||
429 | return 0; | ||
430 | if (unlikely(dma_chan[ch].dev_id == -1)) { | ||
431 | printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n", | ||
432 | ch, csr); | ||
433 | return 0; | ||
434 | } | ||
435 | if (unlikely(csr & OMAP_DMA_TOUT_IRQ)) | ||
436 | printk(KERN_WARNING "DMA timeout with device %d\n", dma_chan[ch].dev_id); | ||
437 | if (unlikely(csr & OMAP_DMA_DROP_IRQ)) | ||
438 | printk(KERN_WARNING "DMA synchronization event drop occurred with device %d\n", | ||
439 | dma_chan[ch].dev_id); | ||
440 | if (likely(csr & OMAP_DMA_BLOCK_IRQ)) | ||
441 | dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE; | ||
442 | if (likely(dma_chan[ch].callback != NULL)) | ||
443 | dma_chan[ch].callback(ch, csr, dma_chan[ch].data); | ||
444 | return 1; | ||
445 | } | 675 | } |
446 | 676 | ||
447 | static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) | 677 | /* |
678 | * Returns current physical destination address for the given DMA channel. | ||
679 | * If the channel is running the caller must disable interrupts prior calling | ||
680 | * this function and process the returned value before re-enabling interrupt to | ||
681 | * prevent races with the interrupt handler. Note that in continuous mode there | ||
682 | * is a chance for CDSA_L register overflow inbetween the two reads resulting | ||
683 | * in incorrect return value. | ||
684 | */ | ||
685 | dma_addr_t omap_get_dma_dst_pos(int lch) | ||
448 | { | 686 | { |
449 | int ch = ((int) dev_id) - 1; | 687 | dma_addr_t offset; |
450 | int handled = 0; | ||
451 | 688 | ||
452 | for (;;) { | 689 | if (cpu_class_is_omap1()) |
453 | int handled_now = 0; | 690 | offset = (dma_addr_t) (OMAP1_DMA_CDSA_L_REG(lch) | |
691 | (OMAP1_DMA_CDSA_U_REG(lch) << 16)); | ||
454 | 692 | ||
455 | handled_now += dma_handle_ch(ch); | 693 | if (cpu_is_omap24xx()) |
456 | if (enable_1510_mode && dma_chan[ch + 6].saved_csr) | 694 | offset = OMAP2_DMA_CDSA_REG(lch); |
457 | handled_now += dma_handle_ch(ch + 6); | ||
458 | if (!handled_now) | ||
459 | break; | ||
460 | handled += handled_now; | ||
461 | } | ||
462 | 695 | ||
463 | return handled ? IRQ_HANDLED : IRQ_NONE; | 696 | return offset; |
464 | } | 697 | } |
465 | 698 | ||
466 | int omap_request_dma(int dev_id, const char *dev_name, | 699 | /* |
467 | void (* callback)(int lch, u16 ch_status, void *data), | 700 | * Returns current source transfer counting for the given DMA channel. |
468 | void *data, int *dma_ch_out) | 701 | * Can be used to monitor the progress of a transfer inside a block. |
702 | * It must be called with disabled interrupts. | ||
703 | */ | ||
704 | int omap_get_dma_src_addr_counter(int lch) | ||
469 | { | 705 | { |
470 | int ch, free_ch = -1; | 706 | return (dma_addr_t) OMAP_DMA_CSAC_REG(lch); |
471 | unsigned long flags; | ||
472 | struct omap_dma_lch *chan; | ||
473 | |||
474 | spin_lock_irqsave(&dma_chan_lock, flags); | ||
475 | for (ch = 0; ch < dma_chan_count; ch++) { | ||
476 | if (free_ch == -1 && dma_chan[ch].dev_id == -1) { | ||
477 | free_ch = ch; | ||
478 | if (dev_id == 0) | ||
479 | break; | ||
480 | } | ||
481 | } | ||
482 | if (free_ch == -1) { | ||
483 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
484 | return -EBUSY; | ||
485 | } | ||
486 | chan = dma_chan + free_ch; | ||
487 | chan->dev_id = dev_id; | ||
488 | clear_lch_regs(free_ch); | ||
489 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
490 | |||
491 | chan->dev_id = dev_id; | ||
492 | chan->dev_name = dev_name; | ||
493 | chan->callback = callback; | ||
494 | chan->data = data; | ||
495 | chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ; | ||
496 | |||
497 | if (cpu_is_omap16xx()) { | ||
498 | /* If the sync device is set, configure it dynamically. */ | ||
499 | if (dev_id != 0) { | ||
500 | set_gdma_dev(free_ch + 1, dev_id); | ||
501 | dev_id = free_ch + 1; | ||
502 | } | ||
503 | /* Disable the 1510 compatibility mode and set the sync device | ||
504 | * id. */ | ||
505 | omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch)); | ||
506 | } else { | ||
507 | omap_writew(dev_id, OMAP_DMA_CCR(free_ch)); | ||
508 | } | ||
509 | *dma_ch_out = free_ch; | ||
510 | |||
511 | return 0; | ||
512 | } | 707 | } |
513 | 708 | ||
514 | void omap_free_dma(int ch) | 709 | int omap_dma_running(void) |
515 | { | 710 | { |
516 | unsigned long flags; | 711 | int lch; |
517 | 712 | ||
518 | spin_lock_irqsave(&dma_chan_lock, flags); | 713 | /* Check if LCD DMA is running */ |
519 | if (dma_chan[ch].dev_id == -1) { | 714 | if (cpu_is_omap16xx()) |
520 | printk("omap_dma: trying to free nonallocated DMA channel %d\n", ch); | 715 | if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN) |
521 | spin_unlock_irqrestore(&dma_chan_lock, flags); | 716 | return 1; |
522 | return; | ||
523 | } | ||
524 | dma_chan[ch].dev_id = -1; | ||
525 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
526 | 717 | ||
527 | /* Disable all DMA interrupts for the channel. */ | 718 | for (lch = 0; lch < dma_chan_count; lch++) |
528 | omap_writew(0, OMAP_DMA_CICR(ch)); | 719 | if (OMAP_DMA_CCR_REG(lch) & OMAP_DMA_CCR_EN) |
529 | /* Make sure the DMA transfer is stopped. */ | 720 | return 1; |
530 | omap_writew(0, OMAP_DMA_CCR(ch)); | ||
531 | } | ||
532 | 721 | ||
533 | int omap_dma_in_1510_mode(void) | 722 | return 0; |
534 | { | ||
535 | return enable_1510_mode; | ||
536 | } | 723 | } |
537 | 724 | ||
538 | /* | 725 | /* |
@@ -550,7 +737,8 @@ void omap_dma_link_lch (int lch_head, int lch_queue) | |||
550 | 737 | ||
551 | if ((dma_chan[lch_head].dev_id == -1) || | 738 | if ((dma_chan[lch_head].dev_id == -1) || |
552 | (dma_chan[lch_queue].dev_id == -1)) { | 739 | (dma_chan[lch_queue].dev_id == -1)) { |
553 | printk(KERN_ERR "omap_dma: trying to link non requested channels\n"); | 740 | printk(KERN_ERR "omap_dma: trying to link " |
741 | "non requested channels\n"); | ||
554 | dump_stack(); | 742 | dump_stack(); |
555 | } | 743 | } |
556 | 744 | ||
@@ -570,20 +758,149 @@ void omap_dma_unlink_lch (int lch_head, int lch_queue) | |||
570 | 758 | ||
571 | if (dma_chan[lch_head].next_lch != lch_queue || | 759 | if (dma_chan[lch_head].next_lch != lch_queue || |
572 | dma_chan[lch_head].next_lch == -1) { | 760 | dma_chan[lch_head].next_lch == -1) { |
573 | printk(KERN_ERR "omap_dma: trying to unlink non linked channels\n"); | 761 | printk(KERN_ERR "omap_dma: trying to unlink " |
762 | "non linked channels\n"); | ||
574 | dump_stack(); | 763 | dump_stack(); |
575 | } | 764 | } |
576 | 765 | ||
577 | 766 | ||
578 | if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) || | 767 | if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) || |
579 | (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) { | 768 | (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) { |
580 | printk(KERN_ERR "omap_dma: You need to stop the DMA channels before unlinking\n"); | 769 | printk(KERN_ERR "omap_dma: You need to stop the DMA channels " |
770 | "before unlinking\n"); | ||
581 | dump_stack(); | 771 | dump_stack(); |
582 | } | 772 | } |
583 | 773 | ||
584 | dma_chan[lch_head].next_lch = -1; | 774 | dma_chan[lch_head].next_lch = -1; |
585 | } | 775 | } |
586 | 776 | ||
777 | /*----------------------------------------------------------------------------*/ | ||
778 | |||
779 | #ifdef CONFIG_ARCH_OMAP1 | ||
780 | |||
781 | static int omap1_dma_handle_ch(int ch) | ||
782 | { | ||
783 | u16 csr; | ||
784 | |||
785 | if (enable_1510_mode && ch >= 6) { | ||
786 | csr = dma_chan[ch].saved_csr; | ||
787 | dma_chan[ch].saved_csr = 0; | ||
788 | } else | ||
789 | csr = OMAP_DMA_CSR_REG(ch); | ||
790 | if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) { | ||
791 | dma_chan[ch + 6].saved_csr = csr >> 7; | ||
792 | csr &= 0x7f; | ||
793 | } | ||
794 | if ((csr & 0x3f) == 0) | ||
795 | return 0; | ||
796 | if (unlikely(dma_chan[ch].dev_id == -1)) { | ||
797 | printk(KERN_WARNING "Spurious interrupt from DMA channel " | ||
798 | "%d (CSR %04x)\n", ch, csr); | ||
799 | return 0; | ||
800 | } | ||
801 | if (unlikely(csr & OMAP_DMA_TOUT_IRQ)) | ||
802 | printk(KERN_WARNING "DMA timeout with device %d\n", | ||
803 | dma_chan[ch].dev_id); | ||
804 | if (unlikely(csr & OMAP_DMA_DROP_IRQ)) | ||
805 | printk(KERN_WARNING "DMA synchronization event drop occurred " | ||
806 | "with device %d\n", dma_chan[ch].dev_id); | ||
807 | if (likely(csr & OMAP_DMA_BLOCK_IRQ)) | ||
808 | dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE; | ||
809 | if (likely(dma_chan[ch].callback != NULL)) | ||
810 | dma_chan[ch].callback(ch, csr, dma_chan[ch].data); | ||
811 | return 1; | ||
812 | } | ||
813 | |||
814 | static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id, | ||
815 | struct pt_regs *regs) | ||
816 | { | ||
817 | int ch = ((int) dev_id) - 1; | ||
818 | int handled = 0; | ||
819 | |||
820 | for (;;) { | ||
821 | int handled_now = 0; | ||
822 | |||
823 | handled_now += omap1_dma_handle_ch(ch); | ||
824 | if (enable_1510_mode && dma_chan[ch + 6].saved_csr) | ||
825 | handled_now += omap1_dma_handle_ch(ch + 6); | ||
826 | if (!handled_now) | ||
827 | break; | ||
828 | handled += handled_now; | ||
829 | } | ||
830 | |||
831 | return handled ? IRQ_HANDLED : IRQ_NONE; | ||
832 | } | ||
833 | |||
834 | #else | ||
835 | #define omap1_dma_irq_handler NULL | ||
836 | #endif | ||
837 | |||
838 | #ifdef CONFIG_ARCH_OMAP2 | ||
839 | |||
840 | static int omap2_dma_handle_ch(int ch) | ||
841 | { | ||
842 | u32 status = OMAP_DMA_CSR_REG(ch); | ||
843 | u32 val; | ||
844 | |||
845 | if (!status) | ||
846 | return 0; | ||
847 | if (unlikely(dma_chan[ch].dev_id == -1)) | ||
848 | return 0; | ||
849 | /* REVISIT: According to 24xx TRM, there's no TOUT_IE */ | ||
850 | if (unlikely(status & OMAP_DMA_TOUT_IRQ)) | ||
851 | printk(KERN_INFO "DMA timeout with device %d\n", | ||
852 | dma_chan[ch].dev_id); | ||
853 | if (unlikely(status & OMAP_DMA_DROP_IRQ)) | ||
854 | printk(KERN_INFO | ||
855 | "DMA synchronization event drop occurred with device " | ||
856 | "%d\n", dma_chan[ch].dev_id); | ||
857 | |||
858 | if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) | ||
859 | printk(KERN_INFO "DMA transaction error with device %d\n", | ||
860 | dma_chan[ch].dev_id); | ||
861 | |||
862 | OMAP_DMA_CSR_REG(ch) = 0x20; | ||
863 | |||
864 | val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); | ||
865 | /* ch in this function is from 0-31 while in register it is 1-32 */ | ||
866 | val = 1 << (ch); | ||
867 | omap_writel(val, OMAP_DMA4_IRQSTATUS_L0); | ||
868 | |||
869 | if (likely(dma_chan[ch].callback != NULL)) | ||
870 | dma_chan[ch].callback(ch, status, dma_chan[ch].data); | ||
871 | |||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | /* STATUS register count is from 1-32 while our is 0-31 */ | ||
876 | static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id, | ||
877 | struct pt_regs *regs) | ||
878 | { | ||
879 | u32 val; | ||
880 | int i; | ||
881 | |||
882 | val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); | ||
883 | |||
884 | for (i = 1; i <= OMAP_LOGICAL_DMA_CH_COUNT; i++) { | ||
885 | int active = val & (1 << (i - 1)); | ||
886 | if (active) | ||
887 | omap2_dma_handle_ch(i - 1); | ||
888 | } | ||
889 | |||
890 | return IRQ_HANDLED; | ||
891 | } | ||
892 | |||
893 | static struct irqaction omap24xx_dma_irq = { | ||
894 | .name = "DMA", | ||
895 | .handler = omap2_dma_irq_handler, | ||
896 | .flags = SA_INTERRUPT | ||
897 | }; | ||
898 | |||
899 | #else | ||
900 | static struct irqaction omap24xx_dma_irq; | ||
901 | #endif | ||
902 | |||
903 | /*----------------------------------------------------------------------------*/ | ||
587 | 904 | ||
588 | static struct lcd_dma_info { | 905 | static struct lcd_dma_info { |
589 | spinlock_t lock; | 906 | spinlock_t lock; |
@@ -795,7 +1112,7 @@ static void set_b1_regs(void) | |||
795 | /* Always set the source port as SDRAM for now*/ | 1112 | /* Always set the source port as SDRAM for now*/ |
796 | w &= ~(0x03 << 6); | 1113 | w &= ~(0x03 << 6); |
797 | if (lcd_dma.callback != NULL) | 1114 | if (lcd_dma.callback != NULL) |
798 | w |= 1 << 1; /* Block interrupt enable */ | 1115 | w |= 1 << 1; /* Block interrupt enable */ |
799 | else | 1116 | else |
800 | w &= ~(1 << 1); | 1117 | w &= ~(1 << 1); |
801 | omap_writew(w, OMAP1610_DMA_LCD_CTRL); | 1118 | omap_writew(w, OMAP1610_DMA_LCD_CTRL); |
@@ -814,7 +1131,8 @@ static void set_b1_regs(void) | |||
814 | omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L); | 1131 | omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L); |
815 | } | 1132 | } |
816 | 1133 | ||
817 | static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) | 1134 | static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, |
1135 | struct pt_regs *regs) | ||
818 | { | 1136 | { |
819 | u16 w; | 1137 | u16 w; |
820 | 1138 | ||
@@ -870,7 +1188,8 @@ void omap_free_lcd_dma(void) | |||
870 | return; | 1188 | return; |
871 | } | 1189 | } |
872 | if (!enable_1510_mode) | 1190 | if (!enable_1510_mode) |
873 | omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, OMAP1610_DMA_LCD_CCR); | 1191 | omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, |
1192 | OMAP1610_DMA_LCD_CCR); | ||
874 | lcd_dma.reserved = 0; | 1193 | lcd_dma.reserved = 0; |
875 | spin_unlock(&lcd_dma.lock); | 1194 | spin_unlock(&lcd_dma.lock); |
876 | } | 1195 | } |
@@ -939,93 +1258,24 @@ void omap_stop_lcd_dma(void) | |||
939 | omap_writew(w, OMAP1610_DMA_LCD_CTRL); | 1258 | omap_writew(w, OMAP1610_DMA_LCD_CTRL); |
940 | } | 1259 | } |
941 | 1260 | ||
942 | /* | 1261 | /*----------------------------------------------------------------------------*/ |
943 | * Clears any DMA state so the DMA engine is ready to restart with new buffers | ||
944 | * through omap_start_dma(). Any buffers in flight are discarded. | ||
945 | */ | ||
946 | void omap_clear_dma(int lch) | ||
947 | { | ||
948 | unsigned long flags; | ||
949 | int status; | ||
950 | |||
951 | local_irq_save(flags); | ||
952 | omap_writew(omap_readw(OMAP_DMA_CCR(lch)) & ~OMAP_DMA_CCR_EN, | ||
953 | OMAP_DMA_CCR(lch)); | ||
954 | status = OMAP_DMA_CSR(lch); /* clear pending interrupts */ | ||
955 | local_irq_restore(flags); | ||
956 | } | ||
957 | |||
958 | /* | ||
959 | * Returns current physical source address for the given DMA channel. | ||
960 | * If the channel is running the caller must disable interrupts prior calling | ||
961 | * this function and process the returned value before re-enabling interrupt to | ||
962 | * prevent races with the interrupt handler. Note that in continuous mode there | ||
963 | * is a chance for CSSA_L register overflow inbetween the two reads resulting | ||
964 | * in incorrect return value. | ||
965 | */ | ||
966 | dma_addr_t omap_get_dma_src_pos(int lch) | ||
967 | { | ||
968 | return (dma_addr_t) (omap_readw(OMAP_DMA_CSSA_L(lch)) | | ||
969 | (omap_readw(OMAP_DMA_CSSA_U(lch)) << 16)); | ||
970 | } | ||
971 | |||
972 | /* | ||
973 | * Returns current physical destination address for the given DMA channel. | ||
974 | * If the channel is running the caller must disable interrupts prior calling | ||
975 | * this function and process the returned value before re-enabling interrupt to | ||
976 | * prevent races with the interrupt handler. Note that in continuous mode there | ||
977 | * is a chance for CDSA_L register overflow inbetween the two reads resulting | ||
978 | * in incorrect return value. | ||
979 | */ | ||
980 | dma_addr_t omap_get_dma_dst_pos(int lch) | ||
981 | { | ||
982 | return (dma_addr_t) (omap_readw(OMAP_DMA_CDSA_L(lch)) | | ||
983 | (omap_readw(OMAP_DMA_CDSA_U(lch)) << 16)); | ||
984 | } | ||
985 | |||
986 | /* | ||
987 | * Returns current source transfer counting for the given DMA channel. | ||
988 | * Can be used to monitor the progress of a transfer inside a block. | ||
989 | * It must be called with disabled interrupts. | ||
990 | */ | ||
991 | int omap_get_dma_src_addr_counter(int lch) | ||
992 | { | ||
993 | return (dma_addr_t) omap_readw(OMAP_DMA_CSAC(lch)); | ||
994 | } | ||
995 | |||
996 | int omap_dma_running(void) | ||
997 | { | ||
998 | int lch; | ||
999 | |||
1000 | /* Check if LCD DMA is running */ | ||
1001 | if (cpu_is_omap16xx()) | ||
1002 | if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN) | ||
1003 | return 1; | ||
1004 | |||
1005 | for (lch = 0; lch < dma_chan_count; lch++) { | ||
1006 | u16 w; | ||
1007 | |||
1008 | w = omap_readw(OMAP_DMA_CCR(lch)); | ||
1009 | if (w & OMAP_DMA_CCR_EN) | ||
1010 | return 1; | ||
1011 | } | ||
1012 | return 0; | ||
1013 | } | ||
1014 | 1262 | ||
1015 | static int __init omap_init_dma(void) | 1263 | static int __init omap_init_dma(void) |
1016 | { | 1264 | { |
1017 | int ch, r; | 1265 | int ch, r; |
1018 | 1266 | ||
1019 | if (cpu_is_omap1510()) { | 1267 | if (cpu_is_omap15xx()) { |
1020 | printk(KERN_INFO "DMA support for OMAP1510 initialized\n"); | 1268 | printk(KERN_INFO "DMA support for OMAP15xx initialized\n"); |
1021 | dma_chan_count = 9; | 1269 | dma_chan_count = 9; |
1022 | enable_1510_mode = 1; | 1270 | enable_1510_mode = 1; |
1023 | } else if (cpu_is_omap16xx() || cpu_is_omap730()) { | 1271 | } else if (cpu_is_omap16xx() || cpu_is_omap730()) { |
1024 | printk(KERN_INFO "OMAP DMA hardware version %d\n", | 1272 | printk(KERN_INFO "OMAP DMA hardware version %d\n", |
1025 | omap_readw(OMAP_DMA_HW_ID)); | 1273 | omap_readw(OMAP_DMA_HW_ID)); |
1026 | printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n", | 1274 | printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n", |
1027 | (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L), | 1275 | (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | |
1028 | (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L), | 1276 | omap_readw(OMAP_DMA_CAPS_0_L), |
1277 | (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | | ||
1278 | omap_readw(OMAP_DMA_CAPS_1_L), | ||
1029 | omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3), | 1279 | omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3), |
1030 | omap_readw(OMAP_DMA_CAPS_4)); | 1280 | omap_readw(OMAP_DMA_CAPS_4)); |
1031 | if (!enable_1510_mode) { | 1281 | if (!enable_1510_mode) { |
@@ -1038,6 +1288,11 @@ static int __init omap_init_dma(void) | |||
1038 | dma_chan_count = 16; | 1288 | dma_chan_count = 16; |
1039 | } else | 1289 | } else |
1040 | dma_chan_count = 9; | 1290 | dma_chan_count = 9; |
1291 | } else if (cpu_is_omap24xx()) { | ||
1292 | u8 revision = omap_readb(OMAP_DMA4_REVISION); | ||
1293 | printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", | ||
1294 | revision >> 4, revision & 0xf); | ||
1295 | dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT; | ||
1041 | } else { | 1296 | } else { |
1042 | dma_chan_count = 0; | 1297 | dma_chan_count = 0; |
1043 | return 0; | 1298 | return 0; |
@@ -1049,41 +1304,56 @@ static int __init omap_init_dma(void) | |||
1049 | memset(&dma_chan, 0, sizeof(dma_chan)); | 1304 | memset(&dma_chan, 0, sizeof(dma_chan)); |
1050 | 1305 | ||
1051 | for (ch = 0; ch < dma_chan_count; ch++) { | 1306 | for (ch = 0; ch < dma_chan_count; ch++) { |
1307 | omap_clear_dma(ch); | ||
1052 | dma_chan[ch].dev_id = -1; | 1308 | dma_chan[ch].dev_id = -1; |
1053 | dma_chan[ch].next_lch = -1; | 1309 | dma_chan[ch].next_lch = -1; |
1054 | 1310 | ||
1055 | if (ch >= 6 && enable_1510_mode) | 1311 | if (ch >= 6 && enable_1510_mode) |
1056 | continue; | 1312 | continue; |
1057 | 1313 | ||
1058 | /* request_irq() doesn't like dev_id (ie. ch) being zero, | 1314 | if (cpu_class_is_omap1()) { |
1059 | * so we have to kludge around this. */ | 1315 | /* request_irq() doesn't like dev_id (ie. ch) being |
1060 | r = request_irq(dma_irq[ch], dma_irq_handler, 0, "DMA", | 1316 | * zero, so we have to kludge around this. */ |
1061 | (void *) (ch + 1)); | 1317 | r = request_irq(omap1_dma_irq[ch], |
1318 | omap1_dma_irq_handler, 0, "DMA", | ||
1319 | (void *) (ch + 1)); | ||
1320 | if (r != 0) { | ||
1321 | int i; | ||
1322 | |||
1323 | printk(KERN_ERR "unable to request IRQ %d " | ||
1324 | "for DMA (error %d)\n", | ||
1325 | omap1_dma_irq[ch], r); | ||
1326 | for (i = 0; i < ch; i++) | ||
1327 | free_irq(omap1_dma_irq[i], | ||
1328 | (void *) (i + 1)); | ||
1329 | return r; | ||
1330 | } | ||
1331 | } | ||
1332 | } | ||
1333 | |||
1334 | if (cpu_is_omap24xx()) | ||
1335 | setup_irq(INT_24XX_SDMA_IRQ0, &omap24xx_dma_irq); | ||
1336 | |||
1337 | /* FIXME: Update LCD DMA to work on 24xx */ | ||
1338 | if (cpu_class_is_omap1()) { | ||
1339 | r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, | ||
1340 | "LCD DMA", NULL); | ||
1062 | if (r != 0) { | 1341 | if (r != 0) { |
1063 | int i; | 1342 | int i; |
1064 | 1343 | ||
1065 | printk(KERN_ERR "unable to request IRQ %d for DMA (error %d)\n", | 1344 | printk(KERN_ERR "unable to request IRQ for LCD DMA " |
1066 | dma_irq[ch], r); | 1345 | "(error %d)\n", r); |
1067 | for (i = 0; i < ch; i++) | 1346 | for (i = 0; i < dma_chan_count; i++) |
1068 | free_irq(dma_irq[i], (void *) (i + 1)); | 1347 | free_irq(omap1_dma_irq[i], (void *) (i + 1)); |
1069 | return r; | 1348 | return r; |
1070 | } | 1349 | } |
1071 | } | 1350 | } |
1072 | r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, "LCD DMA", NULL); | ||
1073 | if (r != 0) { | ||
1074 | int i; | ||
1075 | 1351 | ||
1076 | printk(KERN_ERR "unable to request IRQ for LCD DMA (error %d)\n", r); | ||
1077 | for (i = 0; i < dma_chan_count; i++) | ||
1078 | free_irq(dma_irq[i], (void *) (i + 1)); | ||
1079 | return r; | ||
1080 | } | ||
1081 | return 0; | 1352 | return 0; |
1082 | } | 1353 | } |
1083 | 1354 | ||
1084 | arch_initcall(omap_init_dma); | 1355 | arch_initcall(omap_init_dma); |
1085 | 1356 | ||
1086 | |||
1087 | EXPORT_SYMBOL(omap_get_dma_src_pos); | 1357 | EXPORT_SYMBOL(omap_get_dma_src_pos); |
1088 | EXPORT_SYMBOL(omap_get_dma_dst_pos); | 1358 | EXPORT_SYMBOL(omap_get_dma_dst_pos); |
1089 | EXPORT_SYMBOL(omap_get_dma_src_addr_counter); | 1359 | EXPORT_SYMBOL(omap_get_dma_src_addr_counter); |
@@ -1109,6 +1379,8 @@ EXPORT_SYMBOL(omap_set_dma_dest_index); | |||
1109 | EXPORT_SYMBOL(omap_set_dma_dest_data_pack); | 1379 | EXPORT_SYMBOL(omap_set_dma_dest_data_pack); |
1110 | EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); | 1380 | EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); |
1111 | 1381 | ||
1382 | EXPORT_SYMBOL(omap_set_dma_params); | ||
1383 | |||
1112 | EXPORT_SYMBOL(omap_dma_link_lch); | 1384 | EXPORT_SYMBOL(omap_dma_link_lch); |
1113 | EXPORT_SYMBOL(omap_dma_unlink_lch); | 1385 | EXPORT_SYMBOL(omap_dma_unlink_lch); |
1114 | 1386 | ||
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 55059a24ad41..76f721d85137 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -140,7 +140,7 @@ static struct gpio_bank gpio_bank_1610[5] = { | |||
140 | }; | 140 | }; |
141 | #endif | 141 | #endif |
142 | 142 | ||
143 | #ifdef CONFIG_ARCH_OMAP1510 | 143 | #ifdef CONFIG_ARCH_OMAP15XX |
144 | static struct gpio_bank gpio_bank_1510[2] = { | 144 | static struct gpio_bank gpio_bank_1510[2] = { |
145 | { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO }, | 145 | { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO }, |
146 | { OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1510 } | 146 | { OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1510 } |
@@ -173,7 +173,7 @@ static int gpio_bank_count; | |||
173 | 173 | ||
174 | static inline struct gpio_bank *get_gpio_bank(int gpio) | 174 | static inline struct gpio_bank *get_gpio_bank(int gpio) |
175 | { | 175 | { |
176 | #ifdef CONFIG_ARCH_OMAP1510 | 176 | #ifdef CONFIG_ARCH_OMAP15XX |
177 | if (cpu_is_omap1510()) { | 177 | if (cpu_is_omap1510()) { |
178 | if (OMAP_GPIO_IS_MPUIO(gpio)) | 178 | if (OMAP_GPIO_IS_MPUIO(gpio)) |
179 | return &gpio_bank[0]; | 179 | return &gpio_bank[0]; |
@@ -222,7 +222,7 @@ static inline int gpio_valid(int gpio) | |||
222 | return -1; | 222 | return -1; |
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | #ifdef CONFIG_ARCH_OMAP1510 | 225 | #ifdef CONFIG_ARCH_OMAP15XX |
226 | if (cpu_is_omap1510() && gpio < 16) | 226 | if (cpu_is_omap1510() && gpio < 16) |
227 | return 0; | 227 | return 0; |
228 | #endif | 228 | #endif |
@@ -654,7 +654,7 @@ int omap_request_gpio(int gpio) | |||
654 | /* Set trigger to none. You need to enable the trigger after request_irq */ | 654 | /* Set trigger to none. You need to enable the trigger after request_irq */ |
655 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); | 655 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); |
656 | 656 | ||
657 | #ifdef CONFIG_ARCH_OMAP1510 | 657 | #ifdef CONFIG_ARCH_OMAP15XX |
658 | if (bank->method == METHOD_GPIO_1510) { | 658 | if (bank->method == METHOD_GPIO_1510) { |
659 | void __iomem *reg; | 659 | void __iomem *reg; |
660 | 660 | ||
@@ -739,7 +739,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, | |||
739 | bank = (struct gpio_bank *) desc->data; | 739 | bank = (struct gpio_bank *) desc->data; |
740 | if (bank->method == METHOD_MPUIO) | 740 | if (bank->method == METHOD_MPUIO) |
741 | isr_reg = bank->base + OMAP_MPUIO_GPIO_INT; | 741 | isr_reg = bank->base + OMAP_MPUIO_GPIO_INT; |
742 | #ifdef CONFIG_ARCH_OMAP1510 | 742 | #ifdef CONFIG_ARCH_OMAP15XX |
743 | if (bank->method == METHOD_GPIO_1510) | 743 | if (bank->method == METHOD_GPIO_1510) |
744 | isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS; | 744 | isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS; |
745 | #endif | 745 | #endif |
@@ -774,7 +774,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, | |||
774 | d = irq_desc + gpio_irq; | 774 | d = irq_desc + gpio_irq; |
775 | desc_handle_irq(gpio_irq, d, regs); | 775 | desc_handle_irq(gpio_irq, d, regs); |
776 | } | 776 | } |
777 | } | 777 | } |
778 | } | 778 | } |
779 | 779 | ||
780 | static void gpio_ack_irq(unsigned int irq) | 780 | static void gpio_ack_irq(unsigned int irq) |
@@ -837,8 +837,9 @@ static struct irqchip mpuio_irq_chip = { | |||
837 | .unmask = mpuio_unmask_irq | 837 | .unmask = mpuio_unmask_irq |
838 | }; | 838 | }; |
839 | 839 | ||
840 | static int initialized = 0; | 840 | static int initialized; |
841 | static struct clk * gpio_ck = NULL; | 841 | static struct clk * gpio_ick; |
842 | static struct clk * gpio_fck; | ||
842 | 843 | ||
843 | static int __init _omap_gpio_init(void) | 844 | static int __init _omap_gpio_init(void) |
844 | { | 845 | { |
@@ -848,14 +849,26 @@ static int __init _omap_gpio_init(void) | |||
848 | initialized = 1; | 849 | initialized = 1; |
849 | 850 | ||
850 | if (cpu_is_omap1510()) { | 851 | if (cpu_is_omap1510()) { |
851 | gpio_ck = clk_get(NULL, "arm_gpio_ck"); | 852 | gpio_ick = clk_get(NULL, "arm_gpio_ck"); |
852 | if (IS_ERR(gpio_ck)) | 853 | if (IS_ERR(gpio_ick)) |
853 | printk("Could not get arm_gpio_ck\n"); | 854 | printk("Could not get arm_gpio_ck\n"); |
854 | else | 855 | else |
855 | clk_use(gpio_ck); | 856 | clk_use(gpio_ick); |
857 | } | ||
858 | if (cpu_is_omap24xx()) { | ||
859 | gpio_ick = clk_get(NULL, "gpios_ick"); | ||
860 | if (IS_ERR(gpio_ick)) | ||
861 | printk("Could not get gpios_ick\n"); | ||
862 | else | ||
863 | clk_use(gpio_ick); | ||
864 | gpio_fck = clk_get(NULL, "gpios_fck"); | ||
865 | if (IS_ERR(gpio_ick)) | ||
866 | printk("Could not get gpios_fck\n"); | ||
867 | else | ||
868 | clk_use(gpio_fck); | ||
856 | } | 869 | } |
857 | 870 | ||
858 | #ifdef CONFIG_ARCH_OMAP1510 | 871 | #ifdef CONFIG_ARCH_OMAP15XX |
859 | if (cpu_is_omap1510()) { | 872 | if (cpu_is_omap1510()) { |
860 | printk(KERN_INFO "OMAP1510 GPIO hardware\n"); | 873 | printk(KERN_INFO "OMAP1510 GPIO hardware\n"); |
861 | gpio_bank_count = 2; | 874 | gpio_bank_count = 2; |
@@ -901,7 +914,7 @@ static int __init _omap_gpio_init(void) | |||
901 | if (bank->method == METHOD_MPUIO) { | 914 | if (bank->method == METHOD_MPUIO) { |
902 | omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT); | 915 | omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT); |
903 | } | 916 | } |
904 | #ifdef CONFIG_ARCH_OMAP1510 | 917 | #ifdef CONFIG_ARCH_OMAP15XX |
905 | if (bank->method == METHOD_GPIO_1510) { | 918 | if (bank->method == METHOD_GPIO_1510) { |
906 | __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK); | 919 | __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK); |
907 | __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS); | 920 | __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS); |
@@ -1038,6 +1051,7 @@ static struct sys_device omap_gpio_device = { | |||
1038 | 1051 | ||
1039 | /* | 1052 | /* |
1040 | * This may get called early from board specific init | 1053 | * This may get called early from board specific init |
1054 | * for boards that have interrupts routed via FPGA. | ||
1041 | */ | 1055 | */ |
1042 | int omap_gpio_init(void) | 1056 | int omap_gpio_init(void) |
1043 | { | 1057 | { |
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 9c9b7df3faf6..ea9475c86656 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -491,17 +491,20 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
491 | omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, | 491 | omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, |
492 | OMAP_DMA_DATA_TYPE_S16, | 492 | OMAP_DMA_DATA_TYPE_S16, |
493 | length >> 1, 1, | 493 | length >> 1, 1, |
494 | OMAP_DMA_SYNC_ELEMENT); | 494 | OMAP_DMA_SYNC_ELEMENT, |
495 | 0, 0); | ||
495 | 496 | ||
496 | omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, | 497 | omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, |
497 | OMAP_DMA_PORT_TIPB, | 498 | OMAP_DMA_PORT_TIPB, |
498 | OMAP_DMA_AMODE_CONSTANT, | 499 | OMAP_DMA_AMODE_CONSTANT, |
499 | mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1); | 500 | mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1, |
501 | 0, 0); | ||
500 | 502 | ||
501 | omap_set_dma_src_params(mcbsp[id].dma_tx_lch, | 503 | omap_set_dma_src_params(mcbsp[id].dma_tx_lch, |
502 | OMAP_DMA_PORT_EMIFF, | 504 | OMAP_DMA_PORT_EMIFF, |
503 | OMAP_DMA_AMODE_POST_INC, | 505 | OMAP_DMA_AMODE_POST_INC, |
504 | buffer); | 506 | buffer, |
507 | 0, 0); | ||
505 | 508 | ||
506 | omap_start_dma(mcbsp[id].dma_tx_lch); | 509 | omap_start_dma(mcbsp[id].dma_tx_lch); |
507 | wait_for_completion(&(mcbsp[id].tx_dma_completion)); | 510 | wait_for_completion(&(mcbsp[id].tx_dma_completion)); |
@@ -531,17 +534,20 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng | |||
531 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, | 534 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, |
532 | OMAP_DMA_DATA_TYPE_S16, | 535 | OMAP_DMA_DATA_TYPE_S16, |
533 | length >> 1, 1, | 536 | length >> 1, 1, |
534 | OMAP_DMA_SYNC_ELEMENT); | 537 | OMAP_DMA_SYNC_ELEMENT, |
538 | 0, 0); | ||
535 | 539 | ||
536 | omap_set_dma_src_params(mcbsp[id].dma_rx_lch, | 540 | omap_set_dma_src_params(mcbsp[id].dma_rx_lch, |
537 | OMAP_DMA_PORT_TIPB, | 541 | OMAP_DMA_PORT_TIPB, |
538 | OMAP_DMA_AMODE_CONSTANT, | 542 | OMAP_DMA_AMODE_CONSTANT, |
539 | mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1); | 543 | mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1, |
544 | 0, 0); | ||
540 | 545 | ||
541 | omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, | 546 | omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, |
542 | OMAP_DMA_PORT_EMIFF, | 547 | OMAP_DMA_PORT_EMIFF, |
543 | OMAP_DMA_AMODE_POST_INC, | 548 | OMAP_DMA_AMODE_POST_INC, |
544 | buffer); | 549 | buffer, |
550 | 0, 0); | ||
545 | 551 | ||
546 | omap_start_dma(mcbsp[id].dma_rx_lch); | 552 | omap_start_dma(mcbsp[id].dma_rx_lch); |
547 | wait_for_completion(&(mcbsp[id].rx_dma_completion)); | 553 | wait_for_completion(&(mcbsp[id].rx_dma_completion)); |
@@ -643,7 +649,7 @@ static const struct omap_mcbsp_info mcbsp_730[] = { | |||
643 | }; | 649 | }; |
644 | #endif | 650 | #endif |
645 | 651 | ||
646 | #ifdef CONFIG_ARCH_OMAP1510 | 652 | #ifdef CONFIG_ARCH_OMAP15XX |
647 | static const struct omap_mcbsp_info mcbsp_1510[] = { | 653 | static const struct omap_mcbsp_info mcbsp_1510[] = { |
648 | [0] = { .virt_base = OMAP1510_MCBSP1_BASE, | 654 | [0] = { .virt_base = OMAP1510_MCBSP1_BASE, |
649 | .dma_rx_sync = OMAP_DMA_MCBSP1_RX, | 655 | .dma_rx_sync = OMAP_DMA_MCBSP1_RX, |
@@ -712,7 +718,7 @@ static int __init omap_mcbsp_init(void) | |||
712 | mcbsp_count = ARRAY_SIZE(mcbsp_730); | 718 | mcbsp_count = ARRAY_SIZE(mcbsp_730); |
713 | } | 719 | } |
714 | #endif | 720 | #endif |
715 | #ifdef CONFIG_ARCH_OMAP1510 | 721 | #ifdef CONFIG_ARCH_OMAP15XX |
716 | if (cpu_is_omap1510()) { | 722 | if (cpu_is_omap1510()) { |
717 | mcbsp_info = mcbsp_1510; | 723 | mcbsp_info = mcbsp_1510; |
718 | mcbsp_count = ARRAY_SIZE(mcbsp_1510); | 724 | mcbsp_count = ARRAY_SIZE(mcbsp_1510); |
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c index 64482040f89e..8c1c016aa689 100644 --- a/arch/arm/plat-omap/mux.c +++ b/arch/arm/plat-omap/mux.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h | 4 | * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h |
5 | * | 5 | * |
6 | * Copyright (C) 2003 Nokia Corporation | 6 | * Copyright (C) 2003 - 2005 Nokia Corporation |
7 | * | 7 | * |
8 | * Written by Tony Lindgren <tony.lindgren@nokia.com> | 8 | * Written by Tony Lindgren <tony.lindgren@nokia.com> |
9 | * | 9 | * |
@@ -25,38 +25,74 @@ | |||
25 | #include <linux/config.h> | 25 | #include <linux/config.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/kernel.h> | ||
28 | #include <asm/system.h> | 29 | #include <asm/system.h> |
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
30 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
31 | |||
32 | #define __MUX_C__ | ||
33 | #include <asm/arch/mux.h> | 32 | #include <asm/arch/mux.h> |
34 | 33 | ||
35 | #ifdef CONFIG_OMAP_MUX | 34 | #ifdef CONFIG_OMAP_MUX |
36 | 35 | ||
36 | #define OMAP24XX_L4_BASE 0x48000000 | ||
37 | #define OMAP24XX_PULL_ENA (1 << 3) | ||
38 | #define OMAP24XX_PULL_UP (1 << 4) | ||
39 | |||
40 | static struct pin_config * pin_table; | ||
41 | static unsigned long pin_table_sz; | ||
42 | |||
43 | extern struct pin_config * omap730_pins; | ||
44 | extern struct pin_config * omap1xxx_pins; | ||
45 | extern struct pin_config * omap24xx_pins; | ||
46 | |||
47 | int __init omap_mux_register(struct pin_config * pins, unsigned long size) | ||
48 | { | ||
49 | pin_table = pins; | ||
50 | pin_table_sz = size; | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
37 | /* | 55 | /* |
38 | * Sets the Omap MUX and PULL_DWN registers based on the table | 56 | * Sets the Omap MUX and PULL_DWN registers based on the table |
39 | */ | 57 | */ |
40 | int __init_or_module | 58 | int __init_or_module omap_cfg_reg(const unsigned long index) |
41 | omap_cfg_reg(const reg_cfg_t reg_cfg) | ||
42 | { | 59 | { |
43 | static DEFINE_SPINLOCK(mux_spin_lock); | 60 | static DEFINE_SPINLOCK(mux_spin_lock); |
44 | 61 | ||
45 | unsigned long flags; | 62 | unsigned long flags; |
46 | reg_cfg_set *cfg; | 63 | struct pin_config *cfg; |
47 | unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0, | 64 | unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0, |
48 | pull_orig = 0, pull = 0; | 65 | pull_orig = 0, pull = 0; |
49 | unsigned int mask, warn = 0; | 66 | unsigned int mask, warn = 0; |
50 | 67 | ||
51 | if (cpu_is_omap7xx()) | 68 | if (!pin_table) |
52 | return 0; | 69 | BUG(); |
53 | 70 | ||
54 | if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) { | 71 | if (index >= pin_table_sz) { |
55 | printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg); | 72 | printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n", |
56 | return -EINVAL; | 73 | index, pin_table_sz); |
74 | dump_stack(); | ||
75 | return -ENODEV; | ||
57 | } | 76 | } |
58 | 77 | ||
59 | cfg = (reg_cfg_set *)®_cfg_table[reg_cfg]; | 78 | cfg = (struct pin_config *)&pin_table[index]; |
79 | if (cpu_is_omap24xx()) { | ||
80 | u8 reg = 0; | ||
81 | |||
82 | reg |= cfg->mask & 0x7; | ||
83 | if (cfg->pull_val) | ||
84 | reg |= OMAP24XX_PULL_ENA; | ||
85 | if(cfg->pu_pd_val) | ||
86 | reg |= OMAP24XX_PULL_UP; | ||
87 | #ifdef CONFIG_OMAP_MUX_DEBUG | ||
88 | printk("Muxing %s (0x%08x): 0x%02x -> 0x%02x\n", | ||
89 | cfg->name, OMAP24XX_L4_BASE + cfg->mux_reg, | ||
90 | omap_readb(OMAP24XX_L4_BASE + cfg->mux_reg), reg); | ||
91 | #endif | ||
92 | omap_writeb(reg, OMAP24XX_L4_BASE + cfg->mux_reg); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
60 | 96 | ||
61 | /* Check the mux register in question */ | 97 | /* Check the mux register in question */ |
62 | if (cfg->mux_reg) { | 98 | if (cfg->mux_reg) { |
@@ -157,7 +193,8 @@ omap_cfg_reg(const reg_cfg_t reg_cfg) | |||
157 | return 0; | 193 | return 0; |
158 | #endif | 194 | #endif |
159 | } | 195 | } |
160 | |||
161 | EXPORT_SYMBOL(omap_cfg_reg); | 196 | EXPORT_SYMBOL(omap_cfg_reg); |
162 | 197 | #else | |
198 | #define omap_mux_init() do {} while(0) | ||
199 | #define omap_cfg_reg(x) do {} while(0) | ||
163 | #endif /* CONFIG_OMAP_MUX */ | 200 | #endif /* CONFIG_OMAP_MUX */ |
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c index 1fb16f9edfd5..2ede2ee8cae4 100644 --- a/arch/arm/plat-omap/ocpi.c +++ b/arch/arm/plat-omap/ocpi.c | |||
@@ -25,7 +25,6 @@ | |||
25 | 25 | ||
26 | #include <linux/config.h> | 26 | #include <linux/config.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/version.h> | ||
29 | #include <linux/types.h> | 28 | #include <linux/types.h> |
30 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
31 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c index e15c6c1ddec9..966cca031ca7 100644 --- a/arch/arm/plat-omap/pm.c +++ b/arch/arm/plat-omap/pm.c | |||
@@ -54,11 +54,12 @@ | |||
54 | #include <asm/arch/tps65010.h> | 54 | #include <asm/arch/tps65010.h> |
55 | #include <asm/arch/dsp_common.h> | 55 | #include <asm/arch/dsp_common.h> |
56 | 56 | ||
57 | #include "clock.h" | 57 | #include <asm/arch/clock.h> |
58 | #include "sram.h" | 58 | #include <asm/arch/sram.h> |
59 | 59 | ||
60 | static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; | 60 | static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; |
61 | static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; | 61 | static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; |
62 | static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE]; | ||
62 | static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; | 63 | static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; |
63 | static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; | 64 | static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; |
64 | 65 | ||
@@ -120,8 +121,8 @@ void omap_pm_idle(void) | |||
120 | */ | 121 | */ |
121 | static void omap_pm_wakeup_setup(void) | 122 | static void omap_pm_wakeup_setup(void) |
122 | { | 123 | { |
123 | u32 level1_wake = OMAP_IRQ_BIT(INT_IH2_IRQ); | 124 | u32 level1_wake = 0; |
124 | u32 level2_wake = OMAP_IRQ_BIT(INT_UART2) | OMAP_IRQ_BIT(INT_KEYBOARD); | 125 | u32 level2_wake = OMAP_IRQ_BIT(INT_UART2); |
125 | 126 | ||
126 | /* | 127 | /* |
127 | * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, | 128 | * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, |
@@ -129,19 +130,29 @@ static void omap_pm_wakeup_setup(void) | |||
129 | * drivers must still separately call omap_set_gpio_wakeup() to | 130 | * drivers must still separately call omap_set_gpio_wakeup() to |
130 | * wake up to a GPIO interrupt. | 131 | * wake up to a GPIO interrupt. |
131 | */ | 132 | */ |
132 | if (cpu_is_omap1510() || cpu_is_omap16xx()) | 133 | if (cpu_is_omap730()) |
133 | level1_wake |= OMAP_IRQ_BIT(INT_GPIO_BANK1); | 134 | level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) | |
134 | else if (cpu_is_omap730()) | 135 | OMAP_IRQ_BIT(INT_730_IH2_IRQ); |
135 | level1_wake |= OMAP_IRQ_BIT(INT_730_GPIO_BANK1); | 136 | else if (cpu_is_omap1510()) |
137 | level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | | ||
138 | OMAP_IRQ_BIT(INT_1510_IH2_IRQ); | ||
139 | else if (cpu_is_omap16xx()) | ||
140 | level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | | ||
141 | OMAP_IRQ_BIT(INT_1610_IH2_IRQ); | ||
136 | 142 | ||
137 | omap_writel(~level1_wake, OMAP_IH1_MIR); | 143 | omap_writel(~level1_wake, OMAP_IH1_MIR); |
138 | 144 | ||
139 | if (cpu_is_omap1510()) | 145 | if (cpu_is_omap730()) { |
146 | omap_writel(~level2_wake, OMAP_IH2_0_MIR); | ||
147 | omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), OMAP_IH2_1_MIR); | ||
148 | } else if (cpu_is_omap1510()) { | ||
149 | level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); | ||
140 | omap_writel(~level2_wake, OMAP_IH2_MIR); | 150 | omap_writel(~level2_wake, OMAP_IH2_MIR); |
141 | 151 | } else if (cpu_is_omap16xx()) { | |
142 | /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */ | 152 | level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); |
143 | if (cpu_is_omap16xx()) { | ||
144 | omap_writel(~level2_wake, OMAP_IH2_0_MIR); | 153 | omap_writel(~level2_wake, OMAP_IH2_0_MIR); |
154 | |||
155 | /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */ | ||
145 | omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR); | 156 | omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR); |
146 | omap_writel(~0x0, OMAP_IH2_2_MIR); | 157 | omap_writel(~0x0, OMAP_IH2_2_MIR); |
147 | omap_writel(~0x0, OMAP_IH2_3_MIR); | 158 | omap_writel(~0x0, OMAP_IH2_3_MIR); |
@@ -185,7 +196,17 @@ void omap_pm_suspend(void) | |||
185 | * Save interrupt, MPUI, ARM and UPLD control registers. | 196 | * Save interrupt, MPUI, ARM and UPLD control registers. |
186 | */ | 197 | */ |
187 | 198 | ||
188 | if (cpu_is_omap1510()) { | 199 | if (cpu_is_omap730()) { |
200 | MPUI730_SAVE(OMAP_IH1_MIR); | ||
201 | MPUI730_SAVE(OMAP_IH2_0_MIR); | ||
202 | MPUI730_SAVE(OMAP_IH2_1_MIR); | ||
203 | MPUI730_SAVE(MPUI_CTRL); | ||
204 | MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
205 | MPUI730_SAVE(MPUI_DSP_API_CONFIG); | ||
206 | MPUI730_SAVE(EMIFS_CONFIG); | ||
207 | MPUI730_SAVE(EMIFF_SDRAM_CONFIG); | ||
208 | |||
209 | } else if (cpu_is_omap1510()) { | ||
189 | MPUI1510_SAVE(OMAP_IH1_MIR); | 210 | MPUI1510_SAVE(OMAP_IH1_MIR); |
190 | MPUI1510_SAVE(OMAP_IH2_MIR); | 211 | MPUI1510_SAVE(OMAP_IH2_MIR); |
191 | MPUI1510_SAVE(MPUI_CTRL); | 212 | MPUI1510_SAVE(MPUI_CTRL); |
@@ -280,7 +301,13 @@ void omap_pm_suspend(void) | |||
280 | ULPD_RESTORE(ULPD_CLOCK_CTRL); | 301 | ULPD_RESTORE(ULPD_CLOCK_CTRL); |
281 | ULPD_RESTORE(ULPD_STATUS_REQ); | 302 | ULPD_RESTORE(ULPD_STATUS_REQ); |
282 | 303 | ||
283 | if (cpu_is_omap1510()) { | 304 | if (cpu_is_omap730()) { |
305 | MPUI730_RESTORE(EMIFS_CONFIG); | ||
306 | MPUI730_RESTORE(EMIFF_SDRAM_CONFIG); | ||
307 | MPUI730_RESTORE(OMAP_IH1_MIR); | ||
308 | MPUI730_RESTORE(OMAP_IH2_0_MIR); | ||
309 | MPUI730_RESTORE(OMAP_IH2_1_MIR); | ||
310 | } else if (cpu_is_omap1510()) { | ||
284 | MPUI1510_RESTORE(MPUI_CTRL); | 311 | MPUI1510_RESTORE(MPUI_CTRL); |
285 | MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG); | 312 | MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG); |
286 | MPUI1510_RESTORE(MPUI_DSP_API_CONFIG); | 313 | MPUI1510_RESTORE(MPUI_DSP_API_CONFIG); |
@@ -355,7 +382,14 @@ static int omap_pm_read_proc( | |||
355 | ULPD_SAVE(ULPD_DPLL_CTRL); | 382 | ULPD_SAVE(ULPD_DPLL_CTRL); |
356 | ULPD_SAVE(ULPD_POWER_CTRL); | 383 | ULPD_SAVE(ULPD_POWER_CTRL); |
357 | 384 | ||
358 | if (cpu_is_omap1510()) { | 385 | if (cpu_is_omap730()) { |
386 | MPUI730_SAVE(MPUI_CTRL); | ||
387 | MPUI730_SAVE(MPUI_DSP_STATUS); | ||
388 | MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
389 | MPUI730_SAVE(MPUI_DSP_API_CONFIG); | ||
390 | MPUI730_SAVE(EMIFF_SDRAM_CONFIG); | ||
391 | MPUI730_SAVE(EMIFS_CONFIG); | ||
392 | } else if (cpu_is_omap1510()) { | ||
359 | MPUI1510_SAVE(MPUI_CTRL); | 393 | MPUI1510_SAVE(MPUI_CTRL); |
360 | MPUI1510_SAVE(MPUI_DSP_STATUS); | 394 | MPUI1510_SAVE(MPUI_DSP_STATUS); |
361 | MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); | 395 | MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); |
@@ -404,7 +438,21 @@ static int omap_pm_read_proc( | |||
404 | ULPD_SHOW(ULPD_STATUS_REQ), | 438 | ULPD_SHOW(ULPD_STATUS_REQ), |
405 | ULPD_SHOW(ULPD_POWER_CTRL)); | 439 | ULPD_SHOW(ULPD_POWER_CTRL)); |
406 | 440 | ||
407 | if (cpu_is_omap1510()) { | 441 | if (cpu_is_omap730()) { |
442 | my_buffer_offset += sprintf(my_base + my_buffer_offset, | ||
443 | "MPUI730_CTRL_REG 0x%-8x \n" | ||
444 | "MPUI730_DSP_STATUS_REG: 0x%-8x \n" | ||
445 | "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n" | ||
446 | "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n" | ||
447 | "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n" | ||
448 | "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n", | ||
449 | MPUI730_SHOW(MPUI_CTRL), | ||
450 | MPUI730_SHOW(MPUI_DSP_STATUS), | ||
451 | MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG), | ||
452 | MPUI730_SHOW(MPUI_DSP_API_CONFIG), | ||
453 | MPUI730_SHOW(EMIFF_SDRAM_CONFIG), | ||
454 | MPUI730_SHOW(EMIFS_CONFIG)); | ||
455 | } else if (cpu_is_omap1510()) { | ||
408 | my_buffer_offset += sprintf(my_base + my_buffer_offset, | 456 | my_buffer_offset += sprintf(my_base + my_buffer_offset, |
409 | "MPUI1510_CTRL_REG 0x%-8x \n" | 457 | "MPUI1510_CTRL_REG 0x%-8x \n" |
410 | "MPUI1510_DSP_STATUS_REG: 0x%-8x \n" | 458 | "MPUI1510_DSP_STATUS_REG: 0x%-8x \n" |
@@ -553,7 +601,12 @@ static int __init omap_pm_init(void) | |||
553 | * These routines need to be in SRAM as that's the only | 601 | * These routines need to be in SRAM as that's the only |
554 | * memory the MPU can see when it wakes up. | 602 | * memory the MPU can see when it wakes up. |
555 | */ | 603 | */ |
556 | if (cpu_is_omap1510()) { | 604 | if (cpu_is_omap730()) { |
605 | omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend, | ||
606 | omap730_idle_loop_suspend_sz); | ||
607 | omap_sram_suspend = omap_sram_push(omap730_cpu_suspend, | ||
608 | omap730_cpu_suspend_sz); | ||
609 | } else if (cpu_is_omap1510()) { | ||
557 | omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend, | 610 | omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend, |
558 | omap1510_idle_loop_suspend_sz); | 611 | omap1510_idle_loop_suspend_sz); |
559 | omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend, | 612 | omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend, |
@@ -572,7 +625,11 @@ static int __init omap_pm_init(void) | |||
572 | 625 | ||
573 | pm_idle = omap_pm_idle; | 626 | pm_idle = omap_pm_idle; |
574 | 627 | ||
575 | setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); | 628 | if (cpu_is_omap730()) |
629 | setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq); | ||
630 | else if (cpu_is_omap16xx()) | ||
631 | setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); | ||
632 | |||
576 | #if 0 | 633 | #if 0 |
577 | /* --- BEGIN BOARD-DEPENDENT CODE --- */ | 634 | /* --- BEGIN BOARD-DEPENDENT CODE --- */ |
578 | /* Sleepx mask direction */ | 635 | /* Sleepx mask direction */ |
@@ -591,7 +648,9 @@ static int __init omap_pm_init(void) | |||
591 | omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL); | 648 | omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL); |
592 | 649 | ||
593 | /* Configure IDLECT3 */ | 650 | /* Configure IDLECT3 */ |
594 | if (cpu_is_omap16xx()) | 651 | if (cpu_is_omap730()) |
652 | omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3); | ||
653 | else if (cpu_is_omap16xx()) | ||
595 | omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); | 654 | omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); |
596 | 655 | ||
597 | pm_set_ops(&omap_pm_ops); | 656 | pm_set_ops(&omap_pm_ops); |
@@ -600,8 +659,10 @@ static int __init omap_pm_init(void) | |||
600 | omap_pm_init_proc(); | 659 | omap_pm_init_proc(); |
601 | #endif | 660 | #endif |
602 | 661 | ||
603 | /* configure LOW_PWR pin */ | 662 | if (cpu_is_omap16xx()) { |
604 | omap_cfg_reg(T20_1610_LOW_PWR); | 663 | /* configure LOW_PWR pin */ |
664 | omap_cfg_reg(T20_1610_LOW_PWR); | ||
665 | } | ||
605 | 666 | ||
606 | return 0; | 667 | return 0; |
607 | } | 668 | } |
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/plat-omap/sleep.S index 9f745836f6aa..4cd7d292f854 100644 --- a/arch/arm/plat-omap/sleep.S +++ b/arch/arm/plat-omap/sleep.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/plat-omap/sleep.S | 2 | * linux/arch/arm/plat-omap/sleep.S |
3 | * | 3 | * |
4 | * Low-level OMAP1510/1610 sleep/wakeUp support | 4 | * Low-level OMAP730/1510/1610 sleep/wakeUp support |
5 | * | 5 | * |
6 | * Initial SA1110 code: | 6 | * Initial SA1110 code: |
7 | * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> | 7 | * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> |
@@ -52,7 +52,57 @@ | |||
52 | * processor specific functions here. | 52 | * processor specific functions here. |
53 | */ | 53 | */ |
54 | 54 | ||
55 | #ifdef CONFIG_ARCH_OMAP1510 | 55 | #if defined(CONFIG_ARCH_OMAP730) |
56 | ENTRY(omap730_idle_loop_suspend) | ||
57 | |||
58 | stmfd sp!, {r0 - r12, lr} @ save registers on stack | ||
59 | |||
60 | @ load base address of ARM_IDLECT1 and ARM_IDLECT2 | ||
61 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 | ||
62 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 | ||
63 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 | ||
64 | |||
65 | @ turn off clock domains | ||
66 | @ get ARM_IDLECT2 into r2 | ||
67 | ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | ||
68 | mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff | ||
69 | orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00 | ||
70 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | ||
71 | |||
72 | @ request ARM idle | ||
73 | @ get ARM_IDLECT1 into r1 | ||
74 | ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | ||
75 | orr r3, r1, #OMAP730_IDLE_LOOP_REQUEST & 0xffff | ||
76 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | ||
77 | |||
78 | mov r5, #IDLE_WAIT_CYCLES & 0xff | ||
79 | orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 | ||
80 | l_730: subs r5, r5, #1 | ||
81 | bne l_730 | ||
82 | /* | ||
83 | * Let's wait for the next clock tick to wake us up. | ||
84 | */ | ||
85 | mov r0, #0 | ||
86 | mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt | ||
87 | /* | ||
88 | * omap730_idle_loop_suspend()'s resume point. | ||
89 | * | ||
90 | * It will just start executing here, so we'll restore stuff from the | ||
91 | * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. | ||
92 | */ | ||
93 | |||
94 | @ restore ARM_IDLECT1 and ARM_IDLECT2 and return | ||
95 | @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2 | ||
96 | strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | ||
97 | strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | ||
98 | |||
99 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return | ||
100 | |||
101 | ENTRY(omap730_idle_loop_suspend_sz) | ||
102 | .word . - omap730_idle_loop_suspend | ||
103 | #endif /* CONFIG_ARCH_OMAP730 */ | ||
104 | |||
105 | #ifdef CONFIG_ARCH_OMAP15XX | ||
56 | ENTRY(omap1510_idle_loop_suspend) | 106 | ENTRY(omap1510_idle_loop_suspend) |
57 | 107 | ||
58 | stmfd sp!, {r0 - r12, lr} @ save registers on stack | 108 | stmfd sp!, {r0 - r12, lr} @ save registers on stack |
@@ -100,7 +150,7 @@ l_1510: subs r5, r5, #1 | |||
100 | 150 | ||
101 | ENTRY(omap1510_idle_loop_suspend_sz) | 151 | ENTRY(omap1510_idle_loop_suspend_sz) |
102 | .word . - omap1510_idle_loop_suspend | 152 | .word . - omap1510_idle_loop_suspend |
103 | #endif /* CONFIG_ARCH_OMAP1510 */ | 153 | #endif /* CONFIG_ARCH_OMAP15XX */ |
104 | 154 | ||
105 | #if defined(CONFIG_ARCH_OMAP16XX) | 155 | #if defined(CONFIG_ARCH_OMAP16XX) |
106 | ENTRY(omap1610_idle_loop_suspend) | 156 | ENTRY(omap1610_idle_loop_suspend) |
@@ -169,7 +219,86 @@ ENTRY(omap1610_idle_loop_suspend_sz) | |||
169 | * | 219 | * |
170 | */ | 220 | */ |
171 | 221 | ||
172 | #ifdef CONFIG_ARCH_OMAP1510 | 222 | #if defined(CONFIG_ARCH_OMAP730) |
223 | ENTRY(omap730_cpu_suspend) | ||
224 | |||
225 | @ save registers on stack | ||
226 | stmfd sp!, {r0 - r12, lr} | ||
227 | |||
228 | @ Drain write cache | ||
229 | mov r4, #0 | ||
230 | mcr p15, 0, r0, c7, c10, 4 | ||
231 | nop | ||
232 | |||
233 | @ load base address of Traffic Controller | ||
234 | mov r6, #TCMIF_ASM_BASE & 0xff000000 | ||
235 | orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 | ||
236 | orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 | ||
237 | |||
238 | @ prepare to put SDRAM into self-refresh manually | ||
239 | ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | ||
240 | orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 | ||
241 | orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff | ||
242 | str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | ||
243 | |||
244 | @ prepare to put EMIFS to Sleep | ||
245 | ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | ||
246 | orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff | ||
247 | str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | ||
248 | |||
249 | @ load base address of ARM_IDLECT1 and ARM_IDLECT2 | ||
250 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 | ||
251 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 | ||
252 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 | ||
253 | |||
254 | @ turn off clock domains | ||
255 | @ do not disable PERCK (0x04) | ||
256 | mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff | ||
257 | orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00 | ||
258 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | ||
259 | |||
260 | @ request ARM idle | ||
261 | mov r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff | ||
262 | orr r3, r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff00 | ||
263 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | ||
264 | |||
265 | @ disable instruction cache | ||
266 | mrc p15, 0, r9, c1, c0, 0 | ||
267 | bic r2, r9, #0x1000 | ||
268 | mcr p15, 0, r2, c1, c0, 0 | ||
269 | nop | ||
270 | |||
271 | /* | ||
272 | * Let's wait for the next wake up event to wake us up. r0 can't be | ||
273 | * used here because r0 holds ARM_IDLECT1 | ||
274 | */ | ||
275 | mov r2, #0 | ||
276 | mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt | ||
277 | /* | ||
278 | * omap730_cpu_suspend()'s resume point. | ||
279 | * | ||
280 | * It will just start executing here, so we'll restore stuff from the | ||
281 | * stack. | ||
282 | */ | ||
283 | @ re-enable Icache | ||
284 | mcr p15, 0, r9, c1, c0, 0 | ||
285 | |||
286 | @ reset the ARM_IDLECT1 and ARM_IDLECT2. | ||
287 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | ||
288 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | ||
289 | |||
290 | @ Restore EMIFF controls | ||
291 | str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | ||
292 | str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | ||
293 | |||
294 | @ restore regs and return | ||
295 | ldmfd sp!, {r0 - r12, pc} | ||
296 | |||
297 | ENTRY(omap730_cpu_suspend_sz) | ||
298 | .word . - omap730_cpu_suspend | ||
299 | #endif /* CONFIG_ARCH_OMAP730 */ | ||
300 | |||
301 | #ifdef CONFIG_ARCH_OMAP15XX | ||
173 | ENTRY(omap1510_cpu_suspend) | 302 | ENTRY(omap1510_cpu_suspend) |
174 | 303 | ||
175 | @ save registers on stack | 304 | @ save registers on stack |
@@ -241,7 +370,7 @@ l_1510_2: | |||
241 | 370 | ||
242 | ENTRY(omap1510_cpu_suspend_sz) | 371 | ENTRY(omap1510_cpu_suspend_sz) |
243 | .word . - omap1510_cpu_suspend | 372 | .word . - omap1510_cpu_suspend |
244 | #endif /* CONFIG_ARCH_OMAP1510 */ | 373 | #endif /* CONFIG_ARCH_OMAP15XX */ |
245 | 374 | ||
246 | #if defined(CONFIG_ARCH_OMAP16XX) | 375 | #if defined(CONFIG_ARCH_OMAP16XX) |
247 | ENTRY(omap1610_cpu_suspend) | 376 | ENTRY(omap1610_cpu_suspend) |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 7ad69f14a3e7..792f66375830 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -20,10 +20,13 @@ | |||
20 | #include <asm/io.h> | 20 | #include <asm/io.h> |
21 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
22 | 22 | ||
23 | #include "sram.h" | 23 | #include <asm/arch/sram.h> |
24 | |||
25 | #define OMAP1_SRAM_PA 0x20000000 | ||
26 | #define OMAP1_SRAM_VA 0xd0000000 | ||
27 | #define OMAP2_SRAM_PA 0x40200000 | ||
28 | #define OMAP2_SRAM_VA 0xd0000000 | ||
24 | 29 | ||
25 | #define OMAP1_SRAM_BASE 0xd0000000 | ||
26 | #define OMAP1_SRAM_START 0x20000000 | ||
27 | #define SRAM_BOOTLOADER_SZ 0x80 | 30 | #define SRAM_BOOTLOADER_SZ 0x80 |
28 | 31 | ||
29 | static unsigned long omap_sram_base; | 32 | static unsigned long omap_sram_base; |
@@ -31,37 +34,40 @@ static unsigned long omap_sram_size; | |||
31 | static unsigned long omap_sram_ceil; | 34 | static unsigned long omap_sram_ceil; |
32 | 35 | ||
33 | /* | 36 | /* |
34 | * The amount of SRAM depends on the core type: | 37 | * The amount of SRAM depends on the core type. |
35 | * 730 = 200K, 1510 = 512K, 5912 = 256K, 1610 = 16K, 1710 = 16K | ||
36 | * Note that we cannot try to test for SRAM here because writes | 38 | * Note that we cannot try to test for SRAM here because writes |
37 | * to secure SRAM will hang the system. Also the SRAM is not | 39 | * to secure SRAM will hang the system. Also the SRAM is not |
38 | * yet mapped at this point. | 40 | * yet mapped at this point. |
39 | */ | 41 | */ |
40 | void __init omap_detect_sram(void) | 42 | void __init omap_detect_sram(void) |
41 | { | 43 | { |
42 | omap_sram_base = OMAP1_SRAM_BASE; | 44 | if (!cpu_is_omap24xx()) |
45 | omap_sram_base = OMAP1_SRAM_VA; | ||
46 | else | ||
47 | omap_sram_base = OMAP2_SRAM_VA; | ||
43 | 48 | ||
44 | if (cpu_is_omap730()) | 49 | if (cpu_is_omap730()) |
45 | omap_sram_size = 0x32000; | 50 | omap_sram_size = 0x32000; /* 200K */ |
46 | else if (cpu_is_omap1510()) | 51 | else if (cpu_is_omap15xx()) |
47 | omap_sram_size = 0x80000; | 52 | omap_sram_size = 0x30000; /* 192K */ |
48 | else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710()) | 53 | else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710()) |
49 | omap_sram_size = 0x4000; | 54 | omap_sram_size = 0x4000; /* 16K */ |
50 | else if (cpu_is_omap1611()) | 55 | else if (cpu_is_omap1611()) |
51 | omap_sram_size = 0x3e800; | 56 | omap_sram_size = 0x3e800; /* 250K */ |
57 | else if (cpu_is_omap2420()) | ||
58 | omap_sram_size = 0xa0014; /* 640K */ | ||
52 | else { | 59 | else { |
53 | printk(KERN_ERR "Could not detect SRAM size\n"); | 60 | printk(KERN_ERR "Could not detect SRAM size\n"); |
54 | omap_sram_size = 0x4000; | 61 | omap_sram_size = 0x4000; |
55 | } | 62 | } |
56 | 63 | ||
57 | printk(KERN_INFO "SRAM size: 0x%lx\n", omap_sram_size); | ||
58 | omap_sram_ceil = omap_sram_base + omap_sram_size; | 64 | omap_sram_ceil = omap_sram_base + omap_sram_size; |
59 | } | 65 | } |
60 | 66 | ||
61 | static struct map_desc omap_sram_io_desc[] __initdata = { | 67 | static struct map_desc omap_sram_io_desc[] __initdata = { |
62 | { /* .length gets filled in at runtime */ | 68 | { /* .length gets filled in at runtime */ |
63 | .virtual = OMAP1_SRAM_BASE, | 69 | .virtual = OMAP1_SRAM_VA, |
64 | .pfn = __phys_to_pfn(OMAP1_SRAM_START), | 70 | .pfn = __phys_to_pfn(OMAP1_SRAM_PA), |
65 | .type = MT_DEVICE | 71 | .type = MT_DEVICE |
66 | } | 72 | } |
67 | }; | 73 | }; |
@@ -76,10 +82,19 @@ void __init omap_map_sram(void) | |||
76 | if (omap_sram_size == 0) | 82 | if (omap_sram_size == 0) |
77 | return; | 83 | return; |
78 | 84 | ||
85 | if (cpu_is_omap24xx()) { | ||
86 | omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; | ||
87 | omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA); | ||
88 | } | ||
89 | |||
79 | omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE; | 90 | omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE; |
80 | omap_sram_io_desc[0].length *= PAGE_SIZE; | 91 | omap_sram_io_desc[0].length *= PAGE_SIZE; |
81 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); | 92 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); |
82 | 93 | ||
94 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", | ||
95 | omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual, | ||
96 | omap_sram_io_desc[0].length); | ||
97 | |||
83 | /* | 98 | /* |
84 | * Looks like we need to preserve some bootloader code at the | 99 | * Looks like we need to preserve some bootloader code at the |
85 | * beginning of SRAM for jumping to flash for reboot to work... | 100 | * beginning of SRAM for jumping to flash for reboot to work... |
@@ -88,16 +103,6 @@ void __init omap_map_sram(void) | |||
88 | omap_sram_size - SRAM_BOOTLOADER_SZ); | 103 | omap_sram_size - SRAM_BOOTLOADER_SZ); |
89 | } | 104 | } |
90 | 105 | ||
91 | static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl) = NULL; | ||
92 | |||
93 | void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) | ||
94 | { | ||
95 | if (_omap_sram_reprogram_clock == NULL) | ||
96 | panic("Cannot use SRAM"); | ||
97 | |||
98 | return _omap_sram_reprogram_clock(dpllctl, ckctl); | ||
99 | } | ||
100 | |||
101 | void * omap_sram_push(void * start, unsigned long size) | 106 | void * omap_sram_push(void * start, unsigned long size) |
102 | { | 107 | { |
103 | if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) { | 108 | if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) { |
@@ -111,10 +116,94 @@ void * omap_sram_push(void * start, unsigned long size) | |||
111 | return (void *)omap_sram_ceil; | 116 | return (void *)omap_sram_ceil; |
112 | } | 117 | } |
113 | 118 | ||
114 | void __init omap_sram_init(void) | 119 | static void omap_sram_error(void) |
120 | { | ||
121 | panic("Uninitialized SRAM function\n"); | ||
122 | } | ||
123 | |||
124 | #ifdef CONFIG_ARCH_OMAP1 | ||
125 | |||
126 | static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl); | ||
127 | |||
128 | void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) | ||
129 | { | ||
130 | if (!_omap_sram_reprogram_clock) | ||
131 | omap_sram_error(); | ||
132 | |||
133 | return _omap_sram_reprogram_clock(dpllctl, ckctl); | ||
134 | } | ||
135 | |||
136 | int __init omap1_sram_init(void) | ||
115 | { | 137 | { |
116 | omap_detect_sram(); | ||
117 | omap_map_sram(); | ||
118 | _omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock, | 138 | _omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock, |
119 | sram_reprogram_clock_sz); | 139 | sram_reprogram_clock_sz); |
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | #else | ||
145 | #define omap1_sram_init() do {} while (0) | ||
146 | #endif | ||
147 | |||
148 | #ifdef CONFIG_ARCH_OMAP2 | ||
149 | |||
150 | static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, | ||
151 | u32 base_cs, u32 force_unlock); | ||
152 | |||
153 | void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, | ||
154 | u32 base_cs, u32 force_unlock) | ||
155 | { | ||
156 | if (!_omap2_sram_ddr_init) | ||
157 | omap_sram_error(); | ||
158 | |||
159 | return _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl, | ||
160 | base_cs, force_unlock); | ||
161 | } | ||
162 | |||
163 | static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val, | ||
164 | u32 mem_type); | ||
165 | |||
166 | void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type) | ||
167 | { | ||
168 | if (!_omap2_sram_reprogram_sdrc) | ||
169 | omap_sram_error(); | ||
170 | |||
171 | return _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type); | ||
172 | } | ||
173 | |||
174 | static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); | ||
175 | |||
176 | u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass) | ||
177 | { | ||
178 | if (!_omap2_set_prcm) | ||
179 | omap_sram_error(); | ||
180 | |||
181 | return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass); | ||
182 | } | ||
183 | |||
184 | int __init omap2_sram_init(void) | ||
185 | { | ||
186 | _omap2_sram_ddr_init = omap_sram_push(sram_ddr_init, sram_ddr_init_sz); | ||
187 | |||
188 | _omap2_sram_reprogram_sdrc = omap_sram_push(sram_reprogram_sdrc, | ||
189 | sram_reprogram_sdrc_sz); | ||
190 | _omap2_set_prcm = omap_sram_push(sram_set_prcm, sram_set_prcm_sz); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | #else | ||
195 | #define omap2_sram_init() do {} while (0) | ||
196 | #endif | ||
197 | |||
198 | int __init omap_sram_init(void) | ||
199 | { | ||
200 | omap_detect_sram(); | ||
201 | omap_map_sram(); | ||
202 | |||
203 | if (!cpu_is_omap24xx()) | ||
204 | omap1_sram_init(); | ||
205 | else | ||
206 | omap2_sram_init(); | ||
207 | |||
208 | return 0; | ||
120 | } | 209 | } |
diff --git a/arch/arm/plat-omap/sram.h b/arch/arm/plat-omap/sram.h deleted file mode 100644 index 71984efa6ae8..000000000000 --- a/arch/arm/plat-omap/sram.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/plat-omap/sram.h | ||
3 | * | ||
4 | * Interface for functions that need to be run in internal SRAM | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ARCH_ARM_OMAP_SRAM_H | ||
12 | #define __ARCH_ARM_OMAP_SRAM_H | ||
13 | |||
14 | extern void * omap_sram_push(void * start, unsigned long size); | ||
15 | extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); | ||
16 | |||
17 | /* Do not use these */ | ||
18 | extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl); | ||
19 | extern unsigned long sram_reprogram_clock_sz; | ||
20 | |||
21 | #endif | ||
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c index 205e2d0b826d..00afc7a8c2ab 100644 --- a/arch/arm/plat-omap/usb.c +++ b/arch/arm/plat-omap/usb.c | |||
@@ -91,6 +91,8 @@ EXPORT_SYMBOL(otg_set_transceiver); | |||
91 | 91 | ||
92 | /*-------------------------------------------------------------------------*/ | 92 | /*-------------------------------------------------------------------------*/ |
93 | 93 | ||
94 | #if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX) | ||
95 | |||
94 | static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) | 96 | static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) |
95 | { | 97 | { |
96 | u32 syscon1 = 0; | 98 | u32 syscon1 = 0; |
@@ -271,6 +273,8 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) | |||
271 | return syscon1 << 24; | 273 | return syscon1 << 24; |
272 | } | 274 | } |
273 | 275 | ||
276 | #endif | ||
277 | |||
274 | /*-------------------------------------------------------------------------*/ | 278 | /*-------------------------------------------------------------------------*/ |
275 | 279 | ||
276 | #if defined(CONFIG_USB_GADGET_OMAP) || \ | 280 | #if defined(CONFIG_USB_GADGET_OMAP) || \ |
@@ -494,7 +498,7 @@ static inline void omap_otg_init(struct omap_usb_config *config) {} | |||
494 | 498 | ||
495 | /*-------------------------------------------------------------------------*/ | 499 | /*-------------------------------------------------------------------------*/ |
496 | 500 | ||
497 | #ifdef CONFIG_ARCH_OMAP1510 | 501 | #ifdef CONFIG_ARCH_OMAP15XX |
498 | 502 | ||
499 | #define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL) | 503 | #define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL) |
500 | #define DPLL_IOB (1 << 13) | 504 | #define DPLL_IOB (1 << 13) |
@@ -507,7 +511,6 @@ static inline void omap_otg_init(struct omap_usb_config *config) {} | |||
507 | 511 | ||
508 | static void __init omap_1510_usb_init(struct omap_usb_config *config) | 512 | static void __init omap_1510_usb_init(struct omap_usb_config *config) |
509 | { | 513 | { |
510 | int status; | ||
511 | unsigned int val; | 514 | unsigned int val; |
512 | 515 | ||
513 | omap_usb0_init(config->pins[0], is_usb0_device(config)); | 516 | omap_usb0_init(config->pins[0], is_usb0_device(config)); |
@@ -539,6 +542,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config) | |||
539 | 542 | ||
540 | #ifdef CONFIG_USB_GADGET_OMAP | 543 | #ifdef CONFIG_USB_GADGET_OMAP |
541 | if (config->register_dev) { | 544 | if (config->register_dev) { |
545 | int status; | ||
546 | |||
542 | udc_device.dev.platform_data = config; | 547 | udc_device.dev.platform_data = config; |
543 | status = platform_device_register(&udc_device); | 548 | status = platform_device_register(&udc_device); |
544 | if (status) | 549 | if (status) |
@@ -549,6 +554,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config) | |||
549 | 554 | ||
550 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 555 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
551 | if (config->register_host) { | 556 | if (config->register_host) { |
557 | int status; | ||
558 | |||
552 | ohci_device.dev.platform_data = config; | 559 | ohci_device.dev.platform_data = config; |
553 | status = platform_device_register(&ohci_device); | 560 | status = platform_device_register(&ohci_device); |
554 | if (status) | 561 | if (status) |