Merge branch 'next/soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 27 Jul 2011 00:09:31 +0000 (17:09 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 27 Jul 2011 00:09:31 +0000 (17:09 -0700)
* 'next/soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux-arm-soc:
  MAINTAINERS: add maintainer of CSR SiRFprimaII machine
  ARM: CSR: initializing L2 cache
  ARM: CSR: mapping early DEBUG_LL uart
  ARM: CSR: Adding CSR SiRFprimaII board support
  OMAP4: clocks: Update the clock tree with 4460 clock nodes
  OMAP4: PRCM: OMAP4460 specific PRM and CM register bitshifts
  OMAP4: ID: add omap_has_feature for max freq supported
  OMAP: ID: introduce chip detection for OMAP4460
  ARM: Xilinx: merge board file into main platform code
  ARM: Xilinx: Adding Xilinx board support

Fix up conflicts in arch/arm/mach-omap2/cm-regbits-44xx.h

57 files changed:
Documentation/devicetree/bindings/arm/sirf.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/xilinx.txt [new file with mode: 0644]
MAINTAINERS
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/dts/prima2-cb.dts [new file with mode: 0644]
arch/arm/boot/dts/zynq-ep107.dts [new file with mode: 0644]
arch/arm/mach-omap2/clock44xx_data.c
arch/arm/mach-omap2/cm-regbits-44xx.h
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/prm-regbits-44xx.h
arch/arm/mach-prima2/Makefile [new file with mode: 0644]
arch/arm/mach-prima2/Makefile.boot [new file with mode: 0644]
arch/arm/mach-prima2/clock.c [new file with mode: 0644]
arch/arm/mach-prima2/common.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/clkdev.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/map.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/memory.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/system.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/uart.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-prima2/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/mach-prima2/irq.c [new file with mode: 0644]
arch/arm/mach-prima2/l2x0.c [new file with mode: 0644]
arch/arm/mach-prima2/lluart.c [new file with mode: 0644]
arch/arm/mach-prima2/prima2.c [new file with mode: 0644]
arch/arm/mach-prima2/rstc.c [new file with mode: 0644]
arch/arm/mach-prima2/timer.c [new file with mode: 0644]
arch/arm/mach-zynq/Makefile [new file with mode: 0644]
arch/arm/mach-zynq/Makefile.boot [new file with mode: 0644]
arch/arm/mach-zynq/board_dt.c [new file with mode: 0644]
arch/arm/mach-zynq/common.c [new file with mode: 0644]
arch/arm/mach-zynq/common.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/clkdev.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/memory.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/system.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/uart.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/mach-zynq/include/mach/zynq_soc.h [new file with mode: 0644]
arch/arm/mach-zynq/timer.c [new file with mode: 0644]
arch/arm/mm/Kconfig
arch/arm/plat-omap/include/plat/clkdev_omap.h
arch/arm/plat-omap/include/plat/clock.h
arch/arm/plat-omap/include/plat/cpu.h

diff --git a/Documentation/devicetree/bindings/arm/sirf.txt b/Documentation/devicetree/bindings/arm/sirf.txt
new file mode 100644 (file)
index 0000000..6b07f65
--- /dev/null
@@ -0,0 +1,3 @@
+prima2 "cb" evalutation board
+Required root node properties:
+    - compatible = "sirf,prima2-cb", "sirf,prima2";
diff --git a/Documentation/devicetree/bindings/arm/xilinx.txt b/Documentation/devicetree/bindings/arm/xilinx.txt
new file mode 100644 (file)
index 0000000..6f1ed83
--- /dev/null
@@ -0,0 +1,7 @@
+Xilinx Zynq EP107 Emulation Platform board
+
+This board is an emulation platform for the Zynq product which is
+based on an ARM Cortex A9 processor.
+
+Required root node properties:
+    - compatible = "xlnx,zynq-ep107";
index bf99d93..7b2e9e8 100644 (file)
@@ -734,6 +734,12 @@ T: git git://git.berlios.de/gemini-board
 S:     Maintained
 F:     arch/arm/mach-gemini/
 
+ARM/CSR SIRFPRIMA2 MACHINE SUPPORT
+M:     Barry Song <baohua.song@csr.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-prima2/
+
 ARM/EBSA110 MACHINE SUPPORT
 M:     Russell King <linux@arm.linux.org.uk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
index 9cb1f4b..1f69211 100644 (file)
@@ -340,6 +340,19 @@ config ARCH_GEMINI
        help
          Support for the Cortina Systems Gemini family SoCs
 
+config ARCH_PRIMA2
+       bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform"
+       select CPU_V7
+       select GENERIC_TIME
+       select NO_IOPORT
+       select GENERIC_CLOCKEVENTS
+       select CLKDEV_LOOKUP
+       select GENERIC_IRQ_CHIP
+       select USE_OF
+       select ZONE_DMA
+       help
+          Support for CSR SiRFSoC ARM Cortex A9 Platform
+
 config ARCH_EBSA110
        bool "EBSA-110"
        select CPU_SA110
@@ -884,6 +897,19 @@ config ARCH_VT8500
        select HAVE_PWM
        help
          Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
+
+config ARCH_ZYNQ
+       bool "Xilinx Zynq ARM Cortex A9 Platform"
+       select CPU_V7
+       select GENERIC_TIME
+       select GENERIC_CLOCKEVENTS
+       select CLKDEV_LOOKUP
+       select ARM_GIC
+       select ARM_AMBA
+       select ICST
+       select USE_OF
+       help
+         Support for Xilinx Zynq ARM Cortex A9 Platform
 endchoice
 
 #
index 206c34e..3a4a04b 100644 (file)
@@ -168,6 +168,7 @@ machine-$(CONFIG_ARCH_OMAP3)                := omap2
 machine-$(CONFIG_ARCH_OMAP4)           := omap2
 machine-$(CONFIG_ARCH_ORION5X)         := orion5x
 machine-$(CONFIG_ARCH_PNX4008)         := pnx4008
+machine-$(CONFIG_ARCH_PRIMA2)          := prima2
 machine-$(CONFIG_ARCH_PXA)             := pxa
 machine-$(CONFIG_ARCH_REALVIEW)                := realview
 machine-$(CONFIG_ARCH_RPC)             := rpc
@@ -194,6 +195,7 @@ machine-$(CONFIG_MACH_SPEAR300)             := spear3xx
 machine-$(CONFIG_MACH_SPEAR310)                := spear3xx
 machine-$(CONFIG_MACH_SPEAR320)                := spear3xx
 machine-$(CONFIG_MACH_SPEAR600)                := spear6xx
+machine-$(CONFIG_ARCH_ZYNQ)            := zynq
 
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -201,6 +203,7 @@ plat-$(CONFIG_ARCH_MXC)             := mxc
 plat-$(CONFIG_ARCH_OMAP)       := omap
 plat-$(CONFIG_ARCH_S3C64XX)    := samsung
 plat-$(CONFIG_ARCH_TCC_926)    := tcc
+plat-$(CONFIG_ARCH_ZYNQ)       := versatile
 plat-$(CONFIG_PLAT_IOP)                := iop
 plat-$(CONFIG_PLAT_NOMADIK)    := nomadik
 plat-$(CONFIG_PLAT_ORION)      := orion
diff --git a/arch/arm/boot/dts/prima2-cb.dts b/arch/arm/boot/dts/prima2-cb.dts
new file mode 100644 (file)
index 0000000..6fecc88
--- /dev/null
@@ -0,0 +1,416 @@
+/dts-v1/;
+/ {
+       model = "SiRF Prima2 eVB";
+       compatible = "sirf,prima2-cb", "sirf,prima2";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       interrupt-parent = <&intc>;
+
+       memory {
+               reg = <0x00000000 0x20000000>;
+       };
+
+       chosen {
+               bootargs = "mem=512M real_root=/dev/mmcblk0p2 console=ttyS0 panel=1 bootsplash=true bpp=16 androidboot.console=ttyS1";
+               linux,stdout-path = &uart1;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       reg = <0x0>;
+                       d-cache-line-size = <32>;
+                       i-cache-line-size = <32>;
+                       d-cache-size = <32768>;
+                       i-cache-size = <32768>;
+                       /* from bootloader */
+                       timebase-frequency = <0>;
+                       bus-frequency = <0>;
+                       clock-frequency = <0>;
+               };
+       };
+
+       axi {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x40000000 0x40000000 0x80000000>;
+
+               l2-cache-controller@80040000 {
+                       compatible = "arm,pl310-cache";
+                       reg = <0x80040000 0x1000>;
+                       interrupts = <59>;
+               };
+
+               intc: interrupt-controller@80020000 {
+                       #interrupt-cells = <1>;
+                       interrupt-controller;
+                       compatible = "sirf,prima2-intc";
+                       reg = <0x80020000 0x1000>;
+               };
+
+               sys-iobg {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x88000000 0x88000000 0x40000>;
+
+                       clock-controller@88000000 {
+                               compatible = "sirf,prima2-clkc";
+                               reg = <0x88000000 0x1000>;
+                               interrupts = <3>;
+                       };
+
+                       reset-controller@88010000 {
+                               compatible = "sirf,prima2-rstc";
+                               reg = <0x88010000 0x1000>;
+                       };
+               };
+
+               mem-iobg {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x90000000 0x90000000 0x10000>;
+
+                       memory-controller@90000000 {
+                               compatible = "sirf,prima2-memc";
+                               reg = <0x90000000 0x10000>;
+                               interrupts = <27>;
+                       };
+               };
+
+               disp-iobg {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x90010000 0x90010000 0x30000>;
+
+                       display@90010000 {
+                               compatible = "sirf,prima2-lcd";
+                               reg = <0x90010000 0x20000>;
+                               interrupts = <30>;
+                       };
+
+                       vpp@90020000 {
+                               compatible = "sirf,prima2-vpp";
+                               reg = <0x90020000 0x10000>;
+                               interrupts = <31>;
+                       };
+               };
+
+               graphics-iobg {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x98000000 0x98000000 0x8000000>;
+
+                       graphics@98000000 {
+                               compatible = "powervr,sgx531";
+                               reg = <0x98000000 0x8000000>;
+                               interrupts = <6>;
+                       };
+               };
+
+               multimedia-iobg {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0xa0000000 0xa0000000 0x8000000>;
+
+                       multimedia@a0000000 {
+                               compatible = "sirf,prima2-video-codec";
+                               reg = <0xa0000000 0x8000000>;
+                               interrupts = <5>;
+                       };
+               };
+
+               dsp-iobg {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0xa8000000 0xa8000000 0x2000000>;
+
+                       dspif@a8000000 {
+                               compatible = "sirf,prima2-dspif";
+                               reg = <0xa8000000 0x10000>;
+                               interrupts = <9>;
+                       };
+
+                       gps@a8010000 {
+                               compatible = "sirf,prima2-gps";
+                               reg = <0xa8010000 0x10000>;
+                               interrupts = <7>;
+                       };
+
+                       dsp@a9000000 {
+                               compatible = "sirf,prima2-dsp";
+                               reg = <0xa9000000 0x1000000>;
+                               interrupts = <8>;
+                       };
+               };
+
+               peri-iobg {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0xb0000000 0xb0000000 0x180000>;
+
+                       timer@b0020000 {
+                               compatible = "sirf,prima2-tick";
+                               reg = <0xb0020000 0x1000>;
+                               interrupts = <0>;
+                       };
+
+                       nand@b0030000 {
+                               compatible = "sirf,prima2-nand";
+                               reg = <0xb0030000 0x10000>;
+                               interrupts = <41>;
+                       };
+
+                       audio@b0040000 {
+                               compatible = "sirf,prima2-audio";
+                               reg = <0xb0040000 0x10000>;
+                               interrupts = <35>;
+                       };
+
+                       uart0: uart@b0050000 {
+                               cell-index = <0>;
+                               compatible = "sirf,prima2-uart";
+                               reg = <0xb0050000 0x10000>;
+                               interrupts = <17>;
+                       };
+
+                       uart1: uart@b0060000 {
+                               cell-index = <1>;
+                               compatible = "sirf,prima2-uart";
+                               reg = <0xb0060000 0x10000>;
+                               interrupts = <18>;
+                       };
+
+                       uart2: uart@b0070000 {
+                               cell-index = <2>;
+                               compatible = "sirf,prima2-uart";
+                               reg = <0xb0070000 0x10000>;
+                               interrupts = <19>;
+                       };
+
+                       usp0: usp@b0080000 {
+                               cell-index = <0>;
+                               compatible = "sirf,prima2-usp";
+                               reg = <0xb0080000 0x10000>;
+                               interrupts = <20>;
+                       };
+
+                       usp1: usp@b0090000 {
+                               cell-index = <1>;
+                               compatible = "sirf,prima2-usp";
+                               reg = <0xb0090000 0x10000>;
+                               interrupts = <21>;
+                       };
+
+                       usp2: usp@b00a0000 {
+                               cell-index = <2>;
+                               compatible = "sirf,prima2-usp";
+                               reg = <0xb00a0000 0x10000>;
+                               interrupts = <22>;
+                       };
+
+                       dmac0: dma-controller@b00b0000 {
+                               cell-index = <0>;
+                               compatible = "sirf,prima2-dmac";
+                               reg = <0xb00b0000 0x10000>;
+                               interrupts = <12>;
+                       };
+
+                       dmac1: dma-controller@b0160000 {
+                               cell-index = <1>;
+                               compatible = "sirf,prima2-dmac";
+                               reg = <0xb0160000 0x10000>;
+                               interrupts = <13>;
+                       };
+
+                       vip@b00C0000 {
+                               compatible = "sirf,prima2-vip";
+                               reg = <0xb00C0000 0x10000>;
+                       };
+
+                       spi0: spi@b00d0000 {
+                               cell-index = <0>;
+                               compatible = "sirf,prima2-spi";
+                               reg = <0xb00d0000 0x10000>;
+                               interrupts = <15>;
+                       };
+
+                       spi1: spi@b0170000 {
+                               cell-index = <1>;
+                               compatible = "sirf,prima2-spi";
+                               reg = <0xb0170000 0x10000>;
+                               interrupts = <16>;
+                       };
+
+                       i2c0: i2c@b00e0000 {
+                               cell-index = <0>;
+                               compatible = "sirf,prima2-i2c";
+                               reg = <0xb00e0000 0x10000>;
+                               interrupts = <24>;
+                       };
+
+                       i2c1: i2c@b00f0000 {
+                               cell-index = <1>;
+                               compatible = "sirf,prima2-i2c";
+                               reg = <0xb00f0000 0x10000>;
+                               interrupts = <25>;
+                       };
+
+                       tsc@b0110000 {
+                               compatible = "sirf,prima2-tsc";
+                               reg = <0xb0110000 0x10000>;
+                               interrupts = <33>;
+                       };
+
+                       gpio: gpio-controller@b0120000 {
+                               #gpio-cells = <2>;
+                               #interrupt-cells = <2>;
+                               compatible = "sirf,prima2-gpio";
+                               reg = <0xb0120000 0x10000>;
+                               gpio-controller;
+                               interrupt-controller;
+                       };
+
+                       pwm@b0130000 {
+                               compatible = "sirf,prima2-pwm";
+                               reg = <0xb0130000 0x10000>;
+                       };
+
+                       efusesys@b0140000 {
+                               compatible = "sirf,prima2-efuse";
+                               reg = <0xb0140000 0x10000>;
+                       };
+
+                       pulsec@b0150000 {
+                               compatible = "sirf,prima2-pulsec";
+                               reg = <0xb0150000 0x10000>;
+                               interrupts = <48>;
+                       };
+
+                       pci-iobg {
+                               compatible = "sirf,prima2-pciiobg", "simple-bus";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x56000000 0x56000000 0x1b00000>;
+
+                               sd0: sdhci@56000000 {
+                                       cell-index = <0>;
+                                       compatible = "sirf,prima2-sdhc";
+                                       reg = <0x56000000 0x100000>;
+                                       interrupts = <38>;
+                               };
+
+                               sd1: sdhci@56100000 {
+                                       cell-index = <1>;
+                                       compatible = "sirf,prima2-sdhc";
+                                       reg = <0x56100000 0x100000>;
+                                       interrupts = <38>;
+                               };
+
+                               sd2: sdhci@56200000 {
+                                       cell-index = <2>;
+                                       compatible = "sirf,prima2-sdhc";
+                                       reg = <0x56200000 0x100000>;
+                                       interrupts = <23>;
+                               };
+
+                               sd3: sdhci@56300000 {
+                                       cell-index = <3>;
+                                       compatible = "sirf,prima2-sdhc";
+                                       reg = <0x56300000 0x100000>;
+                                       interrupts = <23>;
+                               };
+
+                               sd4: sdhci@56400000 {
+                                       cell-index = <4>;
+                                       compatible = "sirf,prima2-sdhc";
+                                       reg = <0x56400000 0x100000>;
+                                       interrupts = <39>;
+                               };
+
+                               sd5: sdhci@56500000 {
+                                       cell-index = <5>;
+                                       compatible = "sirf,prima2-sdhc";
+                                       reg = <0x56500000 0x100000>;
+                                       interrupts = <39>;
+                               };
+
+                               pci-copy@57900000 {
+                                       compatible = "sirf,prima2-pcicp";
+                                       reg = <0x57900000 0x100000>;
+                                       interrupts = <40>;
+                               };
+
+                               rom-interface@57a00000 {
+                                       compatible = "sirf,prima2-romif";
+                                       reg = <0x57a00000 0x100000>;
+                               };
+                       };
+               };
+
+               rtc-iobg {
+                       compatible = "sirf,prima2-rtciobg", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x80030000 0x10000>;
+
+                       gpsrtc@1000 {
+                               compatible = "sirf,prima2-gpsrtc";
+                               reg = <0x1000 0x1000>;
+                               interrupts = <55 56 57>;
+                       };
+
+                       sysrtc@2000 {
+                               compatible = "sirf,prima2-sysrtc";
+                               reg = <0x2000 0x1000>;
+                               interrupts = <52 53 54>;
+                       };
+
+                       pwrc@3000 {
+                               compatible = "sirf,prima2-pwrc";
+                               reg = <0x3000 0x1000>;
+                               interrupts = <32>;
+                       };
+               };
+
+               uus-iobg {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0xb8000000 0xb8000000 0x40000>;
+
+                       usb0: usb@b00e0000 {
+                               compatible = "chipidea,ci13611a-prima2";
+                               reg = <0xb8000000 0x10000>;
+                               interrupts = <10>;
+                       };
+
+                       usb1: usb@b00f0000 {
+                               compatible = "chipidea,ci13611a-prima2";
+                               reg = <0xb8010000 0x10000>;
+                               interrupts = <11>;
+                       };
+
+                       sata@b00f0000 {
+                               compatible = "synopsys,dwc-ahsata";
+                               reg = <0xb8020000 0x10000>;
+                               interrupts = <37>;
+                       };
+
+                       security@b00f0000 {
+                               compatible = "sirf,prima2-security";
+                               reg = <0xb8030000 0x10000>;
+                               interrupts = <42>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/zynq-ep107.dts b/arch/arm/boot/dts/zynq-ep107.dts
new file mode 100644 (file)
index 0000000..37ca192
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/ {
+       model = "Xilinx Zynq EP107";
+       compatible = "xlnx,zynq-ep107";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       interrupt-parent = <&intc>;
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x10000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyPS0,9600 root=/dev/ram rw initrd=0x800000,8M earlyprintk";
+               linux,stdout-path = &uart0;
+       };
+
+       amba {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               intc: interrupt-controller@f8f01000 {
+                       interrupt-controller;
+                       compatible = "arm,gic";
+                       reg = <0xF8F01000 0x1000>;
+                       #interrupt-cells = <2>;
+               };
+
+               uart0: uart@e0000000 {
+                       compatible = "xlnx,xuartps";
+                       reg = <0xE0000000 0x1000>;
+                       interrupts = <59 0>;
+                       clock = <50000000>;
+               };
+       };
+};
index 044df38..5b7cab7 100644 (file)
@@ -1397,6 +1397,40 @@ static struct clk dss_dss_clk = {
        .recalc         = &followparent_recalc,
 };
 
+static const struct clksel_rate div3_8to32_rates[] = {
+       { .div = 8, .val = 0, .flags = RATE_IN_44XX },
+       { .div = 16, .val = 1, .flags = RATE_IN_44XX },
+       { .div = 32, .val = 2, .flags = RATE_IN_44XX },
+       { .div = 0 },
+};
+
+static const struct clksel div_ts_div[] = {
+       { .parent = &l4_wkup_clk_mux_ck, .rates = div3_8to32_rates },
+       { .parent = NULL },
+};
+
+static struct clk div_ts_ck = {
+       .name           = "div_ts_ck",
+       .parent         = &l4_wkup_clk_mux_ck,
+       .clksel         = div_ts_div,
+       .clksel_reg     = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+       .clksel_mask    = OMAP4430_CLKSEL_24_25_MASK,
+       .ops            = &clkops_null,
+       .recalc         = &omap2_clksel_recalc,
+       .round_rate     = &omap2_clksel_round_rate,
+       .set_rate       = &omap2_clksel_set_rate,
+};
+
+static struct clk bandgap_ts_fclk = {
+       .name           = "bandgap_ts_fclk",
+       .ops            = &clkops_omap2_dflt,
+       .enable_reg     = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+       .enable_bit     = OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT,
+       .clkdm_name     = "l4_wkup_clkdm",
+       .parent         = &div_ts_ck,
+       .recalc         = &followparent_recalc,
+};
+
 static struct clk dss_48mhz_clk = {
        .name           = "dss_48mhz_clk",
        .ops            = &clkops_omap2_dflt,
@@ -3028,7 +3062,9 @@ static struct omap_clk omap44xx_clks[] = {
        CLK(NULL,       "aes2_fck",                     &aes2_fck,      CK_443X),
        CLK(NULL,       "aess_fck",                     &aess_fck,      CK_443X),
        CLK(NULL,       "bandgap_fclk",                 &bandgap_fclk,  CK_443X),
+       CLK(NULL,       "bandgap_ts_fclk",              &bandgap_ts_fclk,       CK_446X),
        CLK(NULL,       "des3des_fck",                  &des3des_fck,   CK_443X),
+       CLK(NULL,       "div_ts_ck",                    &div_ts_ck,     CK_446X),
        CLK(NULL,       "dmic_sync_mux_ck",             &dmic_sync_mux_ck,      CK_443X),
        CLK(NULL,       "dmic_fck",                     &dmic_fck,      CK_443X),
        CLK(NULL,       "dsp_fck",                      &dsp_fck,       CK_443X),
@@ -3208,6 +3244,9 @@ int __init omap4xxx_clk_init(void)
        if (cpu_is_omap44xx()) {
                cpu_mask = RATE_IN_4430;
                cpu_clkflg = CK_443X;
+       } else if (cpu_is_omap446x()) {
+               cpu_mask = RATE_IN_4460;
+               cpu_clkflg = CK_446X;
        }
 
        clk_init(&omap2_clk_functions);
index 0e77945..65597a7 100644 (file)
 #define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_SHIFT           9
 #define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_MASK            (1 << 9)
 
+/* Used by CM_L4CFG_CLKSTCTRL */
+#define OMAP4460_CLKACTIVITY_CORE_TS_GFCLK_SHIFT               9
+#define OMAP4460_CLKACTIVITY_CORE_TS_GFCLK_MASK                        (1 << 9)
+
 /* Used by CM_CEFUSE_CLKSTCTRL */
 #define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT          9
 #define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK           (1 << 9)
 #define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_SHIFT              11
 #define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_MASK               (1 << 11)
 
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4460_CLKACTIVITY_WKUP_TS_GFCLK_SHIFT               13
+#define OMAP4460_CLKACTIVITY_WKUP_TS_GFCLK_MASK                        (1 << 13)
+
 /*
  * Used by CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL,
  * CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL,
 #define OMAP4430_CLKSEL_60M_SHIFT                              24
 #define OMAP4430_CLKSEL_60M_MASK                               (1 << 24)
 
+/* Used by CM_MPU_MPU_CLKCTRL */
+#define OMAP4460_CLKSEL_ABE_DIV_MODE_SHIFT                     25
+#define OMAP4460_CLKSEL_ABE_DIV_MODE_MASK                      (1 << 25)
+
 /* Used by CM1_ABE_AESS_CLKCTRL */
 #define OMAP4430_CLKSEL_AESS_FCLK_SHIFT                                24
 #define OMAP4430_CLKSEL_AESS_FCLK_MASK                         (1 << 24)
 #define OMAP4430_CLKSEL_DIV_SHIFT                              24
 #define OMAP4430_CLKSEL_DIV_MASK                               (1 << 24)
 
+/* Used by CM_MPU_MPU_CLKCTRL */
+#define OMAP4460_CLKSEL_EMIF_DIV_MODE_SHIFT                    24
+#define OMAP4460_CLKSEL_EMIF_DIV_MODE_MASK                     (1 << 24)
+
 /* Used by CM_CAM_FDIF_CLKCTRL */
 #define OMAP4430_CLKSEL_FCLK_SHIFT                             24
 #define OMAP4430_CLKSEL_FCLK_MASK                              (0x3 << 24)
 #define OMAP4430_D2D_STATDEP_SHIFT                             18
 #define OMAP4430_D2D_STATDEP_MASK                              (1 << 18)
 
+/* Used by CM_CLKSEL_DPLL_MPU */
+#define OMAP4460_DCC_COUNT_MAX_SHIFT                           24
+#define OMAP4460_DCC_COUNT_MAX_MASK                            (0xff << 24)
+
+/* Used by CM_CLKSEL_DPLL_MPU */
+#define OMAP4460_DCC_EN_SHIFT                                  22
+#define OMAP4460_DCC_EN_MASK                                   (1 << 22)
+
 /*
  * Used by CM_SSC_DELTAMSTEP_DPLL_ABE, CM_SSC_DELTAMSTEP_DPLL_CORE,
  * CM_SSC_DELTAMSTEP_DPLL_DDRPHY, CM_SSC_DELTAMSTEP_DPLL_IVA,
 #define OMAP4430_DELTAMSTEP_SHIFT                              0
 #define OMAP4430_DELTAMSTEP_MASK                               (0xfffff << 0)
 
+/* Renamed from DELTAMSTEP Used by CM_SSC_DELTAMSTEP_DPLL_USB */
+#define OMAP4460_DELTAMSTEP_0_20_SHIFT                         0
+#define OMAP4460_DELTAMSTEP_0_20_MASK                          (0x1fffff << 0)
+
 /* Used by CM_DLL_CTRL */
 #define OMAP4430_DLL_OVERRIDE_SHIFT                            0
 #define OMAP4430_DLL_OVERRIDE_MASK                             (1 << 0)
 #define OMAP4430_MODULEMODE_SHIFT                              0
 #define OMAP4430_MODULEMODE_MASK                               (0x3 << 0)
 
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP4460_MPU_DYNDEP_SHIFT                              19
+#define OMAP4460_MPU_DYNDEP_MASK                               (1 << 19)
+
 /* Used by CM_DSS_DSS_CLKCTRL */
 #define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT                     9
 #define OMAP4430_OPTFCLKEN_48MHZ_CLK_MASK                      (1 << 9)
 #define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT                       10
 #define OMAP4430_OPTFCLKEN_SYS_CLK_MASK                                (1 << 10)
 
+/* Used by CM_WKUP_BANDGAP_CLKCTRL */
+#define OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT                       8
+#define OMAP4460_OPTFCLKEN_TS_FCLK_MASK                                (1 << 8)
+
 /* Used by CM_DSS_DSS_CLKCTRL */
 #define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT                                11
 #define OMAP4430_OPTFCLKEN_TV_CLK_MASK                         (1 << 11)
index 2537090..37efb86 100644 (file)
@@ -31,7 +31,7 @@
 static struct omap_chip_id omap_chip;
 static unsigned int omap_revision;
 
-u32 omap3_features;
+u32 omap_features;
 
 unsigned int omap_rev(void)
 {
@@ -183,14 +183,14 @@ static void __init omap24xx_check_revision(void)
 #define OMAP3_CHECK_FEATURE(status,feat)                               \
        if (((status & OMAP3_ ##feat## _MASK)                           \
                >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) {   \
-               omap3_features |= OMAP3_HAS_ ##feat;                    \
+               omap_features |= OMAP3_HAS_ ##feat;                     \
        }
 
 static void __init omap3_check_features(void)
 {
        u32 status;
 
-       omap3_features = 0;
+       omap_features = 0;
 
        status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS);
 
@@ -200,11 +200,11 @@ static void __init omap3_check_features(void)
        OMAP3_CHECK_FEATURE(status, NEON);
        OMAP3_CHECK_FEATURE(status, ISP);
        if (cpu_is_omap3630())
-               omap3_features |= OMAP3_HAS_192MHZ_CLK;
+               omap_features |= OMAP3_HAS_192MHZ_CLK;
        if (!cpu_is_omap3505() && !cpu_is_omap3517())
-               omap3_features |= OMAP3_HAS_IO_WAKEUP;
+               omap_features |= OMAP3_HAS_IO_WAKEUP;
 
-       omap3_features |= OMAP3_HAS_SDRC;
+       omap_features |= OMAP3_HAS_SDRC;
 
        /*
         * TODO: Get additional info (where applicable)
@@ -212,9 +212,34 @@ static void __init omap3_check_features(void)
         */
 }
 
+static void __init omap4_check_features(void)
+{
+       u32 si_type;
+
+       if (cpu_is_omap443x())
+               omap_features |= OMAP4_HAS_MPU_1GHZ;
+
+
+       if (cpu_is_omap446x()) {
+               si_type =
+                       read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1);
+               switch ((si_type & (3 << 16)) >> 16) {
+               case 2:
+                       /* High performance device */
+                       omap_features |= OMAP4_HAS_MPU_1_5GHZ;
+                       break;
+               case 1:
+               default:
+                       /* Standard device */
+                       omap_features |= OMAP4_HAS_MPU_1_2GHZ;
+                       break;
+               }
+       }
+}
+
 static void __init ti816x_check_features(void)
 {
-       omap3_features = OMAP3_HAS_NEON;
+       omap_features = OMAP3_HAS_NEON;
 }
 
 static void __init omap3_check_revision(void)
@@ -344,10 +369,10 @@ static void __init omap4_check_revision(void)
        rev = (idcode >> 28) & 0xf;
 
        /*
-        * Few initial ES2.0 samples IDCODE is same as ES1.0
+        * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0
         * Use ARM register to detect the correct ES version
         */
-       if (!rev) {
+       if (!rev && (hawkeye != 0xb94e)) {
                idcode = read_cpuid(CPUID_ID);
                rev = (idcode & 0xf) - 1;
        }
@@ -377,6 +402,15 @@ static void __init omap4_check_revision(void)
                        omap_chip.oc |= CHIP_IS_OMAP4430ES2_2;
                }
                break;
+       case 0xb94e:
+               switch (rev) {
+               case 0:
+               default:
+                       omap_revision = OMAP4460_REV_ES1_0;
+                       omap_chip.oc |= CHIP_IS_OMAP4460ES1_0;
+                       break;
+               }
+               break;
        default:
                /* Unknown default to latest silicon rev as default */
                omap_revision = OMAP4430_REV_ES2_2;
@@ -518,6 +552,7 @@ void __init omap2_check_revision(void)
                return;
        } else if (cpu_is_omap44xx()) {
                omap4_check_revision();
+               omap4_check_features();
                return;
        } else {
                pr_err("OMAP revision unknown, please fix!\n");
index 6d2776f..3cb247b 100644 (file)
 #define OMAP4430_DUCATI_UNICACHE_STATEST_SHIFT                         10
 #define OMAP4430_DUCATI_UNICACHE_STATEST_MASK                          (0x3 << 10)
 
+/* Used by PRM_DEVICE_OFF_CTRL */
+#define OMAP4460_EMIF1_OFFWKUP_DISABLE_SHIFT                           8
+#define OMAP4460_EMIF1_OFFWKUP_DISABLE_MASK                            (1 << 8)
+
+/* Used by PRM_DEVICE_OFF_CTRL */
+#define OMAP4460_EMIF2_OFFWKUP_DISABLE_SHIFT                           9
+#define OMAP4460_EMIF2_OFFWKUP_DISABLE_MASK                            (1 << 9)
+
 /* Used by RM_MPU_RSTST */
 #define OMAP4430_EMULATION_RST_SHIFT                                   0
 #define OMAP4430_EMULATION_RST_MASK                                    (1 << 0)
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
new file mode 100644 (file)
index 0000000..7af7fc0
--- /dev/null
@@ -0,0 +1,7 @@
+obj-y := timer.o
+obj-y += irq.o
+obj-y += clock.o
+obj-y += rstc.o
+obj-y += prima2.o
+obj-$(CONFIG_DEBUG_LL) += lluart.o
+obj-$(CONFIG_CACHE_L2X0) += l2x0.o
diff --git a/arch/arm/mach-prima2/Makefile.boot b/arch/arm/mach-prima2/Makefile.boot
new file mode 100644 (file)
index 0000000..d023db3
--- /dev/null
@@ -0,0 +1,3 @@
+zreladdr-y             := 0x00008000
+params_phys-y          := 0x00000100
+initrd_phys-y          := 0x00800000
diff --git a/arch/arm/mach-prima2/clock.c b/arch/arm/mach-prima2/clock.c
new file mode 100644 (file)
index 0000000..f9a2aaf
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * Clock tree for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <asm/mach/map.h>
+#include <mach/map.h>
+
+#define SIRFSOC_CLKC_CLK_EN0    0x0000
+#define SIRFSOC_CLKC_CLK_EN1    0x0004
+#define SIRFSOC_CLKC_REF_CFG    0x0014
+#define SIRFSOC_CLKC_CPU_CFG    0x0018
+#define SIRFSOC_CLKC_MEM_CFG    0x001c
+#define SIRFSOC_CLKC_SYS_CFG    0x0020
+#define SIRFSOC_CLKC_IO_CFG     0x0024
+#define SIRFSOC_CLKC_DSP_CFG    0x0028
+#define SIRFSOC_CLKC_GFX_CFG    0x002c
+#define SIRFSOC_CLKC_MM_CFG     0x0030
+#define SIRFSOC_LKC_LCD_CFG     0x0034
+#define SIRFSOC_CLKC_MMC_CFG    0x0038
+#define SIRFSOC_CLKC_PLL1_CFG0  0x0040
+#define SIRFSOC_CLKC_PLL2_CFG0  0x0044
+#define SIRFSOC_CLKC_PLL3_CFG0  0x0048
+#define SIRFSOC_CLKC_PLL1_CFG1  0x004c
+#define SIRFSOC_CLKC_PLL2_CFG1  0x0050
+#define SIRFSOC_CLKC_PLL3_CFG1  0x0054
+#define SIRFSOC_CLKC_PLL1_CFG2  0x0058
+#define SIRFSOC_CLKC_PLL2_CFG2  0x005c
+#define SIRFSOC_CLKC_PLL3_CFG2  0x0060
+
+#define SIRFSOC_CLOCK_VA_BASE          SIRFSOC_VA(0x005000)
+
+#define KHZ     1000
+#define MHZ     (KHZ * KHZ)
+
+struct clk_ops {
+       unsigned long (*get_rate)(struct clk *clk);
+       long (*round_rate)(struct clk *clk, unsigned long rate);
+       int (*set_rate)(struct clk *clk, unsigned long rate);
+       int (*enable)(struct clk *clk);
+       int (*disable)(struct clk *clk);
+       struct clk *(*get_parent)(struct clk *clk);
+       int (*set_parent)(struct clk *clk, struct clk *parent);
+};
+
+struct clk {
+       struct clk *parent;     /* parent clk */
+       unsigned long rate;     /* clock rate in Hz */
+       signed char usage;      /* clock enable count */
+       signed char enable_bit; /* enable bit: 0 ~ 63 */
+       unsigned short regofs;  /* register offset */
+       struct clk_ops *ops;    /* clock operation */
+};
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static inline unsigned long clkc_readl(unsigned reg)
+{
+       return readl(SIRFSOC_CLOCK_VA_BASE + reg);
+}
+
+static inline void clkc_writel(u32 val, unsigned reg)
+{
+       writel(val, SIRFSOC_CLOCK_VA_BASE + reg);
+}
+
+/*
+ * osc_rtc - real time oscillator - 32.768KHz
+ * osc_sys - high speed oscillator - 26MHz
+ */
+
+static struct clk clk_rtc = {
+       .rate = 32768,
+};
+
+static struct clk clk_osc = {
+       .rate = 26 * MHZ,
+};
+
+/*
+ * std pll
+ */
+static unsigned long std_pll_get_rate(struct clk *clk)
+{
+       unsigned long fin = clk_get_rate(clk->parent);
+       u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 -
+               SIRFSOC_CLKC_PLL1_CFG0;
+
+       if (clkc_readl(regcfg2) & BIT(2)) {
+               /* pll bypass mode */
+               clk->rate = fin;
+       } else {
+               /* fout = fin * nf / nr / od */
+               u32 cfg0 = clkc_readl(clk->regofs);
+               u32 nf = (cfg0 & (BIT(13) - 1)) + 1;
+               u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1;
+               u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1;
+               WARN_ON(fin % MHZ);
+               clk->rate = fin / MHZ * nf / nr / od * MHZ;
+       }
+
+       return clk->rate;
+}
+
+static int std_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned long fin, nf, nr, od, reg;
+
+       /*
+        * fout = fin * nf / (nr * od);
+        * set od = 1, nr = fin/MHz, so fout = nf * MHz
+        */
+
+       nf = rate / MHZ;
+       if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1))
+               return -EINVAL;
+
+       fin = clk_get_rate(clk->parent);
+       BUG_ON(fin < MHZ);
+
+       nr = fin / MHZ;
+       BUG_ON((fin % MHZ) || nr > BIT(6));
+
+       od = 1;
+
+       reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19);
+       clkc_writel(reg, clk->regofs);
+
+       reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0;
+       clkc_writel((nf >> 1) - 1, reg);
+
+       reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0;
+       while (!(clkc_readl(reg) & BIT(6)))
+               cpu_relax();
+
+       clk->rate = 0; /* set to zero will force recalculation */
+       return 0;
+}
+
+static struct clk_ops std_pll_ops = {
+       .get_rate = std_pll_get_rate,
+       .set_rate = std_pll_set_rate,
+};
+
+static struct clk clk_pll1 = {
+       .parent = &clk_osc,
+       .regofs = SIRFSOC_CLKC_PLL1_CFG0,
+       .ops = &std_pll_ops,
+};
+
+static struct clk clk_pll2 = {
+       .parent = &clk_osc,
+       .regofs = SIRFSOC_CLKC_PLL2_CFG0,
+       .ops = &std_pll_ops,
+};
+
+static struct clk clk_pll3 = {
+       .parent = &clk_osc,
+       .regofs = SIRFSOC_CLKC_PLL3_CFG0,
+       .ops = &std_pll_ops,
+};
+
+/*
+ * clock domains - cpu, mem, sys/io
+ */
+
+static struct clk clk_mem;
+
+static struct clk *dmn_get_parent(struct clk *clk)
+{
+       struct clk *clks[] = {
+               &clk_osc, &clk_rtc, &clk_pll1, &clk_pll2, &clk_pll3
+       };
+       u32 cfg = clkc_readl(clk->regofs);
+       WARN_ON((cfg & (BIT(3) - 1)) > 4);
+       return clks[cfg & (BIT(3) - 1)];
+}
+
+static int dmn_set_parent(struct clk *clk, struct clk *parent)
+{
+       const struct clk *clks[] = {
+               &clk_osc, &clk_rtc, &clk_pll1, &clk_pll2, &clk_pll3
+       };
+       u32 cfg = clkc_readl(clk->regofs);
+       int i;
+       for (i = 0; i < ARRAY_SIZE(clks); i++) {
+               if (clks[i] == parent) {
+                       cfg &= ~(BIT(3) - 1);
+                       clkc_writel(cfg | i, clk->regofs);
+                       /* BIT(3) - switching status: 1 - busy, 0 - done */
+                       while (clkc_readl(clk->regofs) & BIT(3))
+                               cpu_relax();
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static unsigned long dmn_get_rate(struct clk *clk)
+{
+       unsigned long fin = clk_get_rate(clk->parent);
+       u32 cfg = clkc_readl(clk->regofs);
+       if (cfg & BIT(24)) {
+               /* fcd bypass mode */
+               clk->rate = fin;
+       } else {
+               /*
+                * wait count: bit[19:16], hold count: bit[23:20]
+                */
+               u32 wait = (cfg >> 16) & (BIT(4) - 1);
+               u32 hold = (cfg >> 20) & (BIT(4) - 1);
+
+               clk->rate = fin / (wait + hold + 2);
+       }
+
+       return clk->rate;
+}
+
+static int dmn_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned long fin;
+       unsigned ratio, wait, hold, reg;
+       unsigned bits = (clk == &clk_mem) ? 3 : 4;
+
+       fin = clk_get_rate(clk->parent);
+       ratio = fin / rate;
+
+       if (unlikely(ratio < 2 || ratio > BIT(bits + 1)))
+               return -EINVAL;
+
+       WARN_ON(fin % rate);
+
+       wait = (ratio >> 1) - 1;
+       hold = ratio - wait - 2;
+
+       reg = clkc_readl(clk->regofs);
+       reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20));
+       reg |= (wait << 16) | (hold << 20) | BIT(25);
+       clkc_writel(reg, clk->regofs);
+
+       /* waiting FCD been effective */
+       while (clkc_readl(clk->regofs) & BIT(25))
+               cpu_relax();
+
+       clk->rate = 0; /* set to zero will force recalculation */
+
+       return 0;
+}
+
+/*
+ * cpu clock has no FCD register in Prima2, can only change pll
+ */
+static int cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+       int ret1, ret2;
+       struct clk *cur_parent, *tmp_parent;
+
+       cur_parent = dmn_get_parent(clk);
+       BUG_ON(cur_parent == NULL || cur_parent->usage > 1);
+
+       /* switch to tmp pll before setting parent clock's rate */
+       tmp_parent = cur_parent == &clk_pll1 ? &clk_pll2 : &clk_pll1;
+       ret1 = dmn_set_parent(clk, tmp_parent);
+       BUG_ON(ret1);
+
+       ret2 = clk_set_rate(cur_parent, rate);
+
+       ret1 = dmn_set_parent(clk, cur_parent);
+
+       clk->rate = 0; /* set to zero will force recalculation */
+
+       return ret2 ? ret2 : ret1;
+}
+
+static struct clk_ops cpu_ops = {
+       .get_parent = dmn_get_parent,
+       .set_parent = dmn_set_parent,
+       .set_rate = cpu_set_rate,
+};
+
+static struct clk clk_cpu = {
+       .parent = &clk_pll1,
+       .regofs = SIRFSOC_CLKC_CPU_CFG,
+       .ops = &cpu_ops,
+};
+
+
+static struct clk_ops msi_ops = {
+       .set_rate = dmn_set_rate,
+       .get_rate = dmn_get_rate,
+       .set_parent = dmn_set_parent,
+       .get_parent = dmn_get_parent,
+};
+
+static struct clk clk_mem = {
+       .parent = &clk_pll2,
+       .regofs = SIRFSOC_CLKC_MEM_CFG,
+       .ops = &msi_ops,
+};
+
+static struct clk clk_sys = {
+       .parent = &clk_pll3,
+       .regofs = SIRFSOC_CLKC_SYS_CFG,
+       .ops = &msi_ops,
+};
+
+static struct clk clk_io = {
+       .parent = &clk_pll3,
+       .regofs = SIRFSOC_CLKC_IO_CFG,
+       .ops = &msi_ops,
+};
+
+/*
+ * on-chip clock sets
+ */
+static struct clk_lookup onchip_clks[] = {
+       {
+               .dev_id = "rtc",
+               .clk = &clk_rtc,
+       }, {
+               .dev_id = "osc",
+               .clk = &clk_osc,
+       }, {
+               .dev_id = "pll1",
+               .clk = &clk_pll1,
+       }, {
+               .dev_id = "pll2",
+               .clk = &clk_pll2,
+       }, {
+               .dev_id = "pll3",
+               .clk = &clk_pll3,
+       }, {
+               .dev_id = "cpu",
+               .clk = &clk_cpu,
+       }, {
+               .dev_id = "mem",
+               .clk = &clk_mem,
+       }, {
+               .dev_id = "sys",
+                       .clk = &clk_sys,
+       }, {
+               .dev_id = "io",
+                       .clk = &clk_io,
+       },
+};
+
+int clk_enable(struct clk *clk)
+{
+       unsigned long flags;
+
+       if (unlikely(IS_ERR_OR_NULL(clk)))
+               return -EINVAL;
+
+       if (clk->parent)
+               clk_enable(clk->parent);
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       if (!clk->usage++ && clk->ops && clk->ops->enable)
+               clk->ops->enable(clk);
+       spin_unlock_irqrestore(&clocks_lock, flags);
+       return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+       unsigned long flags;
+
+       if (unlikely(IS_ERR_OR_NULL(clk)))
+               return;
+
+       WARN_ON(!clk->usage);
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       if (--clk->usage == 0 && clk->ops && clk->ops->disable)
+               clk->ops->disable(clk);
+       spin_unlock_irqrestore(&clocks_lock, flags);
+
+       if (clk->parent)
+               clk_disable(clk->parent);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       if (unlikely(IS_ERR_OR_NULL(clk)))
+               return 0;
+
+       if (clk->rate)
+               return clk->rate;
+
+       if (clk->ops && clk->ops->get_rate)
+               return clk->ops->get_rate(clk);
+
+       return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       if (unlikely(IS_ERR_OR_NULL(clk)))
+               return 0;
+
+       if (clk->ops && clk->ops->round_rate)
+               return clk->ops->round_rate(clk, rate);
+
+       return 0;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       if (unlikely(IS_ERR_OR_NULL(clk)))
+               return -EINVAL;
+
+       if (!clk->ops || !clk->ops->set_rate)
+               return -EINVAL;
+
+       return clk->ops->set_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       int ret;
+       unsigned long flags;
+
+       if (unlikely(IS_ERR_OR_NULL(clk)))
+               return -EINVAL;
+
+       if (!clk->ops || !clk->ops->set_parent)
+               return -EINVAL;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       ret = clk->ops->set_parent(clk, parent);
+       if (!ret) {
+               parent->usage += clk->usage;
+               clk->parent->usage -= clk->usage;
+               BUG_ON(clk->parent->usage < 0);
+               clk->parent = parent;
+       }
+       spin_unlock_irqrestore(&clocks_lock, flags);
+       return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+       unsigned long flags;
+
+       if (unlikely(IS_ERR_OR_NULL(clk)))
+               return NULL;
+
+       if (!clk->ops || !clk->ops->get_parent)
+               return clk->parent;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       clk->parent = clk->ops->get_parent(clk);
+       spin_unlock_irqrestore(&clocks_lock, flags);
+       return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+static void __init sirfsoc_clk_init(void)
+{
+       clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks));
+}
+
+static struct of_device_id clkc_ids[] = {
+       { .compatible = "sirf,prima2-clkc" },
+};
+
+void __init sirfsoc_of_clk_init(void)
+{
+       struct device_node *np;
+       struct resource res;
+       struct map_desc sirfsoc_clkc_iodesc = {
+               .virtual = SIRFSOC_CLOCK_VA_BASE,
+               .type    = MT_DEVICE,
+       };
+
+       np = of_find_matching_node(NULL, clkc_ids);
+       if (!np)
+               panic("unable to find compatible clkc node in dtb\n");
+
+       if (of_address_to_resource(np, 0, &res))
+               panic("unable to find clkc range in dtb");
+       of_node_put(np);
+
+       sirfsoc_clkc_iodesc.pfn = __phys_to_pfn(res.start);
+       sirfsoc_clkc_iodesc.length = 1 + res.end - res.start;
+
+       iotable_init(&sirfsoc_clkc_iodesc, 1);
+
+       sirfsoc_clk_init();
+}
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h
new file mode 100644 (file)
index 0000000..83e5d21
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * This file contains common function prototypes to avoid externs in the c files.
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_PRIMA2_COMMON_H__
+#define __MACH_PRIMA2_COMMON_H__
+
+#include <linux/init.h>
+#include <asm/mach/time.h>
+
+extern struct sys_timer sirfsoc_timer;
+
+extern void __init sirfsoc_of_irq_init(void);
+extern void __init sirfsoc_of_clk_init(void);
+
+#ifndef CONFIG_DEBUG_LL
+static inline void sirfsoc_map_lluart(void)  {}
+#else
+extern void __init sirfsoc_map_lluart(void);
+#endif
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/clkdev.h b/arch/arm/mach-prima2/include/mach/clkdev.h
new file mode 100644 (file)
index 0000000..6693251
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * arch/arm/mach-prima2/include/mach/clkdev.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/debug-macro.S b/arch/arm/mach-prima2/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..bf75106
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-prima2/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <mach/hardware.h>
+#include <mach/uart.h>
+
+       .macro  addruart, rp, rv
+       ldr     \rp, =SIRFSOC_UART1_PA_BASE             @ physical
+       ldr     \rv, =SIRFSOC_UART1_VA_BASE             @ virtual
+       .endm
+
+       .macro  senduart,rd,rx
+       str     \rd, [\rx, #SIRFSOC_UART_TXFIFO_DATA]
+       .endm
+
+       .macro  busyuart,rd,rx
+       .endm
+
+       .macro  waituart,rd,rx
+1001:  ldr     \rd, [\rx, #SIRFSOC_UART_TXFIFO_STATUS]
+       tst     \rd, #SIRFSOC_UART1_TXFIFO_EMPTY
+       beq     1001b
+       .endm
+
diff --git a/arch/arm/mach-prima2/include/mach/entry-macro.S b/arch/arm/mach-prima2/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..1c8a50f
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-prima2/include/mach/entry-macro.S
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <mach/hardware.h>
+
+#define SIRFSOC_INT_ID 0x38
+
+       .macro  get_irqnr_preamble, base, tmp
+       ldr     \base, =sirfsoc_intc_base
+       ldr     \base, [\base]
+       .endm
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+       ldr \irqnr, [\base, #SIRFSOC_INT_ID]    @ Get the highest priority irq
+       cmp \irqnr, #0x40                       @ the irq num can't be larger than 0x3f
+       movges \irqnr, #0
+       .endm
+
+       .macro  disable_fiq
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
diff --git a/arch/arm/mach-prima2/include/mach/hardware.h b/arch/arm/mach-prima2/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..105b969
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * arch/arm/mach-prima2/include/mach/hardware.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_HARDWARE_H__
+#define __MACH_HARDWARE_H__
+
+#include <asm/sizes.h>
+#include <mach/map.h>
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/io.h b/arch/arm/mach-prima2/include/mach/io.h
new file mode 100644 (file)
index 0000000..6c31e9e
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-prima2/include/mach/io.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_PRIMA2_IO_H
+#define __MACH_PRIMA2_IO_H
+
+#define IO_SPACE_LIMIT ((resource_size_t)0)
+
+#define __mem_pci(a)            (a)
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/irqs.h b/arch/arm/mach-prima2/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..bb354f9
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * arch/arm/mach-prima2/include/mach/irqs.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define SIRFSOC_INTENAL_IRQ_START  0
+#define SIRFSOC_INTENAL_IRQ_END    59
+
+#define NR_IRQS        220
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/map.h b/arch/arm/mach-prima2/include/mach/map.h
new file mode 100644 (file)
index 0000000..66b1ae2
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * memory & I/O static mapping definitions for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_PRIMA2_MAP_H__
+#define __MACH_PRIMA2_MAP_H__
+
+#include <mach/vmalloc.h>
+
+#define SIRFSOC_VA(x)                  (VMALLOC_END + ((x) & 0x00FFF000))
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/memory.h b/arch/arm/mach-prima2/include/mach/memory.h
new file mode 100644 (file)
index 0000000..368cd5a
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-prima2/include/mach/memory.h
+ *
+ * Copyright (c) 2010 – 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET        UL(0x00000000)
+
+/*
+ * Restrict DMA-able region to workaround silicon limitation.
+ * The limitation restricts buffers available for DMA to SD/MMC
+ * hardware to be below 256MB
+ */
+#define ARM_DMA_ZONE_SIZE      (SZ_256M)
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/system.h b/arch/arm/mach-prima2/include/mach/system.h
new file mode 100644 (file)
index 0000000..0dbd257
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-prima2/include/mach/system.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_SYSTEM_H__
+#define __MACH_SYSTEM_H__
+
+#include <linux/bitops.h>
+#include <mach/hardware.h>
+
+#define SIRFSOC_SYS_RST_BIT  BIT(31)
+
+extern void __iomem *sirfsoc_rstc_base;
+
+static inline void arch_idle(void)
+{
+       cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+       writel(SIRFSOC_SYS_RST_BIT, sirfsoc_rstc_base);
+}
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/timex.h b/arch/arm/mach-prima2/include/mach/timex.h
new file mode 100644 (file)
index 0000000..d6f98a7
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/mach-prima2/include/mach/timex.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_TIMEX_H__
+#define __MACH_TIMEX_H__
+
+#define CLOCK_TICK_RATE  1000000
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/uart.h b/arch/arm/mach-prima2/include/mach/uart.h
new file mode 100644 (file)
index 0000000..c98b4d5
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-prima2/include/mach/uart.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_PRIMA2_SIRFSOC_UART_H
+#define __MACH_PRIMA2_SIRFSOC_UART_H
+
+/* UART-1: used as serial debug port */
+#define SIRFSOC_UART1_PA_BASE          0xb0060000
+#define SIRFSOC_UART1_VA_BASE          SIRFSOC_VA(0x060000)
+#define SIRFSOC_UART1_SIZE             SZ_4K
+
+#define SIRFSOC_UART_TXFIFO_STATUS     0x0114
+#define SIRFSOC_UART_TXFIFO_DATA       0x0118
+
+#define SIRFSOC_UART1_TXFIFO_FULL                       (1 << 5)
+#define SIRFSOC_UART1_TXFIFO_EMPTY                     (1 << 6)
+
+#endif
diff --git a/arch/arm/mach-prima2/include/mach/uncompress.h b/arch/arm/mach-prima2/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..83125c6
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-prima2/include/mach/uncompress.h
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/uart.h>
+
+void arch_decomp_setup(void)
+{
+}
+
+#define arch_decomp_wdog()
+
+static __inline__ void putc(char c)
+{
+       /*
+        * during kernel decompression, all mappings are flat:
+        *  virt_addr == phys_addr
+        */
+       while (__raw_readl(SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS)
+               & SIRFSOC_UART1_TXFIFO_FULL)
+               barrier();
+
+       __raw_writel(c, SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_DATA);
+}
+
+static inline void flush(void)
+{
+}
+
+#endif
+
diff --git a/arch/arm/mach-prima2/include/mach/vmalloc.h b/arch/arm/mach-prima2/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..c9f90fe
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/ach-prima2/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2010 – 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __MACH_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#include <linux/const.h>
+
+#define VMALLOC_END    _AC(0xFEC00000, UL)
+
+#endif
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c
new file mode 100644 (file)
index 0000000..c3404cb
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * interrupt controller support for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define SIRFSOC_INT_RISC_MASK0          0x0018
+#define SIRFSOC_INT_RISC_MASK1          0x001C
+#define SIRFSOC_INT_RISC_LEVEL0         0x0020
+#define SIRFSOC_INT_RISC_LEVEL1         0x0024
+
+void __iomem *sirfsoc_intc_base;
+
+static __init void
+sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
+{
+       struct irq_chip_generic *gc;
+       struct irq_chip_type *ct;
+
+       gc = irq_alloc_generic_chip("SIRFINTC", 1, irq_start, base, handle_level_irq);
+       ct = gc->chip_types;
+
+       ct->chip.irq_mask = irq_gc_mask_clr_bit;
+       ct->chip.irq_unmask = irq_gc_mask_set_bit;
+       ct->regs.mask = SIRFSOC_INT_RISC_MASK0;
+
+       irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, 0);
+}
+
+static __init void sirfsoc_irq_init(void)
+{
+       sirfsoc_alloc_gc(sirfsoc_intc_base, 0, 32);
+       sirfsoc_alloc_gc(sirfsoc_intc_base + 4, 32, SIRFSOC_INTENAL_IRQ_END - 32);
+
+       writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0);
+       writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1);
+
+       writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK0);
+       writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1);
+}
+
+static struct of_device_id intc_ids[]  = {
+       { .compatible = "sirf,prima2-intc" },
+};
+
+void __init sirfsoc_of_irq_init(void)
+{
+       struct device_node *np;
+
+       np = of_find_matching_node(NULL, intc_ids);
+       if (!np)
+               panic("unable to find compatible intc node in dtb\n");
+
+       sirfsoc_intc_base = of_iomap(np, 0);
+       if (!sirfsoc_intc_base)
+               panic("unable to map intc cpu registers\n");
+
+       of_node_put(np);
+
+       sirfsoc_irq_init();
+}
diff --git a/arch/arm/mach-prima2/l2x0.c b/arch/arm/mach-prima2/l2x0.c
new file mode 100644 (file)
index 0000000..9cda205
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * l2 cache initialization for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <mach/memory.h>
+
+#define L2X0_ADDR_FILTERING_START       0xC00
+#define L2X0_ADDR_FILTERING_END         0xC04
+
+static struct of_device_id l2x_ids[]  = {
+       { .compatible = "arm,pl310-cache" },
+};
+
+static int __init sirfsoc_of_l2x_init(void)
+{
+       struct device_node *np;
+       void __iomem *sirfsoc_l2x_base;
+
+       np = of_find_matching_node(NULL, l2x_ids);
+       if (!np)
+               panic("unable to find compatible l2x node in dtb\n");
+
+       sirfsoc_l2x_base = of_iomap(np, 0);
+       if (!sirfsoc_l2x_base)
+               panic("unable to map l2x cpu registers\n");
+
+       of_node_put(np);
+
+       if (!(readl_relaxed(sirfsoc_l2x_base + L2X0_CTRL) & 1)) {
+               /*
+                * set the physical memory windows L2 cache will cover
+                */
+               writel_relaxed(PLAT_PHYS_OFFSET + 1024 * 1024 * 1024,
+                       sirfsoc_l2x_base + L2X0_ADDR_FILTERING_END);
+               writel_relaxed(PLAT_PHYS_OFFSET | 0x1,
+                       sirfsoc_l2x_base + L2X0_ADDR_FILTERING_START);
+
+               writel_relaxed(0,
+                       sirfsoc_l2x_base + L2X0_TAG_LATENCY_CTRL);
+               writel_relaxed(0,
+                       sirfsoc_l2x_base + L2X0_DATA_LATENCY_CTRL);
+       }
+       l2x0_init((void __iomem *)sirfsoc_l2x_base, 0x00040000,
+               0x00000000);
+
+       return 0;
+}
+early_initcall(sirfsoc_of_l2x_init);
diff --git a/arch/arm/mach-prima2/lluart.c b/arch/arm/mach-prima2/lluart.c
new file mode 100644 (file)
index 0000000..a89f9b3
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Static memory mapping for DEBUG_LL
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <mach/map.h>
+#include <mach/uart.h>
+
+void __init sirfsoc_map_lluart(void)
+{
+       struct map_desc sirfsoc_lluart_map = {
+               .virtual        = SIRFSOC_UART1_VA_BASE,
+               .pfn            = __phys_to_pfn(SIRFSOC_UART1_PA_BASE),
+               .length         = SIRFSOC_UART1_SIZE,
+               .type           = MT_DEVICE,
+       };
+
+       iotable_init(&sirfsoc_lluart_map, 1);
+}
diff --git a/arch/arm/mach-prima2/prima2.c b/arch/arm/mach-prima2/prima2.c
new file mode 100644 (file)
index 0000000..f57124b
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Defines machines for CSR SiRFprimaII 
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include "common.h"
+
+static struct of_device_id sirfsoc_of_bus_ids[] __initdata = {
+       { .compatible = "simple-bus", },
+       {},
+};
+
+void __init sirfsoc_mach_init(void)
+{
+       of_platform_bus_probe(NULL, sirfsoc_of_bus_ids, NULL);
+}
+
+static const char *prima2cb_dt_match[] __initdata = {
+       "sirf,prima2-cb",
+       NULL
+};
+
+MACHINE_START(PRIMA2_EVB, "prima2cb")
+       /* Maintainer: Barry Song <baohua.song@csr.com> */
+       .boot_params    = 0x00000100,
+       .init_early     = sirfsoc_of_clk_init,
+       .map_io         = sirfsoc_map_lluart,
+       .init_irq       = sirfsoc_of_irq_init,
+       .timer          = &sirfsoc_timer,
+       .init_machine   = sirfsoc_mach_init,
+       .dt_compat      = prima2cb_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c
new file mode 100644 (file)
index 0000000..d074786
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * reset controller for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+void __iomem *sirfsoc_rstc_base;
+static DEFINE_MUTEX(rstc_lock);
+
+static struct of_device_id rstc_ids[]  = {
+       { .compatible = "sirf,prima2-rstc" },
+};
+
+static int __init sirfsoc_of_rstc_init(void)
+{
+       struct device_node *np;
+
+       np = of_find_matching_node(NULL, rstc_ids);
+       if (!np)
+               panic("unable to find compatible rstc node in dtb\n");
+
+       sirfsoc_rstc_base = of_iomap(np, 0);
+       if (!sirfsoc_rstc_base)
+               panic("unable to map rstc cpu registers\n");
+
+       of_node_put(np);
+
+       return 0;
+}
+early_initcall(sirfsoc_of_rstc_init);
+
+int sirfsoc_reset_device(struct device *dev)
+{
+       const unsigned int *prop = of_get_property(dev->of_node, "reset-bit", NULL);
+       unsigned int reset_bit;
+
+       if (!prop)
+               return -ENODEV;
+
+       reset_bit = be32_to_cpup(prop);
+
+       mutex_lock(&rstc_lock);
+
+       /*
+        * Writing 1 to this bit resets corresponding block. Writing 0 to this
+        * bit de-asserts reset signal of the corresponding block.
+        * datasheet doesn't require explicit delay between the set and clear
+        * of reset bit. it could be shorter if tests pass.
+        */
+       writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit,
+               sirfsoc_rstc_base + (reset_bit / 32) * 4);
+       msleep(10);
+       writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit,
+               sirfsoc_rstc_base + (reset_bit / 32) * 4);
+
+       mutex_unlock(&rstc_lock);
+
+       return 0;
+}
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c
new file mode 100644 (file)
index 0000000..44027f3
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * System timer for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <mach/map.h>
+#include <asm/mach/time.h>
+
+#define SIRFSOC_TIMER_COUNTER_LO       0x0000
+#define SIRFSOC_TIMER_COUNTER_HI       0x0004
+#define SIRFSOC_TIMER_MATCH_0          0x0008
+#define SIRFSOC_TIMER_MATCH_1          0x000C
+#define SIRFSOC_TIMER_MATCH_2          0x0010
+#define SIRFSOC_TIMER_MATCH_3          0x0014
+#define SIRFSOC_TIMER_MATCH_4          0x0018
+#define SIRFSOC_TIMER_MATCH_5          0x001C
+#define SIRFSOC_TIMER_STATUS           0x0020
+#define SIRFSOC_TIMER_INT_EN           0x0024
+#define SIRFSOC_TIMER_WATCHDOG_EN      0x0028
+#define SIRFSOC_TIMER_DIV              0x002C
+#define SIRFSOC_TIMER_LATCH            0x0030
+#define SIRFSOC_TIMER_LATCHED_LO       0x0034
+#define SIRFSOC_TIMER_LATCHED_HI       0x0038
+
+#define SIRFSOC_TIMER_WDT_INDEX                5
+
+#define SIRFSOC_TIMER_LATCH_BIT         BIT(0)
+
+static void __iomem *sirfsoc_timer_base;
+static void __init sirfsoc_of_timer_map(void);
+
+/* timer0 interrupt handler */
+static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *ce = dev_id;
+
+       WARN_ON(!(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_STATUS) & BIT(0)));
+
+       /* clear timer0 interrupt */
+       writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
+
+       ce->event_handler(ce);
+
+       return IRQ_HANDLED;
+}
+
+/* read 64-bit timer counter */
+static cycle_t sirfsoc_timer_read(struct clocksource *cs)
+{
+       u64 cycles;
+
+       /* latch the 64-bit timer counter */
+       writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
+       cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_HI);
+       cycles = (cycles << 32) | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
+
+       return cycles;
+}
+
+static int sirfsoc_timer_set_next_event(unsigned long delta,
+       struct clock_event_device *ce)
+{
+       unsigned long now, next;
+
+       writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
+       now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
+       next = now + delta;
+       writel_relaxed(next, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0);
+       writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH);
+       now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO);
+
+       return next - now > delta ? -ETIME : 0;
+}
+
+static void sirfsoc_timer_set_mode(enum clock_event_mode mode,
+       struct clock_event_device *ce)
+{
+       u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               WARN_ON(1);
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               writel_relaxed(val | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
+               break;
+       case CLOCK_EVT_MODE_SHUTDOWN:
+               writel_relaxed(val & ~BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
+               break;
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+}
+
+static struct clock_event_device sirfsoc_clockevent = {
+       .name = "sirfsoc_clockevent",
+       .rating = 200,
+       .features = CLOCK_EVT_FEAT_ONESHOT,
+       .set_mode = sirfsoc_timer_set_mode,
+       .set_next_event = sirfsoc_timer_set_next_event,
+};
+
+static struct clocksource sirfsoc_clocksource = {
+       .name = "sirfsoc_clocksource",
+       .rating = 200,
+       .mask = CLOCKSOURCE_MASK(64),
+       .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+       .read = sirfsoc_timer_read,
+};
+
+static struct irqaction sirfsoc_timer_irq = {
+       .name = "sirfsoc_timer0",
+       .flags = IRQF_TIMER,
+       .irq = 0,
+       .handler = sirfsoc_timer_interrupt,
+       .dev_id = &sirfsoc_clockevent,
+};
+
+/* Overwrite weak default sched_clock with more precise one */
+unsigned long long notrace sched_clock(void)
+{
+       static int is_mapped = 0;
+
+       /*
+        * sched_clock is called earlier than .init of sys_timer
+        * if we map timer memory in .init of sys_timer, system
+        * will panic due to illegal memory access
+        */
+       if(!is_mapped) {
+               sirfsoc_of_timer_map();
+               is_mapped = 1;
+       }
+
+       return sirfsoc_timer_read(NULL) * (NSEC_PER_SEC / CLOCK_TICK_RATE);
+}
+
+static void __init sirfsoc_clockevent_init(void)
+{
+       clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60);
+
+       sirfsoc_clockevent.max_delta_ns =
+               clockevent_delta2ns(-2, &sirfsoc_clockevent);
+       sirfsoc_clockevent.min_delta_ns =
+               clockevent_delta2ns(2, &sirfsoc_clockevent);
+
+       sirfsoc_clockevent.cpumask = cpumask_of(0);
+       clockevents_register_device(&sirfsoc_clockevent);
+}
+
+/* initialize the kernel jiffy timer source */
+static void __init sirfsoc_timer_init(void)
+{
+       unsigned long rate;
+
+       /* timer's input clock is io clock */
+       struct clk *clk = clk_get_sys("io", NULL);
+
+       BUG_ON(IS_ERR(clk));
+
+       rate = clk_get_rate(clk);
+
+       BUG_ON(rate < CLOCK_TICK_RATE);
+       BUG_ON(rate % CLOCK_TICK_RATE);
+
+       writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV);
+       writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
+       writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
+       writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
+
+       BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
+
+       BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
+
+       sirfsoc_clockevent_init();
+}
+
+static struct of_device_id timer_ids[] = {
+       { .compatible = "sirf,prima2-tick" },
+};
+
+static void __init sirfsoc_of_timer_map(void)
+{
+       struct device_node *np;
+       const unsigned int *intspec;
+
+       np = of_find_matching_node(NULL, timer_ids);
+       if (!np)
+               panic("unable to find compatible timer node in dtb\n");
+       sirfsoc_timer_base = of_iomap(np, 0);
+       if (!sirfsoc_timer_base)
+               panic("unable to map timer cpu registers\n");
+
+       /* Get the interrupts property */
+       intspec = of_get_property(np, "interrupts", NULL);
+       BUG_ON(!intspec);
+       sirfsoc_timer_irq.irq = be32_to_cpup(intspec);
+
+       of_node_put(np);
+}
+
+struct sys_timer sirfsoc_timer = {
+       .init = sirfsoc_timer_init,
+};
diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile
new file mode 100644 (file)
index 0000000..c550c67
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y                          := common.o timer.o board_dt.o
diff --git a/arch/arm/mach-zynq/Makefile.boot b/arch/arm/mach-zynq/Makefile.boot
new file mode 100644 (file)
index 0000000..67039c3
--- /dev/null
@@ -0,0 +1,3 @@
+   zreladdr-y  := 0x00008000
+params_phys-y  := 0x00000100
+initrd_phys-y  := 0x00800000
diff --git a/arch/arm/mach-zynq/board_dt.c b/arch/arm/mach-zynq/board_dt.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
new file mode 100644 (file)
index 0000000..73e9368
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * This file contains common code that is intended to be used across
+ * boards so that it's not replicated.
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/cpumask.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/of.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <mach/zynq_soc.h>
+#include <mach/clkdev.h>
+#include "common.h"
+
+static struct of_device_id zynq_of_bus_ids[] __initdata = {
+       { .compatible = "simple-bus", },
+       {}
+};
+
+/**
+ * xilinx_init_machine() - System specific initialization, intended to be
+ *                        called from board specific initialization.
+ */
+static void __init xilinx_init_machine(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+       /*
+        * 64KB way size, 8-way associativity, parity disabled
+        */
+       l2x0_init(PL310_L2CC_BASE, 0x02060000, 0xF0F0FFFF);
+#endif
+
+       of_platform_bus_probe(NULL, zynq_of_bus_ids, NULL);
+}
+
+/**
+ * xilinx_irq_init() - Interrupt controller initialization for the GIC.
+ */
+static void __init xilinx_irq_init(void)
+{
+       gic_init(0, 29, SCU_GIC_DIST_BASE, SCU_GIC_CPU_BASE);
+}
+
+/* The minimum devices needed to be mapped before the VM system is up and
+ * running include the GIC, UART and Timer Counter.
+ */
+
+static struct map_desc io_desc[] __initdata = {
+       {
+               .virtual        = TTC0_VIRT,
+               .pfn            = __phys_to_pfn(TTC0_PHYS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = SCU_PERIPH_VIRT,
+               .pfn            = __phys_to_pfn(SCU_PERIPH_PHYS),
+               .length         = SZ_8K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = PL310_L2CC_VIRT,
+               .pfn            = __phys_to_pfn(PL310_L2CC_PHYS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+
+#ifdef CONFIG_DEBUG_LL
+       {
+               .virtual        = UART0_VIRT,
+               .pfn            = __phys_to_pfn(UART0_PHYS),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+#endif
+
+};
+
+/**
+ * xilinx_map_io() - Create memory mappings needed for early I/O.
+ */
+static void __init xilinx_map_io(void)
+{
+       iotable_init(io_desc, ARRAY_SIZE(io_desc));
+}
+
+static const char *xilinx_dt_match[] = {
+       "xlnx,zynq-ep107",
+       NULL
+};
+
+MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
+       .map_io         = xilinx_map_io,
+       .init_irq       = xilinx_irq_init,
+       .init_machine   = xilinx_init_machine,
+       .timer          = &xttcpss_sys_timer,
+       .dt_compat      = xilinx_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-zynq/common.h b/arch/arm/mach-zynq/common.h
new file mode 100644 (file)
index 0000000..a009644
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * This file contains common function prototypes to avoid externs
+ * in the c files.
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_ZYNQ_COMMON_H__
+#define __MACH_ZYNQ_COMMON_H__
+
+#include <asm/mach/time.h>
+
+extern struct sys_timer xttcpss_sys_timer;
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/clkdev.h b/arch/arm/mach-zynq/include/mach/clkdev.h
new file mode 100644 (file)
index 0000000..c6e73d8
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-zynq/include/mach/clkdev.h
+ *
+ *  Copyright (C) 2011 Xilinx, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_CLKDEV_H__
+#define __MACH_CLKDEV_H__
+
+#include <plat/clock.h>
+
+struct clk {
+       unsigned long           rate;
+       const struct clk_ops    *ops;
+       const struct icst_params *params;
+       void __iomem            *vcoreg;
+};
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/debug-macro.S b/arch/arm/mach-zynq/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..9f664d5
--- /dev/null
@@ -0,0 +1,36 @@
+/* arch/arm/mach-zynq/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <mach/zynq_soc.h>
+#include <mach/uart.h>
+
+               .macro  addruart, rp, rv
+               ldr     \rp, =LL_UART_PADDR     @ physical
+               ldr     \rv, =LL_UART_VADDR     @ virtual
+               .endm
+
+               .macro  senduart,rd,rx
+               str     \rd, [\rx, #UART_FIFO_OFFSET]   @ TXDATA
+               .endm
+
+               .macro  waituart,rd,rx
+               .endm
+
+               .macro  busyuart,rd,rx
+1002:          ldr     \rd, [\rx, #UART_SR_OFFSET]     @ get status register
+               tst     \rd, #UART_SR_TXFULL            @
+               bne     1002b                   @ wait if FIFO is full
+               .endm
diff --git a/arch/arm/mach-zynq/include/mach/entry-macro.S b/arch/arm/mach-zynq/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..3cfc01b
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * arch/arm/mach-zynq/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * based on arch/plat-mxc/include/mach/entry-macro.S
+ *
+ *  Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
+ *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <mach/hardware.h>
+#include <asm/hardware/entry-macro-gic.S>
+
+               .macro  disable_fiq
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
diff --git a/arch/arm/mach-zynq/include/mach/hardware.h b/arch/arm/mach-zynq/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..d558d8a
--- /dev/null
@@ -0,0 +1,18 @@
+/* arch/arm/mach-zynq/include/mach/hardware.h
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_HARDWARE_H__
+#define __MACH_HARDWARE_H__
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/io.h b/arch/arm/mach-zynq/include/mach/io.h
new file mode 100644 (file)
index 0000000..39d9885
--- /dev/null
@@ -0,0 +1,33 @@
+/* arch/arm/mach-zynq/include/mach/io.h
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_IO_H__
+#define __MACH_IO_H__
+
+/* Allow IO space to be anywhere in the memory */
+
+#define IO_SPACE_LIMIT 0xffff
+
+/* IO address mapping macros, nothing special at this time but required */
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x)               (x)
+#else
+#define IOMEM(x)               ((void __force __iomem *)(x))
+#endif
+
+#define __io(a)                        __typesafe_io(a)
+#define __mem_pci(a)           (a)
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/irqs.h b/arch/arm/mach-zynq/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..5fb04fd
--- /dev/null
@@ -0,0 +1,21 @@
+/* arch/arm/mach-zynq/include/mach/irqs.h
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+#define ARCH_NR_GPIOS  118
+#define NR_IRQS                (128 + ARCH_NR_GPIOS)
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/memory.h b/arch/arm/mach-zynq/include/mach/memory.h
new file mode 100644 (file)
index 0000000..35a9263
--- /dev/null
@@ -0,0 +1,22 @@
+/* arch/arm/mach-zynq/include/mach/memory.h
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_MEMORY_H__
+#define __MACH_MEMORY_H__
+
+#include <asm/sizes.h>
+
+#define PLAT_PHYS_OFFSET       UL(0x0)
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/system.h b/arch/arm/mach-zynq/include/mach/system.h
new file mode 100644 (file)
index 0000000..1b84d70
--- /dev/null
@@ -0,0 +1,28 @@
+/* arch/arm/mach-zynq/include/mach/system.h
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_SYSTEM_H__
+#define __MACH_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+       cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+       /* Add architecture specific reset processing here */
+}
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/timex.h b/arch/arm/mach-zynq/include/mach/timex.h
new file mode 100644 (file)
index 0000000..6c0245e
--- /dev/null
@@ -0,0 +1,23 @@
+/* arch/arm/mach-zynq/include/mach/timex.h
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_TIMEX_H__
+#define __MACH_TIMEX_H__
+
+/* the following is needed for the system to build but will be removed
+   in the future, the value is not important but won't hurt
+*/
+#define CLOCK_TICK_RATE        (100 * HZ)
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/uart.h b/arch/arm/mach-zynq/include/mach/uart.h
new file mode 100644 (file)
index 0000000..5c47c97
--- /dev/null
@@ -0,0 +1,25 @@
+/* arch/arm/mach-zynq/include/mach/uart.h
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_UART_H__
+#define __MACH_UART_H__
+
+#define UART_CR_OFFSET         0x00  /* Control Register [8:0] */
+#define UART_SR_OFFSET         0x2C  /* Channel Status [11:0] */
+#define UART_FIFO_OFFSET       0x30  /* FIFO [15:0] or [7:0] */
+
+#define UART_SR_TXFULL         0x00000010      /* TX FIFO full */
+#define UART_SR_TXEMPTY                0x00000008      /* TX FIFO empty */
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/uncompress.h b/arch/arm/mach-zynq/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..af4e844
--- /dev/null
@@ -0,0 +1,51 @@
+/* arch/arm/mach-zynq/include/mach/uncompress.h
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H__
+#define __MACH_UNCOMPRESS_H__
+
+#include <linux/io.h>
+#include <asm/processor.h>
+#include <mach/zynq_soc.h>
+#include <mach/uart.h>
+
+void arch_decomp_setup(void)
+{
+}
+
+static inline void flush(void)
+{
+       /*
+        * Wait while the FIFO is not empty
+        */
+       while (!(__raw_readl(IOMEM(LL_UART_PADDR + UART_SR_OFFSET)) &
+               UART_SR_TXEMPTY))
+               cpu_relax();
+}
+
+#define arch_decomp_wdog()
+
+static void putc(char ch)
+{
+       /*
+        * Wait for room in the FIFO, then write the char into the FIFO
+        */
+       while (__raw_readl(IOMEM(LL_UART_PADDR + UART_SR_OFFSET)) &
+               UART_SR_TXFULL)
+               cpu_relax();
+
+       __raw_writel(ch, IOMEM(LL_UART_PADDR + UART_FIFO_OFFSET));
+}
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/vmalloc.h b/arch/arm/mach-zynq/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..2398eff
--- /dev/null
@@ -0,0 +1,20 @@
+/* arch/arm/mach-zynq/include/mach/vmalloc.h
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_VMALLOC_H__
+#define __MACH_VMALLOC_H__
+
+#define VMALLOC_END       0xE0000000UL
+
+#endif
diff --git a/arch/arm/mach-zynq/include/mach/zynq_soc.h b/arch/arm/mach-zynq/include/mach/zynq_soc.h
new file mode 100644 (file)
index 0000000..d0d3f8f
--- /dev/null
@@ -0,0 +1,48 @@
+/* arch/arm/mach-zynq/include/mach/zynq_soc.h
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_XILINX_SOC_H__
+#define __MACH_XILINX_SOC_H__
+
+#define PERIPHERAL_CLOCK_RATE          2500000
+
+/* For now, all mappings are flat (physical = virtual)
+ */
+#define UART0_PHYS                     0xE0000000
+#define UART0_VIRT                     UART0_PHYS
+
+#define TTC0_PHYS                      0xF8001000
+#define TTC0_VIRT                      TTC0_PHYS
+
+#define PL310_L2CC_PHYS                        0xF8F02000
+#define PL310_L2CC_VIRT                        PL310_L2CC_PHYS
+
+#define SCU_PERIPH_PHYS                        0xF8F00000
+#define SCU_PERIPH_VIRT                        SCU_PERIPH_PHYS
+
+/* The following are intended for the devices that are mapped early */
+
+#define TTC0_BASE                      IOMEM(TTC0_VIRT)
+#define SCU_PERIPH_BASE                        IOMEM(SCU_PERIPH_VIRT)
+#define SCU_GIC_CPU_BASE               (SCU_PERIPH_BASE + 0x100)
+#define SCU_GIC_DIST_BASE              (SCU_PERIPH_BASE + 0x1000)
+#define PL310_L2CC_BASE                        IOMEM(PL310_L2CC_VIRT)
+
+/*
+ * Mandatory for CONFIG_LL_DEBUG, UART is mapped virtual = physical
+ */
+#define LL_UART_PADDR  UART0_PHYS
+#define LL_UART_VADDR  UART0_VIRT
+
+#endif
diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c
new file mode 100644 (file)
index 0000000..c2c96cc
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * This file contains driver for the Xilinx PS Timer Counter IP.
+ *
+ *  Copyright (C) 2011 Xilinx
+ *
+ * based on arch/mips/kernel/time.c timer driver
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+
+#include <asm/mach/time.h>
+#include <mach/zynq_soc.h>
+#include "common.h"
+
+#define IRQ_TIMERCOUNTER0      42
+
+/*
+ * This driver configures the 2 16-bit count-up timers as follows:
+ *
+ * T1: Timer 1, clocksource for generic timekeeping
+ * T2: Timer 2, clockevent source for hrtimers
+ * T3: Timer 3, <unused>
+ *
+ * The input frequency to the timer module for emulation is 2.5MHz which is
+ * common to all the timer channels (T1, T2, and T3). With a pre-scaler of 32,
+ * the timers are clocked at 78.125KHz (12.8 us resolution).
+ *
+ * The input frequency to the timer module in silicon will be 200MHz. With the
+ * pre-scaler of 32, the timers are clocked at 6.25MHz (160ns resolution).
+ */
+#define XTTCPSS_CLOCKSOURCE    0       /* Timer 1 as a generic timekeeping */
+#define XTTCPSS_CLOCKEVENT     1       /* Timer 2 as a clock event */
+
+#define XTTCPSS_TIMER_BASE             TTC0_BASE
+#define XTTCPCC_EVENT_TIMER_IRQ                (IRQ_TIMERCOUNTER0 + 1)
+/*
+ * Timer Register Offset Definitions of Timer 1, Increment base address by 4
+ * and use same offsets for Timer 2
+ */
+#define XTTCPSS_CLK_CNTRL_OFFSET       0x00 /* Clock Control Reg, RW */
+#define XTTCPSS_CNT_CNTRL_OFFSET       0x0C /* Counter Control Reg, RW */
+#define XTTCPSS_COUNT_VAL_OFFSET       0x18 /* Counter Value Reg, RO */
+#define XTTCPSS_INTR_VAL_OFFSET                0x24 /* Interval Count Reg, RW */
+#define XTTCPSS_MATCH_1_OFFSET         0x30 /* Match 1 Value Reg, RW */
+#define XTTCPSS_MATCH_2_OFFSET         0x3C /* Match 2 Value Reg, RW */
+#define XTTCPSS_MATCH_3_OFFSET         0x48 /* Match 3 Value Reg, RW */
+#define XTTCPSS_ISR_OFFSET             0x54 /* Interrupt Status Reg, RO */
+#define XTTCPSS_IER_OFFSET             0x60 /* Interrupt Enable Reg, RW */
+
+#define XTTCPSS_CNT_CNTRL_DISABLE_MASK 0x1
+
+/* Setup the timers to use pre-scaling */
+
+#define TIMER_RATE (PERIPHERAL_CLOCK_RATE / 32)
+
+/**
+ * struct xttcpss_timer - This definition defines local timer structure
+ *
+ * @base_addr: Base address of timer
+ **/
+struct xttcpss_timer {
+       void __iomem *base_addr;
+};
+
+static struct xttcpss_timer timers[2];
+static struct clock_event_device xttcpss_clockevent;
+
+/**
+ * xttcpss_set_interval - Set the timer interval value
+ *
+ * @timer:     Pointer to the timer instance
+ * @cycles:    Timer interval ticks
+ **/
+static void xttcpss_set_interval(struct xttcpss_timer *timer,
+                                       unsigned long cycles)
+{
+       u32 ctrl_reg;
+
+       /* Disable the counter, set the counter value  and re-enable counter */
+       ctrl_reg = __raw_readl(timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
+       ctrl_reg |= XTTCPSS_CNT_CNTRL_DISABLE_MASK;
+       __raw_writel(ctrl_reg, timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
+
+       __raw_writel(cycles, timer->base_addr + XTTCPSS_INTR_VAL_OFFSET);
+
+       /* Reset the counter (0x10) so that it starts from 0, one-shot
+          mode makes this needed for timing to be right. */
+       ctrl_reg |= 0x10;
+       ctrl_reg &= ~XTTCPSS_CNT_CNTRL_DISABLE_MASK;
+       __raw_writel(ctrl_reg, timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
+}
+
+/**
+ * xttcpss_clock_event_interrupt - Clock event timer interrupt handler
+ *
+ * @irq:       IRQ number of the Timer
+ * @dev_id:    void pointer to the xttcpss_timer instance
+ *
+ * returns: Always IRQ_HANDLED - success
+ **/
+static irqreturn_t xttcpss_clock_event_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = &xttcpss_clockevent;
+       struct xttcpss_timer *timer = dev_id;
+
+       /* Acknowledge the interrupt and call event handler */
+       __raw_writel(__raw_readl(timer->base_addr + XTTCPSS_ISR_OFFSET),
+                       timer->base_addr + XTTCPSS_ISR_OFFSET);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction event_timer_irq = {
+       .name   = "xttcpss clockevent",
+       .flags  = IRQF_DISABLED | IRQF_TIMER,
+       .handler = xttcpss_clock_event_interrupt,
+};
+
+/**
+ * xttcpss_timer_hardware_init - Initialize the timer hardware
+ *
+ * Initialize the hardware to start the clock source, get the clock
+ * event timer ready to use, and hook up the interrupt.
+ **/
+static void __init xttcpss_timer_hardware_init(void)
+{
+       /* Setup the clock source counter to be an incrementing counter
+        * with no interrupt and it rolls over at 0xFFFF. Pre-scale
+          it by 32 also. Let it start running now.
+        */
+       timers[XTTCPSS_CLOCKSOURCE].base_addr = XTTCPSS_TIMER_BASE;
+
+       __raw_writel(0x0, timers[XTTCPSS_CLOCKSOURCE].base_addr +
+                               XTTCPSS_IER_OFFSET);
+       __raw_writel(0x9, timers[XTTCPSS_CLOCKSOURCE].base_addr +
+                               XTTCPSS_CLK_CNTRL_OFFSET);
+       __raw_writel(0x10, timers[XTTCPSS_CLOCKSOURCE].base_addr +
+                               XTTCPSS_CNT_CNTRL_OFFSET);
+
+       /* Setup the clock event timer to be an interval timer which
+        * is prescaled by 32 using the interval interrupt. Leave it
+        * disabled for now.
+        */
+
+       timers[XTTCPSS_CLOCKEVENT].base_addr = XTTCPSS_TIMER_BASE + 4;
+
+       __raw_writel(0x23, timers[XTTCPSS_CLOCKEVENT].base_addr +
+                       XTTCPSS_CNT_CNTRL_OFFSET);
+       __raw_writel(0x9, timers[XTTCPSS_CLOCKEVENT].base_addr +
+                       XTTCPSS_CLK_CNTRL_OFFSET);
+       __raw_writel(0x1, timers[XTTCPSS_CLOCKEVENT].base_addr +
+                       XTTCPSS_IER_OFFSET);
+
+       /* Setup IRQ the clock event timer */
+       event_timer_irq.dev_id = &timers[XTTCPSS_CLOCKEVENT];
+       setup_irq(XTTCPCC_EVENT_TIMER_IRQ, &event_timer_irq);
+}
+
+/**
+ * __raw_readl_cycles - Reads the timer counter register
+ *
+ * returns: Current timer counter register value
+ **/
+static cycle_t __raw_readl_cycles(struct clocksource *cs)
+{
+       struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKSOURCE];
+
+       return (cycle_t)__raw_readl(timer->base_addr +
+                               XTTCPSS_COUNT_VAL_OFFSET);
+}
+
+
+/*
+ * Instantiate and initialize the clock source structure
+ */
+static struct clocksource clocksource_xttcpss = {
+       .name           = "xttcpss_timer1",
+       .rating         = 200,                  /* Reasonable clock source */
+       .read           = __raw_readl_cycles,
+       .mask           = CLOCKSOURCE_MASK(16),
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+
+/**
+ * xttcpss_set_next_event - Sets the time interval for next event
+ *
+ * @cycles:    Timer interval ticks
+ * @evt:       Address of clock event instance
+ *
+ * returns: Always 0 - success
+ **/
+static int xttcpss_set_next_event(unsigned long cycles,
+                                       struct clock_event_device *evt)
+{
+       struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT];
+
+       xttcpss_set_interval(timer, cycles);
+       return 0;
+}
+
+/**
+ * xttcpss_set_mode - Sets the mode of timer
+ *
+ * @mode:      Mode to be set
+ * @evt:       Address of clock event instance
+ **/
+static void xttcpss_set_mode(enum clock_event_mode mode,
+                                       struct clock_event_device *evt)
+{
+       struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT];
+       u32 ctrl_reg;
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               xttcpss_set_interval(timer, TIMER_RATE / HZ);
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+               ctrl_reg = __raw_readl(timer->base_addr +
+                                       XTTCPSS_CNT_CNTRL_OFFSET);
+               ctrl_reg |= XTTCPSS_CNT_CNTRL_DISABLE_MASK;
+               __raw_writel(ctrl_reg,
+                               timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
+               break;
+       case CLOCK_EVT_MODE_RESUME:
+               ctrl_reg = __raw_readl(timer->base_addr +
+                                       XTTCPSS_CNT_CNTRL_OFFSET);
+               ctrl_reg &= ~XTTCPSS_CNT_CNTRL_DISABLE_MASK;
+               __raw_writel(ctrl_reg,
+                               timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
+               break;
+       }
+}
+
+/*
+ * Instantiate and initialize the clock event structure
+ */
+static struct clock_event_device xttcpss_clockevent = {
+       .name           = "xttcpss_timer2",
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .set_next_event = xttcpss_set_next_event,
+       .set_mode       = xttcpss_set_mode,
+       .rating         = 200,
+};
+
+/**
+ * xttcpss_timer_init - Initialize the timer
+ *
+ * Initializes the timer hardware and register the clock source and clock event
+ * timers with Linux kernal timer framework
+ **/
+static void __init xttcpss_timer_init(void)
+{
+       xttcpss_timer_hardware_init();
+       clocksource_register_hz(&clocksource_xttcpss, TIMER_RATE);
+
+       /* Calculate the parameters to allow the clockevent to operate using
+          integer math
+       */
+       clockevents_calc_mult_shift(&xttcpss_clockevent, TIMER_RATE, 4);
+
+       xttcpss_clockevent.max_delta_ns =
+               clockevent_delta2ns(0xfffe, &xttcpss_clockevent);
+       xttcpss_clockevent.min_delta_ns =
+               clockevent_delta2ns(1, &xttcpss_clockevent);
+
+       /* Indicate that clock event is on 1st CPU as SMP boot needs it */
+
+       xttcpss_clockevent.cpumask = cpumask_of(0);
+       clockevents_register_device(&xttcpss_clockevent);
+}
+
+/*
+ * Instantiate and initialize the system timer structure
+ */
+struct sys_timer xttcpss_sys_timer = {
+       .init           = xttcpss_timer_init,
+};
index 0074b8d..a0ea584 100644 (file)
@@ -821,7 +821,8 @@ config CACHE_L2X0
        depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
                   REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \
                   ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \
-                  ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE
+                  ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \
+                  ARCH_PRIMA2 || ARCH_ZYNQ
        default y
        select OUTER_CACHE
        select OUTER_CACHE_SYNC
index f1899a3..387a963 100644 (file)
@@ -39,6 +39,7 @@ struct omap_clk {
 #define CK_36XX                (1 << 10)       /* 36xx/37xx-specific clocks */
 #define CK_443X                (1 << 11)
 #define CK_TI816X      (1 << 12)
+#define CK_446X                (1 << 13)
 
 
 #define CK_34XX                (CK_3430ES1 | CK_3430ES2PLUS)
index f57e064..df4b968 100644 (file)
@@ -58,10 +58,12 @@ struct clkops {
 #define RATE_IN_36XX           (1 << 4)
 #define RATE_IN_4430           (1 << 5)
 #define RATE_IN_TI816X         (1 << 6)
+#define RATE_IN_4460           (1 << 7)
 
 #define RATE_IN_24XX           (RATE_IN_242X | RATE_IN_243X)
 #define RATE_IN_34XX           (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS)
 #define RATE_IN_3XXX           (RATE_IN_34XX | RATE_IN_36XX)
+#define RATE_IN_44XX           (RATE_IN_4430 | RATE_IN_4460)
 
 /* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */
 #define RATE_IN_3430ES2PLUS_36XX       (RATE_IN_3430ES2PLUS | RATE_IN_36XX)
index 8198bb6..67b3d75 100644 (file)
@@ -88,6 +88,7 @@ unsigned int omap_rev(void);
  * cpu_is_omap243x():  True for OMAP2430
  * cpu_is_omap343x():  True for OMAP3430
  * cpu_is_omap443x():  True for OMAP4430
+ * cpu_is_omap446x():  True for OMAP4460
  */
 #define GET_OMAP_CLASS (omap_rev() & 0xff)
 
@@ -123,6 +124,7 @@ IS_OMAP_SUBCLASS(243x, 0x243)
 IS_OMAP_SUBCLASS(343x, 0x343)
 IS_OMAP_SUBCLASS(363x, 0x363)
 IS_OMAP_SUBCLASS(443x, 0x443)
+IS_OMAP_SUBCLASS(446x, 0x446)
 
 IS_TI_SUBCLASS(816x, 0x816)
 
@@ -137,6 +139,7 @@ IS_TI_SUBCLASS(816x, 0x816)
 #define cpu_is_ti816x()                        0
 #define cpu_is_omap44xx()              0
 #define cpu_is_omap443x()              0
+#define cpu_is_omap446x()              0
 
 #if defined(MULTI_OMAP1)
 # if defined(CONFIG_ARCH_OMAP730)
@@ -361,8 +364,10 @@ IS_OMAP_TYPE(3517, 0x3517)
 # if defined(CONFIG_ARCH_OMAP4)
 # undef cpu_is_omap44xx
 # undef cpu_is_omap443x
+# undef cpu_is_omap446x
 # define cpu_is_omap44xx()             is_omap44xx()
 # define cpu_is_omap443x()             is_omap443x()
+# define cpu_is_omap446x()             is_omap446x()
 # endif
 
 /* Macros to detect if we have OMAP1 or OMAP2 */
@@ -410,6 +415,9 @@ IS_OMAP_TYPE(3517, 0x3517)
 #define OMAP4430_REV_ES2_1     (OMAP443X_CLASS | (0x21 << 8))
 #define OMAP4430_REV_ES2_2     (OMAP443X_CLASS | (0x22 << 8))
 
+#define OMAP446X_CLASS         0x44600044
+#define OMAP4460_REV_ES1_0     (OMAP446X_CLASS | (0x10 << 8))
+
 /*
  * omap_chip bits
  *
@@ -439,13 +447,15 @@ IS_OMAP_TYPE(3517, 0x3517)
 #define CHIP_IS_OMAP4430ES2_1          (1 << 12)
 #define CHIP_IS_OMAP4430ES2_2          (1 << 13)
 #define CHIP_IS_TI816X                 (1 << 14)
+#define CHIP_IS_OMAP4460ES1_0          (1 << 15)
 
 #define CHIP_IS_OMAP24XX               (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
 
 #define CHIP_IS_OMAP4430               (CHIP_IS_OMAP4430ES1 |          \
                                         CHIP_IS_OMAP4430ES2 |          \
                                         CHIP_IS_OMAP4430ES2_1 |        \
-                                        CHIP_IS_OMAP4430ES2_2)
+                                        CHIP_IS_OMAP4430ES2_2 |        \
+                                        CHIP_IS_OMAP4460ES1_0)
 
 /*
  * "GE" here represents "greater than or equal to" in terms of ES
@@ -468,7 +478,7 @@ void omap2_check_revision(void);
 /*
  * Runtime detection of OMAP3 features
  */
-extern u32 omap3_features;
+extern u32 omap_features;
 
 #define OMAP3_HAS_L2CACHE              BIT(0)
 #define OMAP3_HAS_IVA                  BIT(1)
@@ -478,11 +488,15 @@ extern u32 omap3_features;
 #define OMAP3_HAS_192MHZ_CLK           BIT(5)
 #define OMAP3_HAS_IO_WAKEUP            BIT(6)
 #define OMAP3_HAS_SDRC                 BIT(7)
+#define OMAP4_HAS_MPU_1GHZ             BIT(8)
+#define OMAP4_HAS_MPU_1_2GHZ           BIT(9)
+#define OMAP4_HAS_MPU_1_5GHZ           BIT(10)
+
 
 #define OMAP3_HAS_FEATURE(feat,flag)                   \
 static inline unsigned int omap3_has_ ##feat(void)     \
 {                                                      \
-       return (omap3_features & OMAP3_HAS_ ##flag);    \
+       return omap_features & OMAP3_HAS_ ##flag;       \
 }                                                      \
 
 OMAP3_HAS_FEATURE(l2cache, L2CACHE)
@@ -494,4 +508,19 @@ OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
 OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
 OMAP3_HAS_FEATURE(sdrc, SDRC)
 
+/*
+ * Runtime detection of OMAP4 features
+ */
+extern u32 omap_features;
+
+#define OMAP4_HAS_FEATURE(feat, flag)                  \
+static inline unsigned int omap4_has_ ##feat(void)     \
+{                                                      \
+       return omap_features & OMAP4_HAS_ ##flag;       \
+}                                                      \
+
+OMAP4_HAS_FEATURE(mpu_1ghz, MPU_1GHZ)
+OMAP4_HAS_FEATURE(mpu_1_2ghz, MPU_1_2GHZ)
+OMAP4_HAS_FEATURE(mpu_1_5ghz, MPU_1_5GHZ)
+
 #endif