From c291f76d24a4190551a42b7b77a2cfeb3f4d36f9 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 11 Feb 2015 10:17:55 +0000 Subject: brcm2708: update to v3.18 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas git-svn-id: svn://svn.openwrt.org/openwrt/trunk@44392 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../0001-Main-bcm2708-linux-port.patch | 5125 ++++++++++++++++++++ 1 file changed, 5125 insertions(+) create mode 100755 target/linux/brcm2708/patches-3.18/0001-Main-bcm2708-linux-port.patch (limited to 'target/linux/brcm2708/patches-3.18/0001-Main-bcm2708-linux-port.patch') diff --git a/target/linux/brcm2708/patches-3.18/0001-Main-bcm2708-linux-port.patch b/target/linux/brcm2708/patches-3.18/0001-Main-bcm2708-linux-port.patch new file mode 100755 index 0000000000..ff2ddb0861 --- /dev/null +++ b/target/linux/brcm2708/patches-3.18/0001-Main-bcm2708-linux-port.patch @@ -0,0 +1,5125 @@ +From 95293790045ab4ae5c357460372dd1b57fc74f29 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sun, 12 May 2013 12:24:19 +0100 +Subject: [PATCH 001/114] Main bcm2708 linux port + +Signed-off-by: popcornmix +--- + arch/arm/Kconfig | 17 + + arch/arm/Kconfig.debug | 8 + + arch/arm/Makefile | 1 + + arch/arm/configs/bcmrpi_defconfig | 464 ++++++++++++++++ + arch/arm/kernel/process.c | 10 + + arch/arm/mach-bcm2708/Kconfig | 26 + + arch/arm/mach-bcm2708/Makefile | 6 + + arch/arm/mach-bcm2708/Makefile.boot | 3 + + arch/arm/mach-bcm2708/armctrl.c | 208 +++++++ + arch/arm/mach-bcm2708/armctrl.h | 27 + + arch/arm/mach-bcm2708/bcm2708.c | 662 +++++++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708.h | 49 ++ + arch/arm/mach-bcm2708/clock.c | 61 +++ + arch/arm/mach-bcm2708/clock.h | 24 + + arch/arm/mach-bcm2708/dma.c | 399 ++++++++++++++ + arch/arm/mach-bcm2708/include/mach/arm_control.h | 419 ++++++++++++++ + arch/arm/mach-bcm2708/include/mach/arm_power.h | 62 +++ + arch/arm/mach-bcm2708/include/mach/clkdev.h | 7 + + arch/arm/mach-bcm2708/include/mach/debug-macro.S | 22 + + arch/arm/mach-bcm2708/include/mach/dma.h | 88 +++ + arch/arm/mach-bcm2708/include/mach/entry-macro.S | 69 +++ + arch/arm/mach-bcm2708/include/mach/frc.h | 38 ++ + arch/arm/mach-bcm2708/include/mach/hardware.h | 28 + + arch/arm/mach-bcm2708/include/mach/io.h | 27 + + arch/arm/mach-bcm2708/include/mach/irqs.h | 196 +++++++ + arch/arm/mach-bcm2708/include/mach/memory.h | 57 ++ + arch/arm/mach-bcm2708/include/mach/platform.h | 228 ++++++++ + arch/arm/mach-bcm2708/include/mach/power.h | 26 + + arch/arm/mach-bcm2708/include/mach/system.h | 38 ++ + arch/arm/mach-bcm2708/include/mach/timex.h | 23 + + arch/arm/mach-bcm2708/include/mach/uncompress.h | 84 +++ + arch/arm/mach-bcm2708/include/mach/vc_mem.h | 35 ++ + arch/arm/mach-bcm2708/include/mach/vcio.h | 165 ++++++ + arch/arm/mach-bcm2708/include/mach/vmalloc.h | 20 + + arch/arm/mach-bcm2708/power.c | 197 +++++++ + arch/arm/mach-bcm2708/vc_mem.c | 431 +++++++++++++++ + arch/arm/mach-bcm2708/vcio.c | 474 ++++++++++++++++ + arch/arm/mm/Kconfig | 2 +- + arch/arm/mm/proc-v6.S | 15 +- + arch/arm/tools/mach-types | 1 + + drivers/tty/serial/amba-pl011.c | 2 +- + include/linux/mmc/host.h | 1 + + include/linux/mmc/sdhci.h | 1 + + 43 files changed, 4716 insertions(+), 5 deletions(-) + create mode 100644 arch/arm/configs/bcmrpi_defconfig + create mode 100644 arch/arm/mach-bcm2708/Kconfig + create mode 100644 arch/arm/mach-bcm2708/Makefile + create mode 100644 arch/arm/mach-bcm2708/Makefile.boot + create mode 100644 arch/arm/mach-bcm2708/armctrl.c + create mode 100644 arch/arm/mach-bcm2708/armctrl.h + create mode 100644 arch/arm/mach-bcm2708/bcm2708.c + create mode 100644 arch/arm/mach-bcm2708/bcm2708.h + create mode 100644 arch/arm/mach-bcm2708/clock.c + create mode 100644 arch/arm/mach-bcm2708/clock.h + create mode 100644 arch/arm/mach-bcm2708/dma.c + create mode 100644 arch/arm/mach-bcm2708/include/mach/arm_control.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/arm_power.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/clkdev.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/debug-macro.S + create mode 100644 arch/arm/mach-bcm2708/include/mach/dma.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/entry-macro.S + create mode 100644 arch/arm/mach-bcm2708/include/mach/frc.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/hardware.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/io.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/irqs.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/memory.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/platform.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/power.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/system.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/timex.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/uncompress.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/vc_mem.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/vcio.h + create mode 100644 arch/arm/mach-bcm2708/include/mach/vmalloc.h + create mode 100644 arch/arm/mach-bcm2708/power.c + create mode 100644 arch/arm/mach-bcm2708/vc_mem.c + create mode 100644 arch/arm/mach-bcm2708/vcio.c + +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 89c4b5c..4cedaf2 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -381,6 +381,22 @@ config ARCH_AT91 + This enables support for systems based on Atmel + AT91RM9200 and AT91SAM9* processors. + ++config ARCH_BCM2708 ++ bool "Broadcom BCM2708 family" ++ select CPU_V6 ++ select ARM_AMBA ++ select HAVE_CLK ++ select HAVE_SCHED_CLOCK ++ select NEED_MACH_GPIO_H ++ select NEED_MACH_MEMORY_H ++ select CLKDEV_LOOKUP ++ select GENERIC_CLOCKEVENTS ++ select ARM_ERRATA_411920 ++ select MACH_BCM2708 ++ select VC4 ++ help ++ This enables support for Broadcom BCM2708 boards. ++ + config ARCH_CLPS711X + bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" + select ARCH_REQUIRE_GPIOLIB +@@ -972,6 +988,7 @@ source "arch/arm/plat-versatile/Kconfig" + source "arch/arm/mach-vt8500/Kconfig" + + source "arch/arm/mach-w90x900/Kconfig" ++source "arch/arm/mach-bcm2708/Kconfig" + + source "arch/arm/mach-zynq/Kconfig" + +diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug +index d8f6a2e..526e50d 100644 +--- a/arch/arm/Kconfig.debug ++++ b/arch/arm/Kconfig.debug +@@ -985,6 +985,14 @@ choice + options; the platform specific options are deprecated + and will be soon removed. + ++ config DEBUG_BCM2708_UART0 ++ bool "Broadcom BCM2708 UART0 (PL011)" ++ depends on MACH_BCM2708 ++ help ++ Say Y here if you want the debug print routines to direct ++ their output to UART 0. The port must have been initialised ++ by the boot-loader before use. ++ + endchoice + + config DEBUG_EXYNOS_UART +diff --git a/arch/arm/Makefile b/arch/arm/Makefile +index 034a949..fea9213 100644 +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -146,6 +146,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 + machine-$(CONFIG_ARCH_AT91) += at91 + machine-$(CONFIG_ARCH_AXXIA) += axxia + machine-$(CONFIG_ARCH_BCM) += bcm ++machine-$(CONFIG_ARCH_BCM2708) += bcm2708 + machine-$(CONFIG_ARCH_BERLIN) += berlin + machine-$(CONFIG_ARCH_CLPS711X) += clps711x + machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx +diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig +new file mode 100644 +index 0000000..8950e53 +--- /dev/null ++++ b/arch/arm/configs/bcmrpi_defconfig +@@ -0,0 +1,464 @@ ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_FHANDLE=y ++CONFIG_AUDIT=y ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_RESOURCE_COUNTERS=y ++CONFIG_BLK_CGROUP=y ++CONFIG_NAMESPACES=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_EMBEDDED=y ++# CONFIG_COMPAT_BRK is not set ++CONFIG_SLAB=y ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++CONFIG_KPROBES=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_BLK_DEV_THROTTLING=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_CFQ_GROUP_IOSCHED=y ++CONFIG_ARCH_BCM2708=y ++CONFIG_AEABI=y ++CONFIG_SECCOMP=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait" ++CONFIG_KEXEC=y ++CONFIG_CPU_IDLE=y ++CONFIG_VFP=y ++CONFIG_BINFMT_MISC=m ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_XFRM_USER=y ++CONFIG_NET_KEY=m ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_IPV6 is not set ++CONFIG_NET_PKTGEN=m ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRCOMM=m ++CONFIG_IRDA_ULTRA=y ++CONFIG_IRDA_CACHE_LAST_LSAP=y ++CONFIG_IRDA_FAST_RR=y ++CONFIG_IRTTY_SIR=m ++CONFIG_KINGSUN_DONGLE=m ++CONFIG_KSDAZZLE_DONGLE=m ++CONFIG_KS959_DONGLE=m ++CONFIG_USB_IRDA=m ++CONFIG_SIGMATEL_FIR=m ++CONFIG_MCS_FIR=m ++CONFIG_BT=m ++CONFIG_BT_RFCOMM=m ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=m ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=m ++CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIBCM203X=m ++CONFIG_BT_HCIBPA10X=m ++CONFIG_BT_HCIBFUSB=m ++CONFIG_BT_HCIVHCI=m ++CONFIG_BT_MRVL=m ++CONFIG_BT_MRVL_SDIO=m ++CONFIG_BT_ATH3K=m ++CONFIG_CFG80211=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set ++CONFIG_BLK_DEV_SD=m ++CONFIG_BLK_DEV_SR=m ++# CONFIG_SCSI_LOWLEVEL is not set ++CONFIG_MD=y ++CONFIG_NETDEVICES=y ++CONFIG_NETCONSOLE=m ++CONFIG_TUN=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_PPP=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SMSC75XX=m ++CONFIG_USB_NET_SMSC95XX=y ++CONFIG_USB_NET_GL620A=m ++CONFIG_USB_NET_NET1080=m ++CONFIG_USB_NET_PLUSB=m ++CONFIG_USB_NET_MCS7830=m ++CONFIG_USB_NET_CDC_SUBSET=m ++CONFIG_USB_ALI_M5632=y ++CONFIG_USB_AN2720=y ++CONFIG_USB_KC2190=y ++# CONFIG_USB_NET_ZAURUS is not set ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++CONFIG_LIBERTAS_THINFIRM=m ++CONFIG_LIBERTAS_THINFIRM_USB=m ++CONFIG_AT76C50X_USB=m ++CONFIG_USB_ZD1201=m ++CONFIG_USB_NET_RNDIS_WLAN=m ++CONFIG_RTL8187=m ++CONFIG_MAC80211_HWSIM=m ++CONFIG_B43=m ++CONFIG_B43LEGACY=m ++CONFIG_HOSTAP=m ++CONFIG_LIBERTAS=m ++CONFIG_LIBERTAS_USB=m ++CONFIG_LIBERTAS_SDIO=m ++CONFIG_P54_COMMON=m ++CONFIG_P54_USB=m ++CONFIG_RT2X00=m ++CONFIG_RT2500USB=m ++CONFIG_RT73USB=m ++CONFIG_RT2800USB=m ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RTL8192CU=m ++CONFIG_ZD1211RW=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_INPUT_POLLDEV=m ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=m ++CONFIG_INPUT_ATI_REMOTE2=m ++CONFIG_INPUT_KEYSPAN_REMOTE=m ++CONFIG_INPUT_POWERMATE=m ++CONFIG_INPUT_YEALINK=m ++CONFIG_INPUT_CM109=m ++CONFIG_INPUT_UINPUT=m ++CONFIG_INPUT_ADXL34X=m ++CONFIG_INPUT_CMA3000=m ++CONFIG_SERIO=m ++CONFIG_SERIO_RAW=m ++CONFIG_GAMEPORT=m ++CONFIG_GAMEPORT_NS558=m ++CONFIG_GAMEPORT_L4=m ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_DEVKMEM is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_HW_RANDOM is not set ++CONFIG_RAW_DRIVER=y ++# CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_FB=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_LOGO_LINUX_MONO is not set ++# CONFIG_LOGO_LINUX_VGA16 is not set ++CONFIG_HID_A4TECH=m ++CONFIG_HID_ACRUX=m ++CONFIG_HID_APPLE=m ++CONFIG_HID_BELKIN=m ++CONFIG_HID_CHERRY=m ++CONFIG_HID_CHICONY=m ++CONFIG_HID_CYPRESS=m ++CONFIG_HID_DRAGONRISE=m ++CONFIG_HID_EMS_FF=m ++CONFIG_HID_ELECOM=m ++CONFIG_HID_EZKEY=m ++CONFIG_HID_HOLTEK=m ++CONFIG_HID_KEYTOUCH=m ++CONFIG_HID_KYE=m ++CONFIG_HID_UCLOGIC=m ++CONFIG_HID_WALTOP=m ++CONFIG_HID_GYRATION=m ++CONFIG_HID_TWINHAN=m ++CONFIG_HID_KENSINGTON=m ++CONFIG_HID_LCPOWER=m ++CONFIG_HID_LOGITECH=m ++CONFIG_HID_MAGICMOUSE=m ++CONFIG_HID_MICROSOFT=m ++CONFIG_HID_MONTEREY=m ++CONFIG_HID_MULTITOUCH=m ++CONFIG_HID_NTRIG=m ++CONFIG_HID_ORTEK=m ++CONFIG_HID_PANTHERLORD=m ++CONFIG_HID_PETALYNX=m ++CONFIG_HID_PICOLCD=m ++CONFIG_HID_ROCCAT=m ++CONFIG_HID_SAMSUNG=m ++CONFIG_HID_SONY=m ++CONFIG_HID_SPEEDLINK=m ++CONFIG_HID_SUNPLUS=m ++CONFIG_HID_GREENASIA=m ++CONFIG_HID_SMARTJOYPLUS=m ++CONFIG_HID_TOPSEED=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_STORAGE=y ++CONFIG_USB_STORAGE_REALTEK=m ++CONFIG_USB_STORAGE_DATAFAB=m ++CONFIG_USB_STORAGE_FREECOM=m ++CONFIG_USB_STORAGE_ISD200=m ++CONFIG_USB_STORAGE_USBAT=m ++CONFIG_USB_STORAGE_SDDR09=m ++CONFIG_USB_STORAGE_SDDR55=m ++CONFIG_USB_STORAGE_JUMPSHOT=m ++CONFIG_USB_STORAGE_ALAUDA=m ++CONFIG_USB_STORAGE_ONETOUCH=m ++CONFIG_USB_STORAGE_KARMA=m ++CONFIG_USB_STORAGE_CYPRESS_ATACB=m ++CONFIG_USB_STORAGE_ENE_UB6250=m ++CONFIG_USB_UAS=m ++CONFIG_USB_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USB_SERIAL=m ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_AIRCABLE=m ++CONFIG_USB_SERIAL_ARK3116=m ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_CH341=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_CP210X=m ++CONFIG_USB_SERIAL_CYPRESS_M8=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=m ++CONFIG_USB_SERIAL_VISOR=m ++CONFIG_USB_SERIAL_IPAQ=m ++CONFIG_USB_SERIAL_IR=m ++CONFIG_USB_SERIAL_EDGEPORT=m ++CONFIG_USB_SERIAL_EDGEPORT_TI=m ++CONFIG_USB_SERIAL_GARMIN=m ++CONFIG_USB_SERIAL_IPW=m ++CONFIG_USB_SERIAL_IUU=m ++CONFIG_USB_SERIAL_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=m ++CONFIG_USB_SERIAL_NAVMAN=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_OTI6858=m ++CONFIG_USB_SERIAL_QCAUX=m ++CONFIG_USB_SERIAL_QUALCOMM=m ++CONFIG_USB_SERIAL_SPCP8X5=m ++CONFIG_USB_SERIAL_SAFE=m ++CONFIG_USB_SERIAL_SIERRAWIRELESS=m ++CONFIG_USB_SERIAL_SYMBOL=m ++CONFIG_USB_SERIAL_TI=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OPTION=m ++CONFIG_USB_SERIAL_OMNINET=m ++CONFIG_USB_SERIAL_OPTICON=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_DEBUG=m ++CONFIG_USB_EMI62=m ++CONFIG_USB_EMI26=m ++CONFIG_USB_ADUTUX=m ++CONFIG_USB_SEVSEG=m ++CONFIG_USB_RIO500=m ++CONFIG_USB_LEGOTOWER=m ++CONFIG_USB_LCD=m ++CONFIG_USB_LED=m ++CONFIG_USB_CYPRESS_CY7C63=m ++CONFIG_USB_CYTHERM=m ++CONFIG_USB_IDMOUSE=m ++CONFIG_USB_FTDI_ELAN=m ++CONFIG_USB_APPLEDISPLAY=m ++CONFIG_USB_LD=m ++CONFIG_USB_TRANCEVIBRATOR=m ++CONFIG_USB_IOWARRIOR=m ++CONFIG_USB_TEST=m ++CONFIG_USB_ISIGHTFW=m ++CONFIG_USB_YUREX=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_UIO=m ++CONFIG_UIO_PDRV_GENIRQ=m ++# CONFIG_IOMMU_SUPPORT is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_REISERFS_FS=m ++CONFIG_REISERFS_FS_XATTR=y ++CONFIG_REISERFS_FS_POSIX_ACL=y ++CONFIG_REISERFS_FS_SECURITY=y ++CONFIG_JFS_FS=m ++CONFIG_JFS_POSIX_ACL=y ++CONFIG_JFS_SECURITY=y ++CONFIG_JFS_STATISTICS=y ++CONFIG_XFS_FS=m ++CONFIG_XFS_QUOTA=y ++CONFIG_XFS_POSIX_ACL=y ++CONFIG_XFS_RT=y ++CONFIG_GFS2_FS=m ++CONFIG_OCFS2_FS=m ++CONFIG_BTRFS_FS=m ++CONFIG_BTRFS_FS_POSIX_ACL=y ++CONFIG_NILFS2_FS=m ++CONFIG_FANOTIFY=y ++CONFIG_AUTOFS4_FS=y ++CONFIG_FUSE_FS=m ++CONFIG_CUSE=m ++CONFIG_FSCACHE=y ++CONFIG_FSCACHE_STATS=y ++CONFIG_FSCACHE_HISTOGRAM=y ++CONFIG_CACHEFILES=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++CONFIG_UDF_FS=m ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_IOCHARSET="ascii" ++CONFIG_NTFS_FS=m ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_CONFIGFS_FS=y ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=y ++CONFIG_NLS_DEFAULT="utf8" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=m ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=m ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++CONFIG_NLS_UTF8=m ++CONFIG_PRINTK_TIME=y ++CONFIG_BOOT_PRINTK_DELAY=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_STACK_USAGE=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_TIMER_STATS=y ++CONFIG_LATENCYTOP=y ++CONFIG_IRQSOFF_TRACER=y ++CONFIG_SCHED_TRACER=y ++CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_KGDB=y ++CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y ++CONFIG_STRICT_DEVMEM=y ++CONFIG_CRYPTO_AUTHENC=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA512=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_DEFLATE=m ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y +diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c +index fe972a2..f4f3bfd 100644 +--- a/arch/arm/kernel/process.c ++++ b/arch/arm/kernel/process.c +@@ -166,6 +166,16 @@ void arch_cpu_idle_dead(void) + } + #endif + ++char bcm2708_reboot_mode = 'h'; ++ ++int __init reboot_setup(char *str) ++{ ++ bcm2708_reboot_mode = str[0]; ++ return 1; ++} ++ ++__setup("reboot=", reboot_setup); ++ + /* + * Called by kexec, immediately prior to machine_kexec(). + * +diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig +new file mode 100644 +index 0000000..1f11478 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/Kconfig +@@ -0,0 +1,26 @@ ++menu "Broadcom BCM2708 Implementations" ++ depends on ARCH_BCM2708 ++ ++config MACH_BCM2708 ++ bool "Broadcom BCM2708 Development Platform" ++ select NEED_MACH_MEMORY_H ++ select NEED_MACH_IO_H ++ select CPU_V6 ++ help ++ Include support for the Broadcom(R) BCM2708 platform. ++ ++config BCM2708_VCMEM ++ bool "Videocore Memory" ++ depends on MACH_BCM2708 ++ default y ++ help ++ Helper for videocore memory access and total size allocation. ++ ++config BCM2708_NOL2CACHE ++ bool "Videocore L2 cache disable" ++ depends on MACH_BCM2708 ++ default n ++ help ++ Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt. ++ ++endmenu +diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile +new file mode 100644 +index 0000000..c76f39bc +--- /dev/null ++++ b/arch/arm/mach-bcm2708/Makefile +@@ -0,0 +1,6 @@ ++# ++# Makefile for the linux kernel. ++# ++ ++obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o ++obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o +diff --git a/arch/arm/mach-bcm2708/Makefile.boot b/arch/arm/mach-bcm2708/Makefile.boot +new file mode 100644 +index 0000000..67039c3 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/Makefile.boot +@@ -0,0 +1,3 @@ ++ zreladdr-y := 0x00008000 ++params_phys-y := 0x00000100 ++initrd_phys-y := 0x00800000 +diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c +new file mode 100644 +index 0000000..ef1c8d5 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/armctrl.c +@@ -0,0 +1,208 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/armctrl.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include "armctrl.h" ++ ++/* For support of kernels >= 3.0 assume only one VIC for now*/ ++static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = { ++ INTERRUPT_VC_JPEG, ++ INTERRUPT_VC_USB, ++ INTERRUPT_VC_3D, ++ INTERRUPT_VC_DMA2, ++ INTERRUPT_VC_DMA3, ++ INTERRUPT_VC_I2C, ++ INTERRUPT_VC_SPI, ++ INTERRUPT_VC_I2SPCM, ++ INTERRUPT_VC_SDIO, ++ INTERRUPT_VC_UART, ++ INTERRUPT_VC_ARASANSDIO ++}; ++ ++static void armctrl_mask_irq(struct irq_data *d) ++{ ++ static const unsigned int disables[4] = { ++ ARM_IRQ_DIBL1, ++ ARM_IRQ_DIBL2, ++ ARM_IRQ_DIBL3, ++ 0 ++ }; ++ ++ unsigned int data = (unsigned int)irq_get_chip_data(d->irq); ++ writel(1 << (data & 0x1f), __io_address(disables[(data >> 5) & 0x3])); ++} ++ ++static void armctrl_unmask_irq(struct irq_data *d) ++{ ++ static const unsigned int enables[4] = { ++ ARM_IRQ_ENBL1, ++ ARM_IRQ_ENBL2, ++ ARM_IRQ_ENBL3, ++ 0 ++ }; ++ ++ unsigned int data = (unsigned int)irq_get_chip_data(d->irq); ++ writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3])); ++} ++ ++#if defined(CONFIG_PM) ++ ++/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */ ++ ++/* Static defines ++ * struct armctrl_device - VIC PM device (< 3.xx) ++ * @sysdev: The system device which is registered. (< 3.xx) ++ * @irq: The IRQ number for the base of the VIC. ++ * @base: The register base for the VIC. ++ * @resume_sources: A bitmask of interrupts for resume. ++ * @resume_irqs: The IRQs enabled for resume. ++ * @int_select: Save for VIC_INT_SELECT. ++ * @int_enable: Save for VIC_INT_ENABLE. ++ * @soft_int: Save for VIC_INT_SOFT. ++ * @protect: Save for VIC_PROTECT. ++ */ ++struct armctrl_info { ++ void __iomem *base; ++ int irq; ++ u32 resume_sources; ++ u32 resume_irqs; ++ u32 int_select; ++ u32 int_enable; ++ u32 soft_int; ++ u32 protect; ++} armctrl; ++ ++static int armctrl_suspend(void) ++{ ++ return 0; ++} ++ ++static void armctrl_resume(void) ++{ ++ return; ++} ++ ++/** ++ * armctrl_pm_register - Register a VIC for later power management control ++ * @base: The base address of the VIC. ++ * @irq: The base IRQ for the VIC. ++ * @resume_sources: bitmask of interrupts allowed for resume sources. ++ * ++ * For older kernels (< 3.xx) do - ++ * Register the VIC with the system device tree so that it can be notified ++ * of suspend and resume requests and ensure that the correct actions are ++ * taken to re-instate the settings on resume. ++ */ ++static void __init armctrl_pm_register(void __iomem * base, unsigned int irq, ++ u32 resume_sources) ++{ ++ armctrl.base = base; ++ armctrl.resume_sources = resume_sources; ++ armctrl.irq = irq; ++} ++ ++static int armctrl_set_wake(struct irq_data *d, unsigned int on) ++{ ++ unsigned int off = d->irq & 31; ++ u32 bit = 1 << off; ++ ++ if (!(bit & armctrl.resume_sources)) ++ return -EINVAL; ++ ++ if (on) ++ armctrl.resume_irqs |= bit; ++ else ++ armctrl.resume_irqs &= ~bit; ++ ++ return 0; ++} ++ ++#else ++static inline void armctrl_pm_register(void __iomem * base, unsigned int irq, ++ u32 arg1) ++{ ++} ++ ++#define armctrl_suspend NULL ++#define armctrl_resume NULL ++#define armctrl_set_wake NULL ++#endif /* CONFIG_PM */ ++ ++static struct syscore_ops armctrl_syscore_ops = { ++ .suspend = armctrl_suspend, ++ .resume = armctrl_resume, ++}; ++ ++/** ++ * armctrl_syscore_init - initicall to register VIC pm functions ++ * ++ * This is called via late_initcall() to register ++ * the resources for the VICs due to the early ++ * nature of the VIC's registration. ++*/ ++static int __init armctrl_syscore_init(void) ++{ ++ register_syscore_ops(&armctrl_syscore_ops); ++ return 0; ++} ++ ++late_initcall(armctrl_syscore_init); ++ ++static struct irq_chip armctrl_chip = { ++ .name = "ARMCTRL", ++ .irq_ack = NULL, ++ .irq_mask = armctrl_mask_irq, ++ .irq_unmask = armctrl_unmask_irq, ++ .irq_set_wake = armctrl_set_wake, ++}; ++ ++/** ++ * armctrl_init - initialise a vectored interrupt controller ++ * @base: iomem base address ++ * @irq_start: starting interrupt number, must be muliple of 32 ++ * @armctrl_sources: bitmask of interrupt sources to allow ++ * @resume_sources: bitmask of interrupt sources to allow for resume ++ */ ++int __init armctrl_init(void __iomem * base, unsigned int irq_start, ++ u32 armctrl_sources, u32 resume_sources) ++{ ++ unsigned int irq; ++ ++ for (irq = 0; irq < BCM2708_ALLOC_IRQS; irq++) { ++ unsigned int data = irq; ++ if (irq >= INTERRUPT_JPEG && irq <= INTERRUPT_ARASANSDIO) ++ data = remap_irqs[irq - INTERRUPT_JPEG]; ++ ++ irq_set_chip(irq, &armctrl_chip); ++ irq_set_chip_data(irq, (void *)data); ++ irq_set_handler(irq, handle_level_irq); ++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_DISABLED); ++ } ++ ++ armctrl_pm_register(base, irq_start, resume_sources); ++ return 0; ++} +diff --git a/arch/arm/mach-bcm2708/armctrl.h b/arch/arm/mach-bcm2708/armctrl.h +new file mode 100644 +index 0000000..0aa916e +--- /dev/null ++++ b/arch/arm/mach-bcm2708/armctrl.h +@@ -0,0 +1,27 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/armctrl.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef __BCM2708_ARMCTRL_H ++#define __BCM2708_ARMCTRL_H ++ ++extern int __init armctrl_init(void __iomem * base, unsigned int irq_start, ++ u32 armctrl_sources, u32 resume_sources); ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +new file mode 100644 +index 0000000..9b4e709 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -0,0 +1,662 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/bcm2708.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "bcm2708.h" ++#include "armctrl.h" ++#include "clock.h" ++ ++#ifdef CONFIG_BCM_VC_CMA ++#include ++#endif ++ ++ ++/* Effectively we have an IOMMU (ARM<->VideoCore map) that is set up to ++ * give us IO access only to 64Mbytes of physical memory (26 bits). We could ++ * represent this window by setting our dmamasks to 26 bits but, in fact ++ * we're not going to use addresses outside this range (they're not in real ++ * memory) so we don't bother. ++ * ++ * In the future we might include code to use this IOMMU to remap other ++ * physical addresses onto VideoCore memory then the use of 32-bits would be ++ * more legitimate. ++ */ ++#define DMA_MASK_BITS_COMMON 32 ++ ++/* command line parameters */ ++static unsigned boardrev, serial; ++static unsigned uart_clock; ++static unsigned disk_led_gpio = 16; ++static unsigned disk_led_active_low = 1; ++static unsigned reboot_part = 0; ++ ++static void __init bcm2708_init_led(void); ++ ++void __init bcm2708_init_irq(void) ++{ ++ armctrl_init(__io_address(ARMCTRL_IC_BASE), 0, 0, 0); ++} ++ ++static struct map_desc bcm2708_io_desc[] __initdata = { ++ { ++ .virtual = IO_ADDRESS(ARMCTRL_BASE), ++ .pfn = __phys_to_pfn(ARMCTRL_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(UART0_BASE), ++ .pfn = __phys_to_pfn(UART0_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(UART1_BASE), ++ .pfn = __phys_to_pfn(UART1_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(DMA_BASE), ++ .pfn = __phys_to_pfn(DMA_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(MCORE_BASE), ++ .pfn = __phys_to_pfn(MCORE_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(ST_BASE), ++ .pfn = __phys_to_pfn(ST_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(USB_BASE), ++ .pfn = __phys_to_pfn(USB_BASE), ++ .length = SZ_128K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(PM_BASE), ++ .pfn = __phys_to_pfn(PM_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE}, ++ { ++ .virtual = IO_ADDRESS(GPIO_BASE), ++ .pfn = __phys_to_pfn(GPIO_BASE), ++ .length = SZ_4K, ++ .type = MT_DEVICE} ++}; ++ ++void __init bcm2708_map_io(void) ++{ ++ iotable_init(bcm2708_io_desc, ARRAY_SIZE(bcm2708_io_desc)); ++} ++ ++/* The STC is a free running counter that increments at the rate of 1MHz */ ++#define STC_FREQ_HZ 1000000 ++ ++static inline uint32_t timer_read(void) ++{ ++ /* STC: a free running counter that increments at the rate of 1MHz */ ++ return readl(__io_address(ST_BASE + 0x04)); ++} ++ ++static unsigned long bcm2708_read_current_timer(void) ++{ ++ return timer_read(); ++} ++ ++static u64 notrace bcm2708_read_sched_clock(void) ++{ ++ return timer_read(); ++} ++ ++static cycle_t clksrc_read(struct clocksource *cs) ++{ ++ return timer_read(); ++} ++ ++static struct clocksource clocksource_stc = { ++ .name = "stc", ++ .rating = 300, ++ .read = clksrc_read, ++ .mask = CLOCKSOURCE_MASK(32), ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++unsigned long frc_clock_ticks32(void) ++{ ++ return timer_read(); ++} ++ ++static void __init bcm2708_clocksource_init(void) ++{ ++ if (clocksource_register_hz(&clocksource_stc, STC_FREQ_HZ)) { ++ printk(KERN_ERR "timer: failed to initialize clock " ++ "source %s\n", clocksource_stc.name); ++ } ++} ++ ++ ++/* ++ * These are fixed clocks. ++ */ ++static struct clk ref24_clk = { ++ .rate = UART0_CLOCK, /* The UART is clocked at 3MHz via APB_CLK */ ++}; ++ ++static struct clk osc_clk = { ++#ifdef CONFIG_ARCH_BCM2708_CHIPIT ++ .rate = 27000000, ++#else ++ .rate = 500000000, /* ARM clock is set from the VideoCore booter */ ++#endif ++}; ++ ++/* warning - the USB needs a clock > 34MHz */ ++ ++#ifdef CONFIG_MMC_BCM2708 ++static struct clk sdhost_clk = { ++#ifdef CONFIG_ARCH_BCM2708_CHIPIT ++ .rate = 4000000, /* 4MHz */ ++#else ++ .rate = 250000000, /* 250MHz */ ++#endif ++}; ++#endif ++ ++static struct clk_lookup lookups[] = { ++ { /* UART0 */ ++ .dev_id = "dev:f1", ++ .clk = &ref24_clk, ++ }, ++ { /* USB */ ++ .dev_id = "bcm2708_usb", ++ .clk = &osc_clk, ++ } ++}; ++ ++#define UART0_IRQ { IRQ_UART, 0 /*NO_IRQ*/ } ++#define UART0_DMA { 15, 14 } ++ ++AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); ++ ++static struct amba_device *amba_devs[] __initdata = { ++ &uart0_device, ++}; ++ ++static struct resource bcm2708_dmaman_resources[] = { ++ { ++ .start = DMA_BASE, ++ .end = DMA_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct platform_device bcm2708_dmaman_device = { ++ .name = BCM_DMAMAN_DRIVER_NAME, ++ .id = 0, /* first bcm2708_dma */ ++ .resource = bcm2708_dmaman_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), ++}; ++ ++static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_fb_device = { ++ .name = "bcm2708_fb", ++ .id = -1, /* only one bcm2708_fb */ ++ .resource = NULL, ++ .num_resources = 0, ++ .dev = { ++ .dma_mask = &fb_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ ++static struct plat_serial8250_port bcm2708_uart1_platform_data[] = { ++ { ++ .mapbase = UART1_BASE + 0x40, ++ .irq = IRQ_AUX, ++ .uartclk = 125000000, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_FIXED_TYPE | UPF_IOREMAP | UPF_SKIP_TEST, ++ .type = PORT_8250, ++ }, ++ {}, ++}; ++ ++static struct platform_device bcm2708_uart1_device = { ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM, ++ .dev = { ++ .platform_data = bcm2708_uart1_platform_data, ++ }, ++}; ++ ++static struct resource bcm2708_usb_resources[] = { ++ [0] = { ++ .start = USB_BASE, ++ .end = USB_BASE + SZ_128K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_USB, ++ .end = IRQ_USB, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 usb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_usb_device = { ++ .name = "bcm2708_usb", ++ .id = -1, /* only one bcm2708_usb */ ++ .resource = bcm2708_usb_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_usb_resources), ++ .dev = { ++ .dma_mask = &usb_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ ++static struct resource bcm2708_vcio_resources[] = { ++ [0] = { /* mailbox/semaphore/doorbell access */ ++ .start = MCORE_BASE, ++ .end = MCORE_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_vcio_device = { ++ .name = BCM_VCIO_DRIVER_NAME, ++ .id = -1, /* only one VideoCore I/O area */ ++ .resource = bcm2708_vcio_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), ++ .dev = { ++ .dma_mask = &vcio_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ ++static struct resource bcm2708_systemtimer_resources[] = { ++ [0] = { /* system timer access */ ++ .start = ST_BASE, ++ .end = ST_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IRQ_TIMER3, ++ .end = IRQ_TIMER3, ++ .flags = IORESOURCE_IRQ, ++ } ++ ++}; ++ ++static u64 systemtimer_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_systemtimer_device = { ++ .name = "bcm2708_systemtimer", ++ .id = -1, /* only one VideoCore I/O area */ ++ .resource = bcm2708_systemtimer_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_systemtimer_resources), ++ .dev = { ++ .dma_mask = &systemtimer_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ ++static struct resource bcm2708_powerman_resources[] = { ++ [0] = { ++ .start = PM_BASE, ++ .end = PM_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static u64 powerman_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++struct platform_device bcm2708_powerman_device = { ++ .name = "bcm2708_powerman", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_powerman_resources), ++ .resource = bcm2708_powerman_resources, ++ .dev = { ++ .dma_mask = &powerman_dmamask, ++ .coherent_dma_mask = 0xffffffffUL}, ++}; ++ ++int __init bcm_register_device(struct platform_device *pdev) ++{ ++ int ret; ++ ++ ret = platform_device_register(pdev); ++ if (ret) ++ pr_debug("Unable to register platform device '%s': %d\n", ++ pdev->name, ret); ++ ++ return ret; ++} ++ ++int calc_rsts(int partition) ++{ ++ return PM_PASSWORD | ++ ((partition & (1 << 0)) << 0) | ++ ((partition & (1 << 1)) << 1) | ++ ((partition & (1 << 2)) << 2) | ++ ((partition & (1 << 3)) << 3) | ++ ((partition & (1 << 4)) << 4) | ++ ((partition & (1 << 5)) << 5); ++} ++ ++static void bcm2708_restart(enum reboot_mode mode, const char *cmd) ++{ ++ extern char bcm2708_reboot_mode; ++ uint32_t pm_rstc, pm_wdog; ++ uint32_t timeout = 10; ++ uint32_t pm_rsts = 0; ++ ++ if(bcm2708_reboot_mode == 'q') ++ { ++ // NOOBS < 1.3 booting with reboot=q ++ pm_rsts = readl(__io_address(PM_RSTS)); ++ pm_rsts = PM_PASSWORD | pm_rsts | PM_RSTS_HADWRQ_SET; ++ } ++ else if(bcm2708_reboot_mode == 'p') ++ { ++ // NOOBS < 1.3 halting ++ pm_rsts = readl(__io_address(PM_RSTS)); ++ pm_rsts = PM_PASSWORD | pm_rsts | PM_RSTS_HADWRH_SET; ++ } ++ else ++ { ++ pm_rsts = calc_rsts(reboot_part); ++ } ++ ++ writel(pm_rsts, __io_address(PM_RSTS)); ++ ++ /* Setup watchdog for reset */ ++ pm_rstc = readl(__io_address(PM_RSTC)); ++ ++ pm_wdog = PM_PASSWORD | (timeout & PM_WDOG_TIME_SET); // watchdog timer = timer clock / 16; need password (31:16) + value (11:0) ++ pm_rstc = PM_PASSWORD | (pm_rstc & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET; ++ ++ writel(pm_wdog, __io_address(PM_WDOG)); ++ writel(pm_rstc, __io_address(PM_RSTC)); ++} ++ ++/* We can't really power off, but if we do the normal reset scheme, and indicate to bootcode.bin not to reboot, then most of the chip will be powered off */ ++static void bcm2708_power_off(void) ++{ ++ extern char bcm2708_reboot_mode; ++ if(bcm2708_reboot_mode == 'q') ++ { ++ // NOOBS < v1.3 ++ bcm2708_restart('p', ""); ++ } ++ else ++ { ++ /* partition 63 is special code for HALT the bootloader knows not to boot*/ ++ reboot_part = 63; ++ /* continue with normal reset mechanism */ ++ bcm2708_restart(0, ""); ++ } ++} ++ ++void __init bcm2708_init(void) ++{ ++ int i; ++ ++#if defined(CONFIG_BCM_VC_CMA) ++ vc_cma_early_init(); ++#endif ++ printk("bcm2708.uart_clock = %d\n", uart_clock); ++ pm_power_off = bcm2708_power_off; ++ ++ if (uart_clock) ++ lookups[0].clk->rate = uart_clock; ++ ++ for (i = 0; i < ARRAY_SIZE(lookups); i++) ++ clkdev_add(&lookups[i]); ++ ++ bcm_register_device(&bcm2708_dmaman_device); ++ bcm_register_device(&bcm2708_vcio_device); ++ bcm_register_device(&bcm2708_systemtimer_device); ++ bcm_register_device(&bcm2708_fb_device); ++ bcm_register_device(&bcm2708_usb_device); ++ bcm_register_device(&bcm2708_uart1_device); ++ bcm_register_device(&bcm2708_powerman_device); ++ ++ bcm2708_init_led(); ++ ++ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { ++ struct amba_device *d = amba_devs[i]; ++ amba_device_register(d, &iomem_resource); ++ } ++ system_rev = boardrev; ++ system_serial_low = serial; ++} ++ ++static void timer_set_mode(enum clock_event_mode mode, ++ struct clock_event_device *clk) ++{ ++ switch (mode) { ++ case CLOCK_EVT_MODE_ONESHOT: /* Leave the timer disabled, .set_next_event will enable it */ ++ case CLOCK_EVT_MODE_SHUTDOWN: ++ break; ++ case CLOCK_EVT_MODE_PERIODIC: ++ ++ case CLOCK_EVT_MODE_UNUSED: ++ case CLOCK_EVT_MODE_RESUME: ++ ++ default: ++ printk(KERN_ERR "timer_set_mode: unhandled mode:%d\n", ++ (int)mode); ++ break; ++ } ++ ++} ++ ++static int timer_set_next_event(unsigned long cycles, ++ struct clock_event_device *unused) ++{ ++ unsigned long stc; ++ do { ++ stc = readl(__io_address(ST_BASE + 0x04)); ++ /* We could take a FIQ here, which may push ST above STC3 */ ++ writel(stc + cycles, __io_address(ST_BASE + 0x18)); ++ } while ((signed long) cycles >= 0 && ++ (signed long) (readl(__io_address(ST_BASE + 0x04)) - stc) ++ >= (signed long) cycles); ++ return 0; ++} ++ ++static struct clock_event_device timer0_clockevent = { ++ .name = "timer0", ++ .shift = 32, ++ .features = CLOCK_EVT_FEAT_ONESHOT, ++ .set_mode = timer_set_mode, ++ .set_next_event = timer_set_next_event, ++}; ++ ++/* ++ * IRQ handler for the timer ++ */ ++static irqreturn_t bcm2708_timer_interrupt(int irq, void *dev_id) ++{ ++ struct clock_event_device *evt = &timer0_clockevent; ++ ++ writel(1 << 3, __io_address(ST_BASE + 0x00)); /* stcs clear timer int */ ++ ++ evt->event_handler(evt); ++ ++ return IRQ_HANDLED; ++} ++ ++static struct irqaction bcm2708_timer_irq = { ++ .name = "BCM2708 Timer Tick", ++ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .handler = bcm2708_timer_interrupt, ++}; ++ ++/* ++ * Set up timer interrupt, and return the current time in seconds. ++ */ ++ ++static struct delay_timer bcm2708_delay_timer = { ++ .read_current_timer = bcm2708_read_current_timer, ++ .freq = STC_FREQ_HZ, ++}; ++ ++static void __init bcm2708_timer_init(void) ++{ ++ /* init high res timer */ ++ bcm2708_clocksource_init(); ++ ++ /* ++ * Initialise to a known state (all timers off) ++ */ ++ writel(0, __io_address(ARM_T_CONTROL)); ++ /* ++ * Make irqs happen for the system timer ++ */ ++ setup_irq(IRQ_TIMER3, &bcm2708_timer_irq); ++ ++ sched_clock_register(bcm2708_read_sched_clock, 32, STC_FREQ_HZ); ++ ++ timer0_clockevent.mult = ++ div_sc(STC_FREQ_HZ, NSEC_PER_SEC, timer0_clockevent.shift); ++ timer0_clockevent.max_delta_ns = ++ clockevent_delta2ns(0xffffffff, &timer0_clockevent); ++ timer0_clockevent.min_delta_ns = ++ clockevent_delta2ns(0xf, &timer0_clockevent); ++ ++ timer0_clockevent.cpumask = cpumask_of(0); ++ clockevents_register_device(&timer0_clockevent); ++ ++ register_current_timer_delay(&bcm2708_delay_timer); ++} ++ ++#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) ++#include ++ ++static struct gpio_led bcm2708_leds[] = { ++ [0] = { ++ .gpio = 16, ++ .name = "led0", ++ .default_trigger = "mmc0", ++ .active_low = 1, ++ }, ++}; ++ ++static struct gpio_led_platform_data bcm2708_led_pdata = { ++ .num_leds = ARRAY_SIZE(bcm2708_leds), ++ .leds = bcm2708_leds, ++}; ++ ++static struct platform_device bcm2708_led_device = { ++ .name = "leds-gpio", ++ .id = -1, ++ .dev = { ++ .platform_data = &bcm2708_led_pdata, ++ }, ++}; ++ ++static void __init bcm2708_init_led(void) ++{ ++ bcm2708_leds[0].gpio = disk_led_gpio; ++ bcm2708_leds[0].active_low = disk_led_active_low; ++ platform_device_register(&bcm2708_led_device); ++} ++#else ++static inline void bcm2708_init_led(void) ++{ ++} ++#endif ++ ++void __init bcm2708_init_early(void) ++{ ++ /* ++ * Some devices allocate their coherent buffers from atomic ++ * context. Increase size of atomic coherent pool to make sure such ++ * the allocations won't fail. ++ */ ++ init_dma_coherent_pool_size(SZ_4M); ++} ++ ++static void __init board_reserve(void) ++{ ++#if defined(CONFIG_BCM_VC_CMA) ++ vc_cma_reserve(); ++#endif ++} ++ ++MACHINE_START(BCM2708, "BCM2708") ++ /* Maintainer: Broadcom Europe Ltd. */ ++ .map_io = bcm2708_map_io, ++ .init_irq = bcm2708_init_irq, ++ .init_time = bcm2708_timer_init, ++ .init_machine = bcm2708_init, ++ .init_early = bcm2708_init_early, ++ .reserve = board_reserve, ++ .restart = bcm2708_restart, ++MACHINE_END ++ ++module_param(boardrev, uint, 0644); ++module_param(serial, uint, 0644); ++module_param(uart_clock, uint, 0644); ++module_param(disk_led_gpio, uint, 0644); ++module_param(disk_led_active_low, uint, 0644); ++module_param(reboot_part, uint, 0644); +diff --git a/arch/arm/mach-bcm2708/bcm2708.h b/arch/arm/mach-bcm2708/bcm2708.h +new file mode 100644 +index 0000000..e339a93 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/bcm2708.h +@@ -0,0 +1,49 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/bcm2708.h ++ * ++ * BCM2708 machine support header ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef __BCM2708_BCM2708_H ++#define __BCM2708_BCM2708_H ++ ++#include ++ ++extern void __init bcm2708_init(void); ++extern void __init bcm2708_init_irq(void); ++extern void __init bcm2708_map_io(void); ++extern struct sys_timer bcm2708_timer; ++extern unsigned int mmc_status(struct device *dev); ++ ++#define AMBA_DEVICE(name, busid, base, plat) \ ++static struct amba_device name##_device = { \ ++ .dev = { \ ++ .coherent_dma_mask = ~0, \ ++ .init_name = busid, \ ++ .platform_data = plat, \ ++ }, \ ++ .res = { \ ++ .start = base##_BASE, \ ++ .end = (base##_BASE) + SZ_4K - 1,\ ++ .flags = IORESOURCE_MEM, \ ++ }, \ ++ .irq = base##_IRQ, \ ++} ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/clock.c b/arch/arm/mach-bcm2708/clock.c +new file mode 100644 +index 0000000..4fc556e +--- /dev/null ++++ b/arch/arm/mach-bcm2708/clock.c +@@ -0,0 +1,61 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/clock.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "clock.h" ++ ++int clk_enable(struct clk *clk) ++{ ++ return 0; ++} ++EXPORT_SYMBOL(clk_enable); ++ ++void clk_disable(struct clk *clk) ++{ ++} ++EXPORT_SYMBOL(clk_disable); ++ ++unsigned long clk_get_rate(struct clk *clk) ++{ ++ return clk->rate; ++} ++EXPORT_SYMBOL(clk_get_rate); ++ ++long clk_round_rate(struct clk *clk, unsigned long rate) ++{ ++ return clk->rate; ++} ++EXPORT_SYMBOL(clk_round_rate); ++ ++int clk_set_rate(struct clk *clk, unsigned long rate) ++{ ++ return -EIO; ++} ++EXPORT_SYMBOL(clk_set_rate); +diff --git a/arch/arm/mach-bcm2708/clock.h b/arch/arm/mach-bcm2708/clock.h +new file mode 100644 +index 0000000..5f9d725 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/clock.h +@@ -0,0 +1,24 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/clock.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++struct module; ++ ++struct clk { ++ unsigned long rate; ++}; +diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c +new file mode 100644 +index 0000000..51d147a +--- /dev/null ++++ b/arch/arm/mach-bcm2708/dma.c +@@ -0,0 +1,399 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/dma.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/*****************************************************************************\ ++ * * ++ * Configuration * ++ * * ++\*****************************************************************************/ ++ ++#define CACHE_LINE_MASK 31 ++#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME ++#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ ++ ++/* valid only for channels 0 - 14, 15 has its own base address */ ++#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */ ++#define BCM2708_DMA_CHANIO(dma_base, n) \ ++ ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n))) ++ ++ ++/*****************************************************************************\ ++ * * ++ * DMA Auxilliary Functions * ++ * * ++\*****************************************************************************/ ++ ++/* A DMA buffer on an arbitrary boundary may separate a cache line into a ++ section inside the DMA buffer and another section outside it. ++ Even if we flush DMA buffers from the cache there is always the chance that ++ during a DMA someone will access the part of a cache line that is outside ++ the DMA buffer - which will then bring in unwelcome data. ++ Without being able to dictate our own buffer pools we must insist that ++ DMA buffers consist of a whole number of cache lines. ++*/ ++ ++extern int ++bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) ++{ ++ int i; ++ ++ for (i = 0; i < sg_len; i++) { ++ if (sg_ptr[i].offset & CACHE_LINE_MASK || ++ sg_ptr[i].length & CACHE_LINE_MASK) ++ return 0; ++ } ++ ++ return 1; ++} ++EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); ++ ++extern void ++bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block) ++{ ++ dsb(); /* ARM data synchronization (push) operation */ ++ ++ writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); ++ writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); ++} ++ ++extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) ++{ ++ dsb(); ++ ++ /* ugly busy wait only option for now */ ++ while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) ++ cpu_relax(); ++} ++ ++EXPORT_SYMBOL_GPL(bcm_dma_start); ++ ++/* Complete an ongoing DMA (assuming its results are to be ignored) ++ Does nothing if there is no DMA in progress. ++ This routine waits for the current AXI transfer to complete before ++ terminating the current DMA. If the current transfer is hung on a DREQ used ++ by an uncooperative peripheral the AXI transfer may never complete. In this ++ case the routine times out and return a non-zero error code. ++ Use of this routine doesn't guarantee that the ongoing or aborted DMA ++ does not produce an interrupt. ++*/ ++extern int ++bcm_dma_abort(void __iomem *dma_chan_base) ++{ ++ unsigned long int cs; ++ int rc = 0; ++ ++ cs = readl(dma_chan_base + BCM2708_DMA_CS); ++ ++ if (BCM2708_DMA_ACTIVE & cs) { ++ long int timeout = 10000; ++ ++ /* write 0 to the active bit - pause the DMA */ ++ writel(0, dma_chan_base + BCM2708_DMA_CS); ++ ++ /* wait for any current AXI transfer to complete */ ++ while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) ++ cs = readl(dma_chan_base + BCM2708_DMA_CS); ++ ++ if (0 != (cs & BCM2708_DMA_ISPAUSED)) { ++ /* we'll un-pause when we set of our next DMA */ ++ rc = -ETIMEDOUT; ++ ++ } else if (BCM2708_DMA_ACTIVE & cs) { ++ /* terminate the control block chain */ ++ writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); ++ ++ /* abort the whole DMA */ ++ writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, ++ dma_chan_base + BCM2708_DMA_CS); ++ } ++ } ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_abort); ++ ++ ++/***************************************************************************** \ ++ * * ++ * DMA Manager Device Methods * ++ * * ++\*****************************************************************************/ ++ ++struct vc_dmaman { ++ void __iomem *dma_base; ++ u32 chan_available; /* bitmap of available channels */ ++ u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ ++}; ++ ++static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, ++ u32 chans_available) ++{ ++ dmaman->dma_base = dma_base; ++ dmaman->chan_available = chans_available; ++ dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ ++ dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ ++} ++ ++static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, ++ unsigned preferred_feature_set) ++{ ++ u32 chans; ++ int feature; ++ ++ chans = dmaman->chan_available; ++ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) ++ /* select the subset of available channels with the desired ++ feature so long as some of the candidate channels have that ++ feature */ ++ if ((preferred_feature_set & (1 << feature)) && ++ (chans & dmaman->has_feature[feature])) ++ chans &= dmaman->has_feature[feature]; ++ ++ if (chans) { ++ int chan = 0; ++ /* return the ordinal of the first channel in the bitmap */ ++ while (chans != 0 && (chans & 1) == 0) { ++ chans >>= 1; ++ chan++; ++ } ++ /* claim the channel */ ++ dmaman->chan_available &= ~(1 << chan); ++ return chan; ++ } else ++ return -ENOMEM; ++} ++ ++static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) ++{ ++ if (chan < 0) ++ return -EINVAL; ++ else if ((1 << chan) & dmaman->chan_available) ++ return -EIDRM; ++ else { ++ dmaman->chan_available |= (1 << chan); ++ return 0; ++ } ++} ++ ++/*****************************************************************************\ ++ * * ++ * DMA IRQs * ++ * * ++\*****************************************************************************/ ++ ++static unsigned char bcm_dma_irqs[] = { ++ IRQ_DMA0, ++ IRQ_DMA1, ++ IRQ_DMA2, ++ IRQ_DMA3, ++ IRQ_DMA4, ++ IRQ_DMA5, ++ IRQ_DMA6, ++ IRQ_DMA7, ++ IRQ_DMA8, ++ IRQ_DMA9, ++ IRQ_DMA10, ++ IRQ_DMA11, ++ IRQ_DMA12 ++}; ++ ++ ++/***************************************************************************** \ ++ * * ++ * DMA Manager Monitor * ++ * * ++\*****************************************************************************/ ++ ++static struct device *dmaman_dev; /* we assume there's only one! */ ++ ++extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, ++ void __iomem **out_dma_base, int *out_dma_irq) ++{ ++ if (!dmaman_dev) ++ return -ENODEV; ++ else { ++ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); ++ int rc; ++ ++ device_lock(dmaman_dev); ++ rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); ++ if (rc >= 0) { ++ *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, ++ rc); ++ *out_dma_irq = bcm_dma_irqs[rc]; ++ } ++ device_unlock(dmaman_dev); ++ ++ return rc; ++ } ++} ++EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); ++ ++extern int bcm_dma_chan_free(int channel) ++{ ++ if (dmaman_dev) { ++ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); ++ int rc; ++ ++ device_lock(dmaman_dev); ++ rc = vc_dmaman_chan_free(dmaman, channel); ++ device_unlock(dmaman_dev); ++ ++ return rc; ++ } else ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_chan_free); ++ ++static int dev_dmaman_register(const char *dev_name, struct device *dev) ++{ ++ int rc = dmaman_dev ? -EINVAL : 0; ++ dmaman_dev = dev; ++ return rc; ++} ++ ++static void dev_dmaman_deregister(const char *dev_name, struct device *dev) ++{ ++ dmaman_dev = NULL; ++} ++ ++/*****************************************************************************\ ++ * * ++ * DMA Device * ++ * * ++\*****************************************************************************/ ++ ++static int dmachans = -1; /* module parameter */ ++ ++static int bcm_dmaman_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct vc_dmaman *dmaman; ++ struct resource *dma_res = NULL; ++ void __iomem *dma_base = NULL; ++ int have_dma_region = 0; ++ ++ dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); ++ if (NULL == dmaman) { ++ printk(KERN_ERR DRIVER_NAME ": failed to allocate " ++ "DMA management memory\n"); ++ ret = -ENOMEM; ++ } else { ++ ++ dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (dma_res == NULL) { ++ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " ++ "resource\n"); ++ ret = -ENODEV; ++ } else if (!request_mem_region(dma_res->start, ++ resource_size(dma_res), ++ DRIVER_NAME)) { ++ dev_err(&pdev->dev, "cannot obtain DMA region\n"); ++ ret = -EBUSY; ++ } else { ++ have_dma_region = 1; ++ dma_base = ioremap(dma_res->start, ++ resource_size(dma_res)); ++ if (!dma_base) { ++ dev_err(&pdev->dev, "cannot map DMA region\n"); ++ ret = -ENOMEM; ++ } else { ++ /* use module parameter if one was provided */ ++ if (dmachans > 0) ++ vc_dmaman_init(dmaman, dma_base, ++ dmachans); ++ else ++ vc_dmaman_init(dmaman, dma_base, ++ DEFAULT_DMACHAN_BITMAP); ++ ++ platform_set_drvdata(pdev, dmaman); ++ dev_dmaman_register(DRIVER_NAME, &pdev->dev); ++ ++ printk(KERN_INFO DRIVER_NAME ": DMA manager " ++ "at %p\n", dma_base); ++ } ++ } ++ } ++ if (ret != 0) { ++ if (dma_base) ++ iounmap(dma_base); ++ if (dma_res && have_dma_region) ++ release_mem_region(dma_res->start, ++ resource_size(dma_res)); ++ if (dmaman) ++ kfree(dmaman); ++ } ++ return ret; ++} ++ ++static int bcm_dmaman_remove(struct platform_device *pdev) ++{ ++ struct vc_dmaman *dmaman = platform_get_drvdata(pdev); ++ ++ platform_set_drvdata(pdev, NULL); ++ dev_dmaman_deregister(DRIVER_NAME, &pdev->dev); ++ kfree(dmaman); ++ ++ return 0; ++} ++ ++static struct platform_driver bcm_dmaman_driver = { ++ .probe = bcm_dmaman_probe, ++ .remove = bcm_dmaman_remove, ++ ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++/*****************************************************************************\ ++ * * ++ * Driver init/exit * ++ * * ++\*****************************************************************************/ ++ ++static int __init bcm_dmaman_drv_init(void) ++{ ++ int ret; ++ ++ ret = platform_driver_register(&bcm_dmaman_driver); ++ if (ret != 0) { ++ printk(KERN_ERR DRIVER_NAME ": failed to register " ++ "on platform\n"); ++ } ++ ++ return ret; ++} ++ ++static void __exit bcm_dmaman_drv_exit(void) ++{ ++ platform_driver_unregister(&bcm_dmaman_driver); ++} ++ ++module_init(bcm_dmaman_drv_init); ++module_exit(bcm_dmaman_drv_exit); ++ ++module_param(dmachans, int, 0644); ++ ++MODULE_AUTHOR("Gray Girling "); ++MODULE_DESCRIPTION("DMA channel manager driver"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM"); +diff --git a/arch/arm/mach-bcm2708/include/mach/arm_control.h b/arch/arm/mach-bcm2708/include/mach/arm_control.h +new file mode 100644 +index 0000000..a82bb92 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/arm_control.h +@@ -0,0 +1,419 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/arm_control.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef __BCM2708_ARM_CONTROL_H ++#define __BCM2708_ARM_CONTROL_H ++ ++/* ++ * Definitions and addresses for the ARM CONTROL logic ++ * This file is manually generated. ++ */ ++ ++#define ARM_BASE 0x7E00B000 ++ ++/* Basic configuration */ ++#define ARM_CONTROL0 HW_REGISTER_RW(ARM_BASE+0x000) ++#define ARM_C0_SIZ128M 0x00000000 ++#define ARM_C0_SIZ256M 0x00000001 ++#define ARM_C0_SIZ512M 0x00000002 ++#define ARM_C0_SIZ1G 0x00000003 ++#define ARM_C0_BRESP0 0x00000000 ++#define ARM_C0_BRESP1 0x00000004 ++#define ARM_C0_BRESP2 0x00000008 ++#define ARM_C0_BOOTHI 0x00000010 ++#define ARM_C0_UNUSED05 0x00000020 /* free */ ++#define ARM_C0_FULLPERI 0x00000040 ++#define ARM_C0_UNUSED78 0x00000180 /* free */ ++#define ARM_C0_JTAGMASK 0x00000E00 ++#define ARM_C0_JTAGOFF 0x00000000 ++#define ARM_C0_JTAGBASH 0x00000800 /* Debug on GPIO off */ ++#define ARM_C0_JTAGGPIO 0x00000C00 /* Debug on GPIO on */ ++#define ARM_C0_APROTMSK 0x0000F000 ++#define ARM_C0_DBG0SYNC 0x00010000 /* VPU0 halt sync */ ++#define ARM_C0_DBG1SYNC 0x00020000 /* VPU1 halt sync */ ++#define ARM_C0_SWDBGREQ 0x00040000 /* HW debug request */ ++#define ARM_C0_PASSHALT 0x00080000 /* ARM halt passed to debugger */ ++#define ARM_C0_PRIO_PER 0x00F00000 /* per priority mask */ ++#define ARM_C0_PRIO_L2 0x0F000000 ++#define ARM_C0_PRIO_UC 0xF0000000 ++ ++#define ARM_C0_APROTPASS 0x0000A000 /* Translate 1:1 */ ++#define ARM_C0_APROTUSER 0x00000000 /* Only user mode */ ++#define ARM_C0_APROTSYST 0x0000F000 /* Only system mode */ ++ ++ ++#define ARM_CONTROL1 HW_REGISTER_RW(ARM_BASE+0x440) ++#define ARM_C1_TIMER 0x00000001 /* re-route timer IRQ to VC */ ++#define ARM_C1_MAIL 0x00000002 /* re-route Mail IRQ to VC */ ++#define ARM_C1_BELL0 0x00000004 /* re-route Doorbell 0 to VC */ ++#define ARM_C1_BELL1 0x00000008 /* re-route Doorbell 1 to VC */ ++#define ARM_C1_PERSON 0x00000100 /* peripherals on */ ++#define ARM_C1_REQSTOP 0x00000200 /* ASYNC bridge request stop */ ++ ++#define ARM_STATUS HW_REGISTER_RW(ARM_BASE+0x444) ++#define ARM_S_ACKSTOP 0x80000000 /* Bridge stopped */ ++#define ARM_S_READPEND 0x000003FF /* pending reads counter */ ++#define ARM_S_WRITPEND 0x000FFC00 /* pending writes counter */ ++ ++#define ARM_ERRHALT HW_REGISTER_RW(ARM_BASE+0x448) ++#define ARM_EH_PERIBURST 0x00000001 /* Burst write seen on peri bus */ ++#define ARM_EH_ILLADDRS1 0x00000002 /* Address bits 25-27 error */ ++#define ARM_EH_ILLADDRS2 0x00000004 /* Address bits 31-28 error */ ++#define ARM_EH_VPU0HALT 0x00000008 /* VPU0 halted & in debug mode */ ++#define ARM_EH_VPU1HALT 0x00000010 /* VPU1 halted & in debug mode */ ++#define ARM_EH_ARMHALT 0x00000020 /* ARM in halted debug mode */ ++ ++#define ARM_ID_SECURE HW_REGISTER_RW(ARM_BASE+0x00C) ++#define ARM_ID HW_REGISTER_RW(ARM_BASE+0x44C) ++#define ARM_IDVAL 0x364D5241 ++ ++/* Translation memory */ ++#define ARM_TRANSLATE HW_REGISTER_RW(ARM_BASE+0x100) ++/* 32 locations: 0x100.. 0x17F */ ++/* 32 spare means we CAN go to 64 pages.... */ ++ ++ ++/* Interrupts */ ++#define ARM_IRQ_PEND0 HW_REGISTER_RW(ARM_BASE+0x200) /* Top IRQ bits */ ++#define ARM_I0_TIMER 0x00000001 /* timer IRQ */ ++#define ARM_I0_MAIL 0x00000002 /* Mail IRQ */ ++#define ARM_I0_BELL0 0x00000004 /* Doorbell 0 */ ++#define ARM_I0_BELL1 0x00000008 /* Doorbell 1 */ ++#define ARM_I0_BANK1 0x00000100 /* Bank1 IRQ */ ++#define ARM_I0_BANK2 0x00000200 /* Bank2 IRQ */ ++ ++#define ARM_IRQ_PEND1 HW_REGISTER_RW(ARM_BASE+0x204) /* All bank1 IRQ bits */ ++/* todo: all I1_interrupt sources */ ++#define ARM_IRQ_PEND2 HW_REGISTER_RW(ARM_BASE+0x208) /* All bank2 IRQ bits */ ++/* todo: all I2_interrupt sources */ ++ ++#define ARM_IRQ_FAST HW_REGISTER_RW(ARM_BASE+0x20C) /* FIQ control */ ++#define ARM_IF_INDEX 0x0000007F /* FIQ select */ ++#define ARM_IF_ENABLE 0x00000080 /* FIQ enable */ ++#define ARM_IF_VCMASK 0x0000003F /* FIQ = (index from VC source) */ ++#define ARM_IF_TIMER 0x00000040 /* FIQ = ARM timer */ ++#define ARM_IF_MAIL 0x00000041 /* FIQ = ARM Mail */ ++#define ARM_IF_BELL0 0x00000042 /* FIQ = ARM Doorbell 0 */ ++#define ARM_IF_BELL1 0x00000043 /* FIQ = ARM Doorbell 1 */ ++#define ARM_IF_VP0HALT 0x00000044 /* FIQ = VPU0 Halt seen */ ++#define ARM_IF_VP1HALT 0x00000045 /* FIQ = VPU1 Halt seen */ ++#define ARM_IF_ILLEGAL 0x00000046 /* FIQ = Illegal access seen */ ++ ++#define ARM_IRQ_ENBL1 HW_REGISTER_RW(ARM_BASE+0x210) /* Bank1 enable bits */ ++#define ARM_IRQ_ENBL2 HW_REGISTER_RW(ARM_BASE+0x214) /* Bank2 enable bits */ ++#define ARM_IRQ_ENBL3 HW_REGISTER_RW(ARM_BASE+0x218) /* ARM irqs enable bits */ ++#define ARM_IRQ_DIBL1 HW_REGISTER_RW(ARM_BASE+0x21C) /* Bank1 disable bits */ ++#define ARM_IRQ_DIBL2 HW_REGISTER_RW(ARM_BASE+0x220) /* Bank2 disable bits */ ++#define ARM_IRQ_DIBL3 HW_REGISTER_RW(ARM_BASE+0x224) /* ARM irqs disable bits */ ++#define ARM_IE_TIMER 0x00000001 /* Timer IRQ */ ++#define ARM_IE_MAIL 0x00000002 /* Mail IRQ */ ++#define ARM_IE_BELL0 0x00000004 /* Doorbell 0 */ ++#define ARM_IE_BELL1 0x00000008 /* Doorbell 1 */ ++#define ARM_IE_VP0HALT 0x00000010 /* VPU0 Halt */ ++#define ARM_IE_VP1HALT 0x00000020 /* VPU1 Halt */ ++#define ARM_IE_ILLEGAL 0x00000040 /* Illegal access seen */ ++ ++/* Timer */ ++/* For reg. fields see sp804 spec. */ ++#define ARM_T_LOAD HW_REGISTER_RW(ARM_BASE+0x400) ++#define ARM_T_VALUE HW_REGISTER_RW(ARM_BASE+0x404) ++#define ARM_T_CONTROL HW_REGISTER_RW(ARM_BASE+0x408) ++#define ARM_T_IRQCNTL HW_REGISTER_RW(ARM_BASE+0x40C) ++#define ARM_T_RAWIRQ HW_REGISTER_RW(ARM_BASE+0x410) ++#define ARM_T_MSKIRQ HW_REGISTER_RW(ARM_BASE+0x414) ++#define ARM_T_RELOAD HW_REGISTER_RW(ARM_BASE+0x418) ++#define ARM_T_PREDIV HW_REGISTER_RW(ARM_BASE+0x41c) ++#define ARM_T_FREECNT HW_REGISTER_RW(ARM_BASE+0x420) ++ ++#define TIMER_CTRL_ONESHOT (1 << 0) ++#define TIMER_CTRL_32BIT (1 << 1) ++#define TIMER_CTRL_DIV1 (0 << 2) ++#define TIMER_CTRL_DIV16 (1 << 2) ++#define TIMER_CTRL_DIV256 (2 << 2) ++#define TIMER_CTRL_IE (1 << 5) ++#define TIMER_CTRL_PERIODIC (1 << 6) ++#define TIMER_CTRL_ENABLE (1 << 7) ++#define TIMER_CTRL_DBGHALT (1 << 8) ++#define TIMER_CTRL_ENAFREE (1 << 9) ++#define TIMER_CTRL_FREEDIV_SHIFT 16) ++#define TIMER_CTRL_FREEDIV_MASK 0xff ++ ++/* Semaphores, Doorbells, Mailboxes */ ++#define ARM_SBM_OWN0 (ARM_BASE+0x800) ++#define ARM_SBM_OWN1 (ARM_BASE+0x900) ++#define ARM_SBM_OWN2 (ARM_BASE+0xA00) ++#define ARM_SBM_OWN3 (ARM_BASE+0xB00) ++ ++/* MAILBOXES ++ * Register flags are common across all ++ * owner registers. See end of this section ++ * ++ * Semaphores, Doorbells, Mailboxes Owner 0 ++ * ++ */ ++ ++#define ARM_0_SEMS HW_REGISTER_RW(ARM_SBM_OWN0+0x00) ++#define ARM_0_SEM0 HW_REGISTER_RW(ARM_SBM_OWN0+0x00) ++#define ARM_0_SEM1 HW_REGISTER_RW(ARM_SBM_OWN0+0x04) ++#define ARM_0_SEM2 HW_REGISTER_RW(ARM_SBM_OWN0+0x08) ++#define ARM_0_SEM3 HW_REGISTER_RW(ARM_SBM_OWN0+0x0C) ++#define ARM_0_SEM4 HW_REGISTER_RW(ARM_SBM_OWN0+0x10) ++#define ARM_0_SEM5 HW_REGISTER_RW(ARM_SBM_OWN0+0x14) ++#define ARM_0_SEM6 HW_REGISTER_RW(ARM_SBM_OWN0+0x18) ++#define ARM_0_SEM7 HW_REGISTER_RW(ARM_SBM_OWN0+0x1C) ++#define ARM_0_BELL0 HW_REGISTER_RW(ARM_SBM_OWN0+0x40) ++#define ARM_0_BELL1 HW_REGISTER_RW(ARM_SBM_OWN0+0x44) ++#define ARM_0_BELL2 HW_REGISTER_RW(ARM_SBM_OWN0+0x48) ++#define ARM_0_BELL3 HW_REGISTER_RW(ARM_SBM_OWN0+0x4C) ++/* MAILBOX 0 access in Owner 0 area */ ++/* Some addresses should ONLY be used by owner 0 */ ++#define ARM_0_MAIL0_WRT HW_REGISTER_RW(ARM_SBM_OWN0+0x80) /* .. 0x8C (4 locations) */ ++#define ARM_0_MAIL0_RD HW_REGISTER_RW(ARM_SBM_OWN0+0x80) /* .. 0x8C (4 locations) Normal read */ ++#define ARM_0_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN0+0x90) /* none-pop read */ ++#define ARM_0_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN0+0x94) /* Sender read (only LS 2 bits) */ ++#define ARM_0_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN0+0x98) /* Status read */ ++#define ARM_0_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN0+0x9C) /* Config read/write */ ++/* MAILBOX 1 access in Owner 0 area */ ++/* Owner 0 should only WRITE to this mailbox */ ++#define ARM_0_MAIL1_WRT HW_REGISTER_RW(ARM_SBM_OWN0+0xA0) /* .. 0xAC (4 locations) */ ++/*#define ARM_0_MAIL1_RD HW_REGISTER_RW(ARM_SBM_OWN0+0xA0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_0_MAIL1_POL HW_REGISTER_RW(ARM_SBM_OWN0+0xB0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_0_MAIL1_SND HW_REGISTER_RW(ARM_SBM_OWN0+0xB4) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_0_MAIL1_STA HW_REGISTER_RW(ARM_SBM_OWN0+0xB8) /* Status read */ ++/*#define ARM_0_MAIL1_CNF HW_REGISTER_RW(ARM_SBM_OWN0+0xBC) */ /* DO NOT USE THIS !!!!! */ ++/* General SEM, BELL, MAIL config/status */ ++#define ARM_0_SEMCLRDBG HW_REGISTER_RW(ARM_SBM_OWN0+0xE0) /* semaphore clear/debug register */ ++#define ARM_0_BELLCLRDBG HW_REGISTER_RW(ARM_SBM_OWN0+0xE4) /* Doorbells clear/debug register */ ++#define ARM_0_ALL_IRQS HW_REGISTER_RW(ARM_SBM_OWN0+0xF8) /* ALL interrupts */ ++#define ARM_0_MY_IRQS HW_REGISTER_RW(ARM_SBM_OWN0+0xFC) /* IRQS pending for owner 0 */ ++ ++/* Semaphores, Doorbells, Mailboxes Owner 1 */ ++#define ARM_1_SEMS HW_REGISTER_RW(ARM_SBM_OWN1+0x00) ++#define ARM_1_SEM0 HW_REGISTER_RW(ARM_SBM_OWN1+0x00) ++#define ARM_1_SEM1 HW_REGISTER_RW(ARM_SBM_OWN1+0x04) ++#define ARM_1_SEM2 HW_REGISTER_RW(ARM_SBM_OWN1+0x08) ++#define ARM_1_SEM3 HW_REGISTER_RW(ARM_SBM_OWN1+0x0C) ++#define ARM_1_SEM4 HW_REGISTER_RW(ARM_SBM_OWN1+0x10) ++#define ARM_1_SEM5 HW_REGISTER_RW(ARM_SBM_OWN1+0x14) ++#define ARM_1_SEM6 HW_REGISTER_RW(ARM_SBM_OWN1+0x18) ++#define ARM_1_SEM7 HW_REGISTER_RW(ARM_SBM_OWN1+0x1C) ++#define ARM_1_BELL0 HW_REGISTER_RW(ARM_SBM_OWN1+0x40) ++#define ARM_1_BELL1 HW_REGISTER_RW(ARM_SBM_OWN1+0x44) ++#define ARM_1_BELL2 HW_REGISTER_RW(ARM_SBM_OWN1+0x48) ++#define ARM_1_BELL3 HW_REGISTER_RW(ARM_SBM_OWN1+0x4C) ++/* MAILBOX 0 access in Owner 0 area */ ++/* Owner 1 should only WRITE to this mailbox */ ++#define ARM_1_MAIL0_WRT HW_REGISTER_RW(ARM_SBM_OWN1+0x80) /* .. 0x8C (4 locations) */ ++/*#define ARM_1_MAIL0_RD HW_REGISTER_RW(ARM_SBM_OWN1+0x80) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_1_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN1+0x90) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_1_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN1+0x94) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_1_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN1+0x98) /* Status read */ ++/*#define ARM_1_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN1+0x9C) */ /* DO NOT USE THIS !!!!! */ ++/* MAILBOX 1 access in Owner 0 area */ ++#define ARM_1_MAIL1_WRT HW_REGISTER_RW(ARM_SBM_OWN1+0xA0) /* .. 0xAC (4 locations) */ ++#define ARM_1_MAIL1_RD HW_REGISTER_RW(ARM_SBM_OWN1+0xA0) /* .. 0xAC (4 locations) Normal read */ ++#define ARM_1_MAIL1_POL HW_REGISTER_RW(ARM_SBM_OWN1+0xB0) /* none-pop read */ ++#define ARM_1_MAIL1_SND HW_REGISTER_RW(ARM_SBM_OWN1+0xB4) /* Sender read (only LS 2 bits) */ ++#define ARM_1_MAIL1_STA HW_REGISTER_RW(ARM_SBM_OWN1+0xB8) /* Status read */ ++#define ARM_1_MAIL1_CNF HW_REGISTER_RW(ARM_SBM_OWN1+0xBC) ++/* General SEM, BELL, MAIL config/status */ ++#define ARM_1_SEMCLRDBG HW_REGISTER_RW(ARM_SBM_OWN1+0xE0) /* semaphore clear/debug register */ ++#define ARM_1_BELLCLRDBG HW_REGISTER_RW(ARM_SBM_OWN1+0xE4) /* Doorbells clear/debug register */ ++#define ARM_1_MY_IRQS HW_REGISTER_RW(ARM_SBM_OWN1+0xFC) /* IRQS pending for owner 1 */ ++#define ARM_1_ALL_IRQS HW_REGISTER_RW(ARM_SBM_OWN1+0xF8) /* ALL interrupts */ ++ ++/* Semaphores, Doorbells, Mailboxes Owner 2 */ ++#define ARM_2_SEMS HW_REGISTER_RW(ARM_SBM_OWN2+0x00) ++#define ARM_2_SEM0 HW_REGISTER_RW(ARM_SBM_OWN2+0x00) ++#define ARM_2_SEM1 HW_REGISTER_RW(ARM_SBM_OWN2+0x04) ++#define ARM_2_SEM2 HW_REGISTER_RW(ARM_SBM_OWN2+0x08) ++#define ARM_2_SEM3 HW_REGISTER_RW(ARM_SBM_OWN2+0x0C) ++#define ARM_2_SEM4 HW_REGISTER_RW(ARM_SBM_OWN2+0x10) ++#define ARM_2_SEM5 HW_REGISTER_RW(ARM_SBM_OWN2+0x14) ++#define ARM_2_SEM6 HW_REGISTER_RW(ARM_SBM_OWN2+0x18) ++#define ARM_2_SEM7 HW_REGISTER_RW(ARM_SBM_OWN2+0x1C) ++#define ARM_2_BELL0 HW_REGISTER_RW(ARM_SBM_OWN2+0x40) ++#define ARM_2_BELL1 HW_REGISTER_RW(ARM_SBM_OWN2+0x44) ++#define ARM_2_BELL2 HW_REGISTER_RW(ARM_SBM_OWN2+0x48) ++#define ARM_2_BELL3 HW_REGISTER_RW(ARM_SBM_OWN2+0x4C) ++/* MAILBOX 0 access in Owner 2 area */ ++/* Owner 2 should only WRITE to this mailbox */ ++#define ARM_2_MAIL0_WRT HW_REGISTER_RW(ARM_SBM_OWN2+0x80) /* .. 0x8C (4 locations) */ ++/*#define ARM_2_MAIL0_RD HW_REGISTER_RW(ARM_SBM_OWN2+0x80) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_2_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN2+0x90) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_2_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN2+0x94) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_2_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN2+0x98) /* Status read */ ++/*#define ARM_2_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN2+0x9C) */ /* DO NOT USE THIS !!!!! */ ++/* MAILBOX 1 access in Owner 2 area */ ++/* Owner 2 should only WRITE to this mailbox */ ++#define ARM_2_MAIL1_WRT HW_REGISTER_RW(ARM_SBM_OWN2+0xA0) /* .. 0xAC (4 locations) */ ++/*#define ARM_2_MAIL1_RD HW_REGISTER_RW(ARM_SBM_OWN2+0xA0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_2_MAIL1_POL HW_REGISTER_RW(ARM_SBM_OWN2+0xB0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_2_MAIL1_SND HW_REGISTER_RW(ARM_SBM_OWN2+0xB4) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_2_MAIL1_STA HW_REGISTER_RW(ARM_SBM_OWN2+0xB8) /* Status read */ ++/*#define ARM_2_MAIL1_CNF HW_REGISTER_RW(ARM_SBM_OWN2+0xBC) */ /* DO NOT USE THIS !!!!! */ ++/* General SEM, BELL, MAIL config/status */ ++#define ARM_2_SEMCLRDBG HW_REGISTER_RW(ARM_SBM_OWN2+0xE0) /* semaphore clear/debug register */ ++#define ARM_2_BELLCLRDBG HW_REGISTER_RW(ARM_SBM_OWN2+0xE4) /* Doorbells clear/debug register */ ++#define ARM_2_MY_IRQS HW_REGISTER_RW(ARM_SBM_OWN2+0xFC) /* IRQS pending for owner 2 */ ++#define ARM_2_ALL_IRQS HW_REGISTER_RW(ARM_SBM_OWN2+0xF8) /* ALL interrupts */ ++ ++/* Semaphores, Doorbells, Mailboxes Owner 3 */ ++#define ARM_3_SEMS HW_REGISTER_RW(ARM_SBM_OWN3+0x00) ++#define ARM_3_SEM0 HW_REGISTER_RW(ARM_SBM_OWN3+0x00) ++#define ARM_3_SEM1 HW_REGISTER_RW(ARM_SBM_OWN3+0x04) ++#define ARM_3_SEM2 HW_REGISTER_RW(ARM_SBM_OWN3+0x08) ++#define ARM_3_SEM3 HW_REGISTER_RW(ARM_SBM_OWN3+0x0C) ++#define ARM_3_SEM4 HW_REGISTER_RW(ARM_SBM_OWN3+0x10) ++#define ARM_3_SEM5 HW_REGISTER_RW(ARM_SBM_OWN3+0x14) ++#define ARM_3_SEM6 HW_REGISTER_RW(ARM_SBM_OWN3+0x18) ++#define ARM_3_SEM7 HW_REGISTER_RW(ARM_SBM_OWN3+0x1C) ++#define ARM_3_BELL0 HW_REGISTER_RW(ARM_SBM_OWN3+0x40) ++#define ARM_3_BELL1 HW_REGISTER_RW(ARM_SBM_OWN3+0x44) ++#define ARM_3_BELL2 HW_REGISTER_RW(ARM_SBM_OWN3+0x48) ++#define ARM_3_BELL3 HW_REGISTER_RW(ARM_SBM_OWN3+0x4C) ++/* MAILBOX 0 access in Owner 3 area */ ++/* Owner 3 should only WRITE to this mailbox */ ++#define ARM_3_MAIL0_WRT HW_REGISTER_RW(ARM_SBM_OWN3+0x80) /* .. 0x8C (4 locations) */ ++/*#define ARM_3_MAIL0_RD HW_REGISTER_RW(ARM_SBM_OWN3+0x80) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_3_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN3+0x90) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_3_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN3+0x94) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_3_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN3+0x98) /* Status read */ ++/*#define ARM_3_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN3+0x9C) */ /* DO NOT USE THIS !!!!! */ ++/* MAILBOX 1 access in Owner 3 area */ ++/* Owner 3 should only WRITE to this mailbox */ ++#define ARM_3_MAIL1_WRT HW_REGISTER_RW(ARM_SBM_OWN3+0xA0) /* .. 0xAC (4 locations) */ ++/*#define ARM_3_MAIL1_RD HW_REGISTER_RW(ARM_SBM_OWN3+0xA0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_3_MAIL1_POL HW_REGISTER_RW(ARM_SBM_OWN3+0xB0) */ /* DO NOT USE THIS !!!!! */ ++/*#define ARM_3_MAIL1_SND HW_REGISTER_RW(ARM_SBM_OWN3+0xB4) */ /* DO NOT USE THIS !!!!! */ ++#define ARM_3_MAIL1_STA HW_REGISTER_RW(ARM_SBM_OWN3+0xB8) /* Status read */ ++/*#define ARM_3_MAIL1_CNF HW_REGISTER_RW(ARM_SBM_OWN3+0xBC) */ /* DO NOT USE THIS !!!!! */ ++/* General SEM, BELL, MAIL config/status */ ++#define ARM_3_SEMCLRDBG HW_REGISTER_RW(ARM_SBM_OWN3+0xE0) /* semaphore clear/debug register */ ++#define ARM_3_BELLCLRDBG HW_REGISTER_RW(ARM_SBM_OWN3+0xE4) /* Doorbells clear/debug register */ ++#define ARM_3_MY_IRQS HW_REGISTER_RW(ARM_SBM_OWN3+0xFC) /* IRQS pending for owner 3 */ ++#define ARM_3_ALL_IRQS HW_REGISTER_RW(ARM_SBM_OWN3+0xF8) /* ALL interrupts */ ++ ++ ++ ++/* Mailbox flags. Valid for all owners */ ++ ++/* Mailbox status register (...0x98) */ ++#define ARM_MS_FULL 0x80000000 ++#define ARM_MS_EMPTY 0x40000000 ++#define ARM_MS_LEVEL 0x400000FF /* Max. value depdnds on mailbox depth parameter */ ++ ++/* MAILBOX config/status register (...0x9C) */ ++/* ANY write to this register clears the error bits! */ ++#define ARM_MC_IHAVEDATAIRQEN 0x00000001 /* mailbox irq enable: has data */ ++#define ARM_MC_IHAVESPACEIRQEN 0x00000002 /* mailbox irq enable: has space */ ++#define ARM_MC_OPPISEMPTYIRQEN 0x00000004 /* mailbox irq enable: Opp. is empty */ ++#define ARM_MC_MAIL_CLEAR 0x00000008 /* mailbox clear write 1, then 0 */ ++#define ARM_MC_IHAVEDATAIRQPEND 0x00000010 /* mailbox irq pending: has space */ ++#define ARM_MC_IHAVESPACEIRQPEND 0x00000020 /* mailbox irq pending: Opp. is empty */ ++#define ARM_MC_OPPISEMPTYIRQPEND 0x00000040 /* mailbox irq pending */ ++/* Bit 7 is unused */ ++#define ARM_MC_ERRNOOWN 0x00000100 /* error : none owner read from mailbox */ ++#define ARM_MC_ERROVERFLW 0x00000200 /* error : write to fill mailbox */ ++#define ARM_MC_ERRUNDRFLW 0x00000400 /* error : read from empty mailbox */ ++ ++/* Semaphore clear/debug register (...0xE0) */ ++#define ARM_SD_OWN0 0x00000003 /* Owner of sem 0 */ ++#define ARM_SD_OWN1 0x0000000C /* Owner of sem 1 */ ++#define ARM_SD_OWN2 0x00000030 /* Owner of sem 2 */ ++#define ARM_SD_OWN3 0x000000C0 /* Owner of sem 3 */ ++#define ARM_SD_OWN4 0x00000300 /* Owner of sem 4 */ ++#define ARM_SD_OWN5 0x00000C00 /* Owner of sem 5 */ ++#define ARM_SD_OWN6 0x00003000 /* Owner of sem 6 */ ++#define ARM_SD_OWN7 0x0000C000 /* Owner of sem 7 */ ++#define ARM_SD_SEM0 0x00010000 /* Status of sem 0 */ ++#define ARM_SD_SEM1 0x00020000 /* Status of sem 1 */ ++#define ARM_SD_SEM2 0x00040000 /* Status of sem 2 */ ++#define ARM_SD_SEM3 0x00080000 /* Status of sem 3 */ ++#define ARM_SD_SEM4 0x00100000 /* Status of sem 4 */ ++#define ARM_SD_SEM5 0x00200000 /* Status of sem 5 */ ++#define ARM_SD_SEM6 0x00400000 /* Status of sem 6 */ ++#define ARM_SD_SEM7 0x00800000 /* Status of sem 7 */ ++ ++/* Doorbells clear/debug register (...0xE4) */ ++#define ARM_BD_OWN0 0x00000003 /* Owner of doorbell 0 */ ++#define ARM_BD_OWN1 0x0000000C /* Owner of doorbell 1 */ ++#define ARM_BD_OWN2 0x00000030 /* Owner of doorbell 2 */ ++#define ARM_BD_OWN3 0x000000C0 /* Owner of doorbell 3 */ ++#define ARM_BD_BELL0 0x00000100 /* Status of doorbell 0 */ ++#define ARM_BD_BELL1 0x00000200 /* Status of doorbell 1 */ ++#define ARM_BD_BELL2 0x00000400 /* Status of doorbell 2 */ ++#define ARM_BD_BELL3 0x00000800 /* Status of doorbell 3 */ ++ ++/* MY IRQS register (...0xF8) */ ++#define ARM_MYIRQ_BELL 0x00000001 /* This owner has a doorbell IRQ */ ++#define ARM_MYIRQ_MAIL 0x00000002 /* This owner has a mailbox IRQ */ ++ ++/* ALL IRQS register (...0xF8) */ ++#define ARM_AIS_BELL0 0x00000001 /* Doorbell 0 IRQ pending */ ++#define ARM_AIS_BELL1 0x00000002 /* Doorbell 1 IRQ pending */ ++#define ARM_AIS_BELL2 0x00000004 /* Doorbell 2 IRQ pending */ ++#define ARM_AIS_BELL3 0x00000008 /* Doorbell 3 IRQ pending */ ++#define ARM_AIS0_HAVEDATA 0x00000010 /* MAIL 0 has data IRQ pending */ ++#define ARM_AIS0_HAVESPAC 0x00000020 /* MAIL 0 has space IRQ pending */ ++#define ARM_AIS0_OPPEMPTY 0x00000040 /* MAIL 0 opposite is empty IRQ */ ++#define ARM_AIS1_HAVEDATA 0x00000080 /* MAIL 1 has data IRQ pending */ ++#define ARM_AIS1_HAVESPAC 0x00000100 /* MAIL 1 has space IRQ pending */ ++#define ARM_AIS1_OPPEMPTY 0x00000200 /* MAIL 1 opposite is empty IRQ */ ++/* Note that bell-0, bell-1 and MAIL0 IRQ go only to the ARM */ ++/* Whilst that bell-2, bell-3 and MAIL1 IRQ go only to the VC */ ++/* */ ++/* ARM JTAG BASH */ ++/* */ ++#define AJB_BASE 0x7e2000c0 ++ ++#define AJBCONF HW_REGISTER_RW(AJB_BASE+0x00) ++#define AJB_BITS0 0x000000 ++#define AJB_BITS4 0x000004 ++#define AJB_BITS8 0x000008 ++#define AJB_BITS12 0x00000C ++#define AJB_BITS16 0x000010 ++#define AJB_BITS20 0x000014 ++#define AJB_BITS24 0x000018 ++#define AJB_BITS28 0x00001C ++#define AJB_BITS32 0x000020 ++#define AJB_BITS34 0x000022 ++#define AJB_OUT_MS 0x000040 ++#define AJB_OUT_LS 0x000000 ++#define AJB_INV_CLK 0x000080 ++#define AJB_D0_RISE 0x000100 ++#define AJB_D0_FALL 0x000000 ++#define AJB_D1_RISE 0x000200 ++#define AJB_D1_FALL 0x000000 ++#define AJB_IN_RISE 0x000400 ++#define AJB_IN_FALL 0x000000 ++#define AJB_ENABLE 0x000800 ++#define AJB_HOLD0 0x000000 ++#define AJB_HOLD1 0x001000 ++#define AJB_HOLD2 0x002000 ++#define AJB_HOLD3 0x003000 ++#define AJB_RESETN 0x004000 ++#define AJB_CLKSHFT 16 ++#define AJB_BUSY 0x80000000 ++#define AJBTMS HW_REGISTER_RW(AJB_BASE+0x04) ++#define AJBTDI HW_REGISTER_RW(AJB_BASE+0x08) ++#define AJBTDO HW_REGISTER_RW(AJB_BASE+0x0c) ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/include/mach/arm_power.h b/arch/arm/mach-bcm2708/include/mach/arm_power.h +new file mode 100644 +index 0000000..d3bf245 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/arm_power.h +@@ -0,0 +1,62 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/include/mach/arm_power.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef _ARM_POWER_H ++#define _ARM_POWER_H ++ ++/* Use meaningful names on each side */ ++#ifdef __VIDEOCORE__ ++#define PREFIX(x) ARM_##x ++#else ++#define PREFIX(x) BCM_##x ++#endif ++ ++enum { ++ PREFIX(POWER_SDCARD_BIT), ++ PREFIX(POWER_UART_BIT), ++ PREFIX(POWER_MINIUART_BIT), ++ PREFIX(POWER_USB_BIT), ++ PREFIX(POWER_I2C0_BIT), ++ PREFIX(POWER_I2C1_BIT), ++ PREFIX(POWER_I2C2_BIT), ++ PREFIX(POWER_SPI_BIT), ++ PREFIX(POWER_CCP2TX_BIT), ++ PREFIX(POWER_DSI_BIT), ++ ++ PREFIX(POWER_MAX) ++}; ++ ++enum { ++ PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), ++ PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), ++ PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), ++ PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), ++ PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), ++ PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), ++ PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), ++ PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), ++ PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), ++ PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), ++ ++ PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, ++ PREFIX(POWER_NONE) = 0 ++}; ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/include/mach/clkdev.h b/arch/arm/mach-bcm2708/include/mach/clkdev.h +new file mode 100644 +index 0000000..04b37a8 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/clkdev.h +@@ -0,0 +1,7 @@ ++#ifndef __ASM_MACH_CLKDEV_H ++#define __ASM_MACH_CLKDEV_H ++ ++#define __clk_get(clk) ({ 1; }) ++#define __clk_put(clk) do { } while (0) ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/include/mach/debug-macro.S b/arch/arm/mach-bcm2708/include/mach/debug-macro.S +new file mode 100644 +index 0000000..b24304a +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/debug-macro.S +@@ -0,0 +1,22 @@ ++/* arch/arm/mach-bcm2708/include/mach/debug-macro.S ++ * ++ * Debugging macro include header ++ * ++ * Copyright (C) 2010 Broadcom ++ * Copyright (C) 1994-1999 Russell King ++ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++*/ ++ ++#include ++ ++ .macro addruart, rp, rv, tmp ++ ldr \rp, =UART0_BASE ++ ldr \rv, =IO_ADDRESS(UART0_BASE) ++ .endm ++ ++#include +diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h +new file mode 100644 +index 0000000..f2568d4 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/dma.h +@@ -0,0 +1,88 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/include/mach/dma.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++ ++#ifndef _MACH_BCM2708_DMA_H ++#define _MACH_BCM2708_DMA_H ++ ++#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma" ++ ++/* DMA CS Control and Status bits */ ++#define BCM2708_DMA_ACTIVE (1 << 0) ++#define BCM2708_DMA_INT (1 << 2) ++#define BCM2708_DMA_ISPAUSED (1 << 4) /* Pause requested or not active */ ++#define BCM2708_DMA_ISHELD (1 << 5) /* Is held by DREQ flow control */ ++#define BCM2708_DMA_ERR (1 << 8) ++#define BCM2708_DMA_ABORT (1 << 30) /* stop current CB, go to next, WO */ ++#define BCM2708_DMA_RESET (1 << 31) /* WO, self clearing */ ++ ++/* DMA control block "info" field bits */ ++#define BCM2708_DMA_INT_EN (1 << 0) ++#define BCM2708_DMA_TDMODE (1 << 1) ++#define BCM2708_DMA_WAIT_RESP (1 << 3) ++#define BCM2708_DMA_D_INC (1 << 4) ++#define BCM2708_DMA_D_WIDTH (1 << 5) ++#define BCM2708_DMA_D_DREQ (1 << 6) ++#define BCM2708_DMA_S_INC (1 << 8) ++#define BCM2708_DMA_S_WIDTH (1 << 9) ++#define BCM2708_DMA_S_DREQ (1 << 10) ++ ++#define BCM2708_DMA_BURST(x) (((x)&0xf) << 12) ++#define BCM2708_DMA_PER_MAP(x) ((x) << 16) ++#define BCM2708_DMA_WAITS(x) (((x)&0x1f) << 21) ++ ++#define BCM2708_DMA_DREQ_EMMC 11 ++#define BCM2708_DMA_DREQ_SDHOST 13 ++ ++#define BCM2708_DMA_CS 0x00 /* Control and Status */ ++#define BCM2708_DMA_ADDR 0x04 ++/* the current control block appears in the following registers - read only */ ++#define BCM2708_DMA_INFO 0x08 ++#define BCM2708_DMA_SOURCE_AD 0x0c ++#define BCM2708_DMA_DEST_AD 0x10 ++#define BCM2708_DMA_NEXTCB 0x1C ++#define BCM2708_DMA_DEBUG 0x20 ++ ++#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS) ++#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR) ++ ++#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) ++ ++struct bcm2708_dma_cb { ++ unsigned long info; ++ unsigned long src; ++ unsigned long dst; ++ unsigned long length; ++ unsigned long stride; ++ unsigned long next; ++ unsigned long pad[2]; ++}; ++ ++extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); ++extern void bcm_dma_start(void __iomem *dma_chan_base, ++ dma_addr_t control_block); ++extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); ++extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); ++ ++/* When listing features we can ask for when allocating DMA channels give ++ those with higher priority smaller ordinal numbers */ ++#define BCM_DMA_FEATURE_FAST_ORD 0 ++#define BCM_DMA_FEATURE_BULK_ORD 1 ++#define BCM_DMA_FEATURE_FAST (1< ++ ++ .macro disable_fiq ++ .endm ++ ++ .macro get_irqnr_preamble, base, tmp ++ ldr \base, =IO_ADDRESS(ARMCTRL_IC_BASE) ++ .endm ++ ++ .macro arch_ret_to_user, tmp1, tmp2 ++ .endm ++ ++ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ++ /* get masked status */ ++ ldr \irqstat, [\base, #(ARM_IRQ_PEND0 - ARMCTRL_IC_BASE)] ++ mov \irqnr, #(ARM_IRQ0_BASE + 31) ++ and \tmp, \irqstat, #0x300 @ save bits 8 and 9 ++ /* clear bits 8 and 9, and test */ ++ bics \irqstat, \irqstat, #0x300 ++ bne 1010f ++ ++ tst \tmp, #0x100 ++ ldrne \irqstat, [\base, #(ARM_IRQ_PEND1 - ARMCTRL_IC_BASE)] ++ movne \irqnr, #(ARM_IRQ1_BASE + 31) ++ @ Mask out the interrupts also present in PEND0 - see SW-5809 ++ bicne \irqstat, #((1<<7) | (1<<9) | (1<<10)) ++ bicne \irqstat, #((1<<18) | (1<<19)) ++ bne 1010f ++ ++ tst \tmp, #0x200 ++ ldrne \irqstat, [\base, #(ARM_IRQ_PEND2 - ARMCTRL_IC_BASE)] ++ movne \irqnr, #(ARM_IRQ2_BASE + 31) ++ @ Mask out the interrupts also present in PEND0 - see SW-5809 ++ bicne \irqstat, #((1<<21) | (1<<22) | (1<<23) | (1<<24) | (1<<25)) ++ bicne \irqstat, #((1<<30)) ++ beq 1020f ++ ++1010: ++ @ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1)) ++ @ N.B. CLZ is an ARM5 instruction. ++ sub \tmp, \irqstat, #1 ++ eor \irqstat, \irqstat, \tmp ++ clz \tmp, \irqstat ++ sub \irqnr, \tmp ++ ++1020: @ EQ will be set if no irqs pending ++ ++ .endm +diff --git a/arch/arm/mach-bcm2708/include/mach/frc.h b/arch/arm/mach-bcm2708/include/mach/frc.h +new file mode 100644 +index 0000000..dd51e07 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/frc.h +@@ -0,0 +1,38 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/timex.h ++ * ++ * BCM2708 free running counter (timer) ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef _MACH_FRC_H ++#define _MACH_FRC_H ++ ++#define FRC_TICK_RATE (1000000) ++ ++/*! Free running counter incrementing at the CLOCK_TICK_RATE ++ (slightly faster than frc_clock_ticks63() ++ */ ++extern unsigned long frc_clock_ticks32(void); ++ ++/*! Free running counter incrementing at the CLOCK_TICK_RATE ++ * Note - top bit should be ignored (see cnt32_to_63) ++ */ ++extern unsigned long long frc_clock_ticks63(void); ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/include/mach/hardware.h b/arch/arm/mach-bcm2708/include/mach/hardware.h +new file mode 100644 +index 0000000..c2954e8 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/hardware.h +@@ -0,0 +1,28 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/hardware.h ++ * ++ * This file contains the hardware definitions of the BCM2708 devices. ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __ASM_ARCH_HARDWARE_H ++#define __ASM_ARCH_HARDWARE_H ++ ++#include ++#include ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/include/mach/io.h b/arch/arm/mach-bcm2708/include/mach/io.h +new file mode 100644 +index 0000000..e6eb84d +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/io.h +@@ -0,0 +1,27 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/io.h ++ * ++ * Copyright (C) 2003 ARM Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __ASM_ARM_ARCH_IO_H ++#define __ASM_ARM_ARCH_IO_H ++ ++#define IO_SPACE_LIMIT 0xffffffff ++ ++#define __io(a) __typesafe_io(a) ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/include/mach/irqs.h b/arch/arm/mach-bcm2708/include/mach/irqs.h +new file mode 100644 +index 0000000..3a88a1a +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/irqs.h +@@ -0,0 +1,196 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/irqs.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * Copyright (C) 2003 ARM Limited ++ * Copyright (C) 2000 Deep Blue Solutions Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef _BCM2708_IRQS_H_ ++#define _BCM2708_IRQS_H_ ++ ++#include ++ ++/* ++ * IRQ interrupts definitions are the same as the INT definitions ++ * held within platform.h ++ */ ++#define IRQ_ARMCTRL_START 0 ++#define IRQ_TIMER0 (IRQ_ARMCTRL_START + INTERRUPT_TIMER0) ++#define IRQ_TIMER1 (IRQ_ARMCTRL_START + INTERRUPT_TIMER1) ++#define IRQ_TIMER2 (IRQ_ARMCTRL_START + INTERRUPT_TIMER2) ++#define IRQ_TIMER3 (IRQ_ARMCTRL_START + INTERRUPT_TIMER3) ++#define IRQ_CODEC0 (IRQ_ARMCTRL_START + INTERRUPT_CODEC0) ++#define IRQ_CODEC1 (IRQ_ARMCTRL_START + INTERRUPT_CODEC1) ++#define IRQ_CODEC2 (IRQ_ARMCTRL_START + INTERRUPT_CODEC2) ++#define IRQ_JPEG (IRQ_ARMCTRL_START + INTERRUPT_JPEG) ++#define IRQ_ISP (IRQ_ARMCTRL_START + INTERRUPT_ISP) ++#define IRQ_USB (IRQ_ARMCTRL_START + INTERRUPT_USB) ++#define IRQ_3D (IRQ_ARMCTRL_START + INTERRUPT_3D) ++#define IRQ_TRANSPOSER (IRQ_ARMCTRL_START + INTERRUPT_TRANSPOSER) ++#define IRQ_MULTICORESYNC0 (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC0) ++#define IRQ_MULTICORESYNC1 (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC1) ++#define IRQ_MULTICORESYNC2 (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC2) ++#define IRQ_MULTICORESYNC3 (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC3) ++#define IRQ_DMA0 (IRQ_ARMCTRL_START + INTERRUPT_DMA0) ++#define IRQ_DMA1 (IRQ_ARMCTRL_START + INTERRUPT_DMA1) ++#define IRQ_DMA2 (IRQ_ARMCTRL_START + INTERRUPT_DMA2) ++#define IRQ_DMA3 (IRQ_ARMCTRL_START + INTERRUPT_DMA3) ++#define IRQ_DMA4 (IRQ_ARMCTRL_START + INTERRUPT_DMA4) ++#define IRQ_DMA5 (IRQ_ARMCTRL_START + INTERRUPT_DMA5) ++#define IRQ_DMA6 (IRQ_ARMCTRL_START + INTERRUPT_DMA6) ++#define IRQ_DMA7 (IRQ_ARMCTRL_START + INTERRUPT_DMA7) ++#define IRQ_DMA8 (IRQ_ARMCTRL_START + INTERRUPT_DMA8) ++#define IRQ_DMA9 (IRQ_ARMCTRL_START + INTERRUPT_DMA9) ++#define IRQ_DMA10 (IRQ_ARMCTRL_START + INTERRUPT_DMA10) ++#define IRQ_DMA11 (IRQ_ARMCTRL_START + INTERRUPT_DMA11) ++#define IRQ_DMA12 (IRQ_ARMCTRL_START + INTERRUPT_DMA12) ++#define IRQ_AUX (IRQ_ARMCTRL_START + INTERRUPT_AUX) ++#define IRQ_ARM (IRQ_ARMCTRL_START + INTERRUPT_ARM) ++#define IRQ_VPUDMA (IRQ_ARMCTRL_START + INTERRUPT_VPUDMA) ++#define IRQ_HOSTPORT (IRQ_ARMCTRL_START + INTERRUPT_HOSTPORT) ++#define IRQ_VIDEOSCALER (IRQ_ARMCTRL_START + INTERRUPT_VIDEOSCALER) ++#define IRQ_CCP2TX (IRQ_ARMCTRL_START + INTERRUPT_CCP2TX) ++#define IRQ_SDC (IRQ_ARMCTRL_START + INTERRUPT_SDC) ++#define IRQ_DSI0 (IRQ_ARMCTRL_START + INTERRUPT_DSI0) ++#define IRQ_AVE (IRQ_ARMCTRL_START + INTERRUPT_AVE) ++#define IRQ_CAM0 (IRQ_ARMCTRL_START + INTERRUPT_CAM0) ++#define IRQ_CAM1 (IRQ_ARMCTRL_START + INTERRUPT_CAM1) ++#define IRQ_HDMI0 (IRQ_ARMCTRL_START + INTERRUPT_HDMI0) ++#define IRQ_HDMI1 (IRQ_ARMCTRL_START + INTERRUPT_HDMI1) ++#define IRQ_PIXELVALVE1 (IRQ_ARMCTRL_START + INTERRUPT_PIXELVALVE1) ++#define IRQ_I2CSPISLV (IRQ_ARMCTRL_START + INTERRUPT_I2CSPISLV) ++#define IRQ_DSI1 (IRQ_ARMCTRL_START + INTERRUPT_DSI1) ++#define IRQ_PWA0 (IRQ_ARMCTRL_START + INTERRUPT_PWA0) ++#define IRQ_PWA1 (IRQ_ARMCTRL_START + INTERRUPT_PWA1) ++#define IRQ_CPR (IRQ_ARMCTRL_START + INTERRUPT_CPR) ++#define IRQ_SMI (IRQ_ARMCTRL_START + INTERRUPT_SMI) ++#define IRQ_GPIO0 (IRQ_ARMCTRL_START + INTERRUPT_GPIO0) ++#define IRQ_GPIO1 (IRQ_ARMCTRL_START + INTERRUPT_GPIO1) ++#define IRQ_GPIO2 (IRQ_ARMCTRL_START + INTERRUPT_GPIO2) ++#define IRQ_GPIO3 (IRQ_ARMCTRL_START + INTERRUPT_GPIO3) ++#define IRQ_I2C (IRQ_ARMCTRL_START + INTERRUPT_I2C) ++#define IRQ_SPI (IRQ_ARMCTRL_START + INTERRUPT_SPI) ++#define IRQ_I2SPCM (IRQ_ARMCTRL_START + INTERRUPT_I2SPCM) ++#define IRQ_SDIO (IRQ_ARMCTRL_START + INTERRUPT_SDIO) ++#define IRQ_UART (IRQ_ARMCTRL_START + INTERRUPT_UART) ++#define IRQ_SLIMBUS (IRQ_ARMCTRL_START + INTERRUPT_SLIMBUS) ++#define IRQ_VEC (IRQ_ARMCTRL_START + INTERRUPT_VEC) ++#define IRQ_CPG (IRQ_ARMCTRL_START + INTERRUPT_CPG) ++#define IRQ_RNG (IRQ_ARMCTRL_START + INTERRUPT_RNG) ++#define IRQ_ARASANSDIO (IRQ_ARMCTRL_START + INTERRUPT_ARASANSDIO) ++#define IRQ_AVSPMON (IRQ_ARMCTRL_START + INTERRUPT_AVSPMON) ++ ++#define IRQ_ARM_TIMER (IRQ_ARMCTRL_START + INTERRUPT_ARM_TIMER) ++#define IRQ_ARM_MAILBOX (IRQ_ARMCTRL_START + INTERRUPT_ARM_MAILBOX) ++#define IRQ_ARM_DOORBELL_0 (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_0) ++#define IRQ_ARM_DOORBELL_1 (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_1) ++#define IRQ_VPU0_HALTED (IRQ_ARMCTRL_START + INTERRUPT_VPU0_HALTED) ++#define IRQ_VPU1_HALTED (IRQ_ARMCTRL_START + INTERRUPT_VPU1_HALTED) ++#define IRQ_ILLEGAL_TYPE0 (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE0) ++#define IRQ_ILLEGAL_TYPE1 (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE1) ++#define IRQ_PENDING1 (IRQ_ARMCTRL_START + INTERRUPT_PENDING1) ++#define IRQ_PENDING2 (IRQ_ARMCTRL_START + INTERRUPT_PENDING2) ++ ++/* ++ * FIQ interrupts definitions are the same as the INT definitions. ++ */ ++#define FIQ_TIMER0 INT_TIMER0 ++#define FIQ_TIMER1 INT_TIMER1 ++#define FIQ_TIMER2 INT_TIMER2 ++#define FIQ_TIMER3 INT_TIMER3 ++#define FIQ_CODEC0 INT_CODEC0 ++#define FIQ_CODEC1 INT_CODEC1 ++#define FIQ_CODEC2 INT_CODEC2 ++#define FIQ_JPEG INT_JPEG ++#define FIQ_ISP INT_ISP ++#define FIQ_USB INT_USB ++#define FIQ_3D INT_3D ++#define FIQ_TRANSPOSER INT_TRANSPOSER ++#define FIQ_MULTICORESYNC0 INT_MULTICORESYNC0 ++#define FIQ_MULTICORESYNC1 INT_MULTICORESYNC1 ++#define FIQ_MULTICORESYNC2 INT_MULTICORESYNC2 ++#define FIQ_MULTICORESYNC3 INT_MULTICORESYNC3 ++#define FIQ_DMA0 INT_DMA0 ++#define FIQ_DMA1 INT_DMA1 ++#define FIQ_DMA2 INT_DMA2 ++#define FIQ_DMA3 INT_DMA3 ++#define FIQ_DMA4 INT_DMA4 ++#define FIQ_DMA5 INT_DMA5 ++#define FIQ_DMA6 INT_DMA6 ++#define FIQ_DMA7 INT_DMA7 ++#define FIQ_DMA8 INT_DMA8 ++#define FIQ_DMA9 INT_DMA9 ++#define FIQ_DMA10 INT_DMA10 ++#define FIQ_DMA11 INT_DMA11 ++#define FIQ_DMA12 INT_DMA12 ++#define FIQ_AUX INT_AUX ++#define FIQ_ARM INT_ARM ++#define FIQ_VPUDMA INT_VPUDMA ++#define FIQ_HOSTPORT INT_HOSTPORT ++#define FIQ_VIDEOSCALER INT_VIDEOSCALER ++#define FIQ_CCP2TX INT_CCP2TX ++#define FIQ_SDC INT_SDC ++#define FIQ_DSI0 INT_DSI0 ++#define FIQ_AVE INT_AVE ++#define FIQ_CAM0 INT_CAM0 ++#define FIQ_CAM1 INT_CAM1 ++#define FIQ_HDMI0 INT_HDMI0 ++#define FIQ_HDMI1 INT_HDMI1 ++#define FIQ_PIXELVALVE1 INT_PIXELVALVE1 ++#define FIQ_I2CSPISLV INT_I2CSPISLV ++#define FIQ_DSI1 INT_DSI1 ++#define FIQ_PWA0 INT_PWA0 ++#define FIQ_PWA1 INT_PWA1 ++#define FIQ_CPR INT_CPR ++#define FIQ_SMI INT_SMI ++#define FIQ_GPIO0 INT_GPIO0 ++#define FIQ_GPIO1 INT_GPIO1 ++#define FIQ_GPIO2 INT_GPIO2 ++#define FIQ_GPIO3 INT_GPIO3 ++#define FIQ_I2C INT_I2C ++#define FIQ_SPI INT_SPI ++#define FIQ_I2SPCM INT_I2SPCM ++#define FIQ_SDIO INT_SDIO ++#define FIQ_UART INT_UART ++#define FIQ_SLIMBUS INT_SLIMBUS ++#define FIQ_VEC INT_VEC ++#define FIQ_CPG INT_CPG ++#define FIQ_RNG INT_RNG ++#define FIQ_ARASANSDIO INT_ARASANSDIO ++#define FIQ_AVSPMON INT_AVSPMON ++ ++#define FIQ_ARM_TIMER INT_ARM_TIMER ++#define FIQ_ARM_MAILBOX INT_ARM_MAILBOX ++#define FIQ_ARM_DOORBELL_0 INT_ARM_DOORBELL_0 ++#define FIQ_ARM_DOORBELL_1 INT_ARM_DOORBELL_1 ++#define FIQ_VPU0_HALTED INT_VPU0_HALTED ++#define FIQ_VPU1_HALTED INT_VPU1_HALTED ++#define FIQ_ILLEGAL_TYPE0 INT_ILLEGAL_TYPE0 ++#define FIQ_ILLEGAL_TYPE1 INT_ILLEGAL_TYPE1 ++#define FIQ_PENDING1 INT_PENDING1 ++#define FIQ_PENDING2 INT_PENDING2 ++ ++#define HARD_IRQS (64 + 21) ++#define GPIO_IRQ_START (HARD_IRQS) ++#define GPIO_IRQS (32*5) ++#define SPARE_ALLOC_IRQS 64 ++#define BCM2708_ALLOC_IRQS (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS) ++#define FREE_IRQS 128 ++#define NR_IRQS (BCM2708_ALLOC_IRQS+FREE_IRQS) ++ ++#endif /* _BCM2708_IRQS_H_ */ +diff --git a/arch/arm/mach-bcm2708/include/mach/memory.h b/arch/arm/mach-bcm2708/include/mach/memory.h +new file mode 100644 +index 0000000..7548a52 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/memory.h +@@ -0,0 +1,57 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/memory.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __ASM_ARCH_MEMORY_H ++#define __ASM_ARCH_MEMORY_H ++ ++/* Memory overview: ++ ++ [ARMcore] <--virtual addr--> ++ [ARMmmu] <--physical addr--> ++ [GERTmap] <--bus add--> ++ [VCperiph] ++ ++*/ ++ ++/* ++ * Physical DRAM offset. ++ */ ++#define BCM_PLAT_PHYS_OFFSET UL(0x00000000) ++#define VC_ARMMEM_OFFSET UL(0x00000000) /* offset in VC of ARM memory */ ++ ++#ifdef CONFIG_BCM2708_NOL2CACHE ++ #define _REAL_BUS_OFFSET UL(0xC0000000) /* don't use L1 or L2 caches */ ++#else ++ #define _REAL_BUS_OFFSET UL(0x40000000) /* use L2 cache */ ++#endif ++ ++/* We're using the memory at 64M in the VideoCore for Linux - this adjustment ++ * will provide the offset into this area as well as setting the bits that ++ * stop the L1 and L2 cache from being used ++ * ++ * WARNING: this only works because the ARM is given memory at a fixed location ++ * (ARMMEM_OFFSET) ++ */ ++#define BUS_OFFSET (VC_ARMMEM_OFFSET + _REAL_BUS_OFFSET) ++#define __virt_to_bus(x) ((x) + (BUS_OFFSET - PAGE_OFFSET)) ++#define __bus_to_virt(x) ((x) - (BUS_OFFSET - PAGE_OFFSET)) ++#define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - BCM_PLAT_PHYS_OFFSET)) ++#define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - BCM_PLAT_PHYS_OFFSET)) ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h +new file mode 100644 +index 0000000..2e7e1bb +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/platform.h +@@ -0,0 +1,228 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/platform.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef _BCM2708_PLATFORM_H ++#define _BCM2708_PLATFORM_H ++ ++ ++/* macros to get at IO space when running virtually */ ++#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) ++ ++#define __io_address(n) IOMEM(IO_ADDRESS(n)) ++ ++ ++/* ++ * SDRAM ++ */ ++#define BCM2708_SDRAM_BASE 0x00000000 ++ ++/* ++ * Logic expansion modules ++ * ++ */ ++ ++ ++/* ------------------------------------------------------------------------ ++ * BCM2708 ARMCTRL Registers ++ * ------------------------------------------------------------------------ ++ */ ++ ++#define HW_REGISTER_RW(addr) (addr) ++#define HW_REGISTER_RO(addr) (addr) ++ ++#include "arm_control.h" ++#undef ARM_BASE ++ ++/* ++ * Definitions and addresses for the ARM CONTROL logic ++ * This file is manually generated. ++ */ ++ ++#define BCM2708_PERI_BASE 0x20000000 ++#define IC0_BASE (BCM2708_PERI_BASE + 0x2000) ++#define ST_BASE (BCM2708_PERI_BASE + 0x3000) /* System Timer */ ++#define MPHI_BASE (BCM2708_PERI_BASE + 0x6000) /* Message -based Parallel Host Interface */ ++#define DMA_BASE (BCM2708_PERI_BASE + 0x7000) /* DMA controller */ ++#define ARM_BASE (BCM2708_PERI_BASE + 0xB000) /* BCM2708 ARM control block */ ++#define PM_BASE (BCM2708_PERI_BASE + 0x100000) /* Power Management, Reset controller and Watchdog registers */ ++#define PCM_CLOCK_BASE (BCM2708_PERI_BASE + 0x101098) /* PCM Clock */ ++#define RNG_BASE (BCM2708_PERI_BASE + 0x104000) /* Hardware RNG */ ++#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO */ ++#define UART0_BASE (BCM2708_PERI_BASE + 0x201000) /* Uart 0 */ ++#define MMCI0_BASE (BCM2708_PERI_BASE + 0x202000) /* MMC interface */ ++#define I2S_BASE (BCM2708_PERI_BASE + 0x203000) /* I2S */ ++#define SPI0_BASE (BCM2708_PERI_BASE + 0x204000) /* SPI0 */ ++#define BSC0_BASE (BCM2708_PERI_BASE + 0x205000) /* BSC0 I2C/TWI */ ++#define UART1_BASE (BCM2708_PERI_BASE + 0x215000) /* Uart 1 */ ++#define EMMC_BASE (BCM2708_PERI_BASE + 0x300000) /* eMMC interface */ ++#define SMI_BASE (BCM2708_PERI_BASE + 0x600000) /* SMI */ ++#define BSC1_BASE (BCM2708_PERI_BASE + 0x804000) /* BSC1 I2C/TWI */ ++#define USB_BASE (BCM2708_PERI_BASE + 0x980000) /* DTC_OTG USB controller */ ++#define MCORE_BASE (BCM2708_PERI_BASE + 0x0000) /* Fake frame buffer device (actually the multicore sync block*/ ++ ++#define ARMCTRL_BASE (ARM_BASE + 0x000) ++#define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ ++#define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ ++#define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ ++ ++ ++/* ++ * Interrupt assignments ++ */ ++ ++#define ARM_IRQ1_BASE 0 ++#define INTERRUPT_TIMER0 (ARM_IRQ1_BASE + 0) ++#define INTERRUPT_TIMER1 (ARM_IRQ1_BASE + 1) ++#define INTERRUPT_TIMER2 (ARM_IRQ1_BASE + 2) ++#define INTERRUPT_TIMER3 (ARM_IRQ1_BASE + 3) ++#define INTERRUPT_CODEC0 (ARM_IRQ1_BASE + 4) ++#define INTERRUPT_CODEC1 (ARM_IRQ1_BASE + 5) ++#define INTERRUPT_CODEC2 (ARM_IRQ1_BASE + 6) ++#define INTERRUPT_VC_JPEG (ARM_IRQ1_BASE + 7) ++#define INTERRUPT_ISP (ARM_IRQ1_BASE + 8) ++#define INTERRUPT_VC_USB (ARM_IRQ1_BASE + 9) ++#define INTERRUPT_VC_3D (ARM_IRQ1_BASE + 10) ++#define INTERRUPT_TRANSPOSER (ARM_IRQ1_BASE + 11) ++#define INTERRUPT_MULTICORESYNC0 (ARM_IRQ1_BASE + 12) ++#define INTERRUPT_MULTICORESYNC1 (ARM_IRQ1_BASE + 13) ++#define INTERRUPT_MULTICORESYNC2 (ARM_IRQ1_BASE + 14) ++#define INTERRUPT_MULTICORESYNC3 (ARM_IRQ1_BASE + 15) ++#define INTERRUPT_DMA0 (ARM_IRQ1_BASE + 16) ++#define INTERRUPT_DMA1 (ARM_IRQ1_BASE + 17) ++#define INTERRUPT_VC_DMA2 (ARM_IRQ1_BASE + 18) ++#define INTERRUPT_VC_DMA3 (ARM_IRQ1_BASE + 19) ++#define INTERRUPT_DMA4 (ARM_IRQ1_BASE + 20) ++#define INTERRUPT_DMA5 (ARM_IRQ1_BASE + 21) ++#define INTERRUPT_DMA6 (ARM_IRQ1_BASE + 22) ++#define INTERRUPT_DMA7 (ARM_IRQ1_BASE + 23) ++#define INTERRUPT_DMA8 (ARM_IRQ1_BASE + 24) ++#define INTERRUPT_DMA9 (ARM_IRQ1_BASE + 25) ++#define INTERRUPT_DMA10 (ARM_IRQ1_BASE + 26) ++#define INTERRUPT_DMA11 (ARM_IRQ1_BASE + 27) ++#define INTERRUPT_DMA12 (ARM_IRQ1_BASE + 28) ++#define INTERRUPT_AUX (ARM_IRQ1_BASE + 29) ++#define INTERRUPT_ARM (ARM_IRQ1_BASE + 30) ++#define INTERRUPT_VPUDMA (ARM_IRQ1_BASE + 31) ++ ++#define ARM_IRQ2_BASE 32 ++#define INTERRUPT_HOSTPORT (ARM_IRQ2_BASE + 0) ++#define INTERRUPT_VIDEOSCALER (ARM_IRQ2_BASE + 1) ++#define INTERRUPT_CCP2TX (ARM_IRQ2_BASE + 2) ++#define INTERRUPT_SDC (ARM_IRQ2_BASE + 3) ++#define INTERRUPT_DSI0 (ARM_IRQ2_BASE + 4) ++#define INTERRUPT_AVE (ARM_IRQ2_BASE + 5) ++#define INTERRUPT_CAM0 (ARM_IRQ2_BASE + 6) ++#define INTERRUPT_CAM1 (ARM_IRQ2_BASE + 7) ++#define INTERRUPT_HDMI0 (ARM_IRQ2_BASE + 8) ++#define INTERRUPT_HDMI1 (ARM_IRQ2_BASE + 9) ++#define INTERRUPT_PIXELVALVE1 (ARM_IRQ2_BASE + 10) ++#define INTERRUPT_I2CSPISLV (ARM_IRQ2_BASE + 11) ++#define INTERRUPT_DSI1 (ARM_IRQ2_BASE + 12) ++#define INTERRUPT_PWA0 (ARM_IRQ2_BASE + 13) ++#define INTERRUPT_PWA1 (ARM_IRQ2_BASE + 14) ++#define INTERRUPT_CPR (ARM_IRQ2_BASE + 15) ++#define INTERRUPT_SMI (ARM_IRQ2_BASE + 16) ++#define INTERRUPT_GPIO0 (ARM_IRQ2_BASE + 17) ++#define INTERRUPT_GPIO1 (ARM_IRQ2_BASE + 18) ++#define INTERRUPT_GPIO2 (ARM_IRQ2_BASE + 19) ++#define INTERRUPT_GPIO3 (ARM_IRQ2_BASE + 20) ++#define INTERRUPT_VC_I2C (ARM_IRQ2_BASE + 21) ++#define INTERRUPT_VC_SPI (ARM_IRQ2_BASE + 22) ++#define INTERRUPT_VC_I2SPCM (ARM_IRQ2_BASE + 23) ++#define INTERRUPT_VC_SDIO (ARM_IRQ2_BASE + 24) ++#define INTERRUPT_VC_UART (ARM_IRQ2_BASE + 25) ++#define INTERRUPT_SLIMBUS (ARM_IRQ2_BASE + 26) ++#define INTERRUPT_VEC (ARM_IRQ2_BASE + 27) ++#define INTERRUPT_CPG (ARM_IRQ2_BASE + 28) ++#define INTERRUPT_RNG (ARM_IRQ2_BASE + 29) ++#define INTERRUPT_VC_ARASANSDIO (ARM_IRQ2_BASE + 30) ++#define INTERRUPT_AVSPMON (ARM_IRQ2_BASE + 31) ++ ++#define ARM_IRQ0_BASE 64 ++#define INTERRUPT_ARM_TIMER (ARM_IRQ0_BASE + 0) ++#define INTERRUPT_ARM_MAILBOX (ARM_IRQ0_BASE + 1) ++#define INTERRUPT_ARM_DOORBELL_0 (ARM_IRQ0_BASE + 2) ++#define INTERRUPT_ARM_DOORBELL_1 (ARM_IRQ0_BASE + 3) ++#define INTERRUPT_VPU0_HALTED (ARM_IRQ0_BASE + 4) ++#define INTERRUPT_VPU1_HALTED (ARM_IRQ0_BASE + 5) ++#define INTERRUPT_ILLEGAL_TYPE0 (ARM_IRQ0_BASE + 6) ++#define INTERRUPT_ILLEGAL_TYPE1 (ARM_IRQ0_BASE + 7) ++#define INTERRUPT_PENDING1 (ARM_IRQ0_BASE + 8) ++#define INTERRUPT_PENDING2 (ARM_IRQ0_BASE + 9) ++#define INTERRUPT_JPEG (ARM_IRQ0_BASE + 10) ++#define INTERRUPT_USB (ARM_IRQ0_BASE + 11) ++#define INTERRUPT_3D (ARM_IRQ0_BASE + 12) ++#define INTERRUPT_DMA2 (ARM_IRQ0_BASE + 13) ++#define INTERRUPT_DMA3 (ARM_IRQ0_BASE + 14) ++#define INTERRUPT_I2C (ARM_IRQ0_BASE + 15) ++#define INTERRUPT_SPI (ARM_IRQ0_BASE + 16) ++#define INTERRUPT_I2SPCM (ARM_IRQ0_BASE + 17) ++#define INTERRUPT_SDIO (ARM_IRQ0_BASE + 18) ++#define INTERRUPT_UART (ARM_IRQ0_BASE + 19) ++#define INTERRUPT_ARASANSDIO (ARM_IRQ0_BASE + 20) ++ ++#define MAXIRQNUM (32 + 32 + 20) ++#define MAXFIQNUM (32 + 32 + 20) ++ ++#define MAX_TIMER 2 ++#define MAX_PERIOD 699050 ++#define TICKS_PER_uSEC 1 ++ ++/* ++ * These are useconds NOT ticks. ++ * ++ */ ++#define mSEC_1 1000 ++#define mSEC_5 (mSEC_1 * 5) ++#define mSEC_10 (mSEC_1 * 10) ++#define mSEC_25 (mSEC_1 * 25) ++#define SEC_1 (mSEC_1 * 1000) ++ ++/* ++ * Watchdog ++ */ ++#define PM_RSTC (PM_BASE+0x1c) ++#define PM_RSTS (PM_BASE+0x20) ++#define PM_WDOG (PM_BASE+0x24) ++ ++#define PM_WDOG_RESET 0000000000 ++#define PM_PASSWORD 0x5a000000 ++#define PM_WDOG_TIME_SET 0x000fffff ++#define PM_RSTC_WRCFG_CLR 0xffffffcf ++#define PM_RSTC_WRCFG_SET 0x00000030 ++#define PM_RSTC_WRCFG_FULL_RESET 0x00000020 ++#define PM_RSTC_RESET 0x00000102 ++ ++#define PM_RSTS_HADPOR_SET 0x00001000 ++#define PM_RSTS_HADSRH_SET 0x00000400 ++#define PM_RSTS_HADSRF_SET 0x00000200 ++#define PM_RSTS_HADSRQ_SET 0x00000100 ++#define PM_RSTS_HADWRH_SET 0x00000040 ++#define PM_RSTS_HADWRF_SET 0x00000020 ++#define PM_RSTS_HADWRQ_SET 0x00000010 ++#define PM_RSTS_HADDRH_SET 0x00000004 ++#define PM_RSTS_HADDRF_SET 0x00000002 ++#define PM_RSTS_HADDRQ_SET 0x00000001 ++ ++#define UART0_CLOCK 3000000 ++ ++#endif ++ ++/* END */ +diff --git a/arch/arm/mach-bcm2708/include/mach/power.h b/arch/arm/mach-bcm2708/include/mach/power.h +new file mode 100644 +index 0000000..52b3b02 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/power.h +@@ -0,0 +1,26 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/power.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This device provides a shared mechanism for controlling the power to ++ * VideoCore subsystems. ++ */ ++ ++#ifndef _MACH_BCM2708_POWER_H ++#define _MACH_BCM2708_POWER_H ++ ++#include ++#include ++ ++typedef unsigned int BCM_POWER_HANDLE_T; ++ ++extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); ++extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); ++extern int bcm_power_close(BCM_POWER_HANDLE_T handle); ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/include/mach/system.h b/arch/arm/mach-bcm2708/include/mach/system.h +new file mode 100644 +index 0000000..2d0b821 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/system.h +@@ -0,0 +1,38 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/system.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * Copyright (C) 2003 ARM Limited ++ * Copyright (C) 2000 Deep Blue Solutions Ltd ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef __ASM_ARCH_SYSTEM_H ++#define __ASM_ARCH_SYSTEM_H ++ ++#include ++#include ++#include ++ ++static inline void arch_idle(void) ++{ ++ /* ++ * This should do all the clock switching ++ * and wait for interrupt tricks ++ */ ++ cpu_do_idle(); ++} ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/include/mach/timex.h b/arch/arm/mach-bcm2708/include/mach/timex.h +new file mode 100644 +index 0000000..64a660c +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/timex.h +@@ -0,0 +1,23 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/timex.h ++ * ++ * BCM2708 sysem clock frequency ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#define CLOCK_TICK_RATE (1000000) +diff --git a/arch/arm/mach-bcm2708/include/mach/uncompress.h b/arch/arm/mach-bcm2708/include/mach/uncompress.h +new file mode 100644 +index 0000000..d634813 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/uncompress.h +@@ -0,0 +1,84 @@ ++/* ++ * arch/arm/mach-bcn2708/include/mach/uncompress.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * Copyright (C) 2003 ARM Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++ ++#define UART_BAUD 115200 ++ ++#define BCM2708_UART_DR __io(UART0_BASE + UART01x_DR) ++#define BCM2708_UART_FR __io(UART0_BASE + UART01x_FR) ++#define BCM2708_UART_IBRD __io(UART0_BASE + UART011_IBRD) ++#define BCM2708_UART_FBRD __io(UART0_BASE + UART011_FBRD) ++#define BCM2708_UART_LCRH __io(UART0_BASE + UART011_LCRH) ++#define BCM2708_UART_CR __io(UART0_BASE + UART011_CR) ++ ++/* ++ * This does not append a newline ++ */ ++static inline void putc(int c) ++{ ++ while (__raw_readl(BCM2708_UART_FR) & UART01x_FR_TXFF) ++ barrier(); ++ ++ __raw_writel(c, BCM2708_UART_DR); ++} ++ ++static inline void flush(void) ++{ ++ int fr; ++ ++ do { ++ fr = __raw_readl(BCM2708_UART_FR); ++ barrier(); ++ } while ((fr & (UART011_FR_TXFE | UART01x_FR_BUSY)) != UART011_FR_TXFE); ++} ++ ++static inline void arch_decomp_setup(void) ++{ ++ int temp, div, rem, frac; ++ ++ temp = 16 * UART_BAUD; ++ div = UART0_CLOCK / temp; ++ rem = UART0_CLOCK % temp; ++ temp = (8 * rem) / UART_BAUD; ++ frac = (temp >> 1) + (temp & 1); ++ ++ /* Make sure the UART is disabled before we start */ ++ __raw_writel(0, BCM2708_UART_CR); ++ ++ /* Set the baud rate */ ++ __raw_writel(div, BCM2708_UART_IBRD); ++ __raw_writel(frac, BCM2708_UART_FBRD); ++ ++ /* Set the UART to 8n1, FIFO enabled */ ++ __raw_writel(UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN, BCM2708_UART_LCRH); ++ ++ /* Enable the UART */ ++ __raw_writel(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE, ++ BCM2708_UART_CR); ++} ++ ++/* ++ * nothing to do ++ */ ++#define arch_decomp_wdog() +diff --git a/arch/arm/mach-bcm2708/include/mach/vc_mem.h b/arch/arm/mach-bcm2708/include/mach/vc_mem.h +new file mode 100644 +index 0000000..4a4a338 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/vc_mem.h +@@ -0,0 +1,35 @@ ++/***************************************************************************** ++* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#if !defined( VC_MEM_H ) ++#define VC_MEM_H ++ ++#include ++ ++#define VC_MEM_IOC_MAGIC 'v' ++ ++#define VC_MEM_IOC_MEM_PHYS_ADDR _IOR( VC_MEM_IOC_MAGIC, 0, unsigned long ) ++#define VC_MEM_IOC_MEM_SIZE _IOR( VC_MEM_IOC_MAGIC, 1, unsigned int ) ++#define VC_MEM_IOC_MEM_BASE _IOR( VC_MEM_IOC_MAGIC, 2, unsigned int ) ++#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) ++ ++#if defined( __KERNEL__ ) ++#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF ++ ++extern unsigned long mm_vc_mem_phys_addr; ++extern unsigned int mm_vc_mem_size; ++extern int vc_mem_get_current_size( void ); ++#endif ++ ++#endif /* VC_MEM_H */ +diff --git a/arch/arm/mach-bcm2708/include/mach/vcio.h b/arch/arm/mach-bcm2708/include/mach/vcio.h +new file mode 100644 +index 0000000..8e11d67 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/vcio.h +@@ -0,0 +1,165 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/vcio.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#ifndef _MACH_BCM2708_VCIO_H ++#define _MACH_BCM2708_VCIO_H ++ ++/* Routines to handle I/O via the VideoCore "ARM control" registers ++ * (semaphores, doorbells, mailboxes) ++ */ ++ ++#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio" ++ ++/* Constants shared with the ARM identifying separate mailbox channels */ ++#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ ++#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ ++#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ ++#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ ++#define MBOX_CHAN_COUNT 9 ++ ++enum { ++ VCMSG_PROCESS_REQUEST = 0x00000000 ++}; ++enum { ++ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, ++ VCMSG_REQUEST_FAILED = 0x80000001 ++}; ++/* Mailbox property tags */ ++enum { ++ VCMSG_PROPERTY_END = 0x00000000, ++ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, ++ VCMSG_GET_BOARD_MODEL = 0x00010001, ++ VCMSG_GET_BOARD_REVISION = 0x00010002, ++ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, ++ VCMSG_GET_BOARD_SERIAL = 0x00010004, ++ VCMSG_GET_ARM_MEMORY = 0x00010005, ++ VCMSG_GET_VC_MEMORY = 0x00010006, ++ VCMSG_GET_CLOCKS = 0x00010007, ++ VCMSG_GET_COMMAND_LINE = 0x00050001, ++ VCMSG_GET_DMA_CHANNELS = 0x00060001, ++ VCMSG_GET_POWER_STATE = 0x00020001, ++ VCMSG_GET_TIMING = 0x00020002, ++ VCMSG_SET_POWER_STATE = 0x00028001, ++ VCMSG_GET_CLOCK_STATE = 0x00030001, ++ VCMSG_SET_CLOCK_STATE = 0x00038001, ++ VCMSG_GET_CLOCK_RATE = 0x00030002, ++ VCMSG_SET_CLOCK_RATE = 0x00038002, ++ VCMSG_GET_VOLTAGE = 0x00030003, ++ VCMSG_SET_VOLTAGE = 0x00038003, ++ VCMSG_GET_MAX_CLOCK = 0x00030004, ++ VCMSG_GET_MAX_VOLTAGE = 0x00030005, ++ VCMSG_GET_TEMPERATURE = 0x00030006, ++ VCMSG_GET_MIN_CLOCK = 0x00030007, ++ VCMSG_GET_MIN_VOLTAGE = 0x00030008, ++ VCMSG_GET_TURBO = 0x00030009, ++ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, ++ VCMSG_GET_STC = 0x0003000b, ++ VCMSG_SET_TURBO = 0x00038009, ++ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, ++ VCMSG_SET_LOCK_MEM = 0x0003000d, ++ VCMSG_SET_UNLOCK_MEM = 0x0003000e, ++ VCMSG_SET_RELEASE_MEM = 0x0003000f, ++ VCMSG_SET_EXECUTE_CODE = 0x00030010, ++ VCMSG_SET_EXECUTE_QPU = 0x00030011, ++ VCMSG_SET_ENABLE_QPU = 0x00030012, ++ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, ++ VCMSG_GET_EDID_BLOCK = 0x00030020, ++ VCMSG_GET_CUSTOMER_OTP = 0x00030021, ++ VCMSG_SET_CUSTOMER_OTP = 0x00038021, ++ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, ++ VCMSG_SET_RELEASE_BUFFER = 0x00048001, ++ VCMSG_SET_BLANK_SCREEN = 0x00040002, ++ VCMSG_TST_BLANK_SCREEN = 0x00044002, ++ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, ++ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, ++ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, ++ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, ++ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, ++ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, ++ VCMSG_GET_DEPTH = 0x00040005, ++ VCMSG_TST_DEPTH = 0x00044005, ++ VCMSG_SET_DEPTH = 0x00048005, ++ VCMSG_GET_PIXEL_ORDER = 0x00040006, ++ VCMSG_TST_PIXEL_ORDER = 0x00044006, ++ VCMSG_SET_PIXEL_ORDER = 0x00048006, ++ VCMSG_GET_ALPHA_MODE = 0x00040007, ++ VCMSG_TST_ALPHA_MODE = 0x00044007, ++ VCMSG_SET_ALPHA_MODE = 0x00048007, ++ VCMSG_GET_PITCH = 0x00040008, ++ VCMSG_TST_PITCH = 0x00044008, ++ VCMSG_SET_PITCH = 0x00048008, ++ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, ++ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, ++ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, ++ VCMSG_GET_OVERSCAN = 0x0004000a, ++ VCMSG_TST_OVERSCAN = 0x0004400a, ++ VCMSG_SET_OVERSCAN = 0x0004800a, ++ VCMSG_GET_PALETTE = 0x0004000b, ++ VCMSG_TST_PALETTE = 0x0004400b, ++ VCMSG_SET_PALETTE = 0x0004800b, ++ VCMSG_GET_LAYER = 0x0004000c, ++ VCMSG_TST_LAYER = 0x0004400c, ++ VCMSG_SET_LAYER = 0x0004800c, ++ VCMSG_GET_TRANSFORM = 0x0004000d, ++ VCMSG_TST_TRANSFORM = 0x0004400d, ++ VCMSG_SET_TRANSFORM = 0x0004800d, ++ VCMSG_TST_VSYNC = 0x0004400e, ++ VCMSG_SET_VSYNC = 0x0004800e, ++ VCMSG_SET_CURSOR_INFO = 0x00008010, ++ VCMSG_SET_CURSOR_STATE = 0x00008011, ++}; ++ ++extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); ++extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); ++extern int /*rc*/ bcm_mailbox_property(void *data, int size); ++ ++#include ++ ++/* ++ * The major device number. We can't rely on dynamic ++ * registration any more, because ioctls need to know ++ * it. ++ */ ++#define MAJOR_NUM 100 ++ ++/* ++ * Set the message of the device driver ++ */ ++#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) ++/* ++ * _IOWR means that we're creating an ioctl command ++ * number for passing information from a user process ++ * to the kernel module and from the kernel module to user process ++ * ++ * The first arguments, MAJOR_NUM, is the major device ++ * number we're using. ++ * ++ * The second argument is the number of the command ++ * (there could be several with different meanings). ++ * ++ * The third argument is the type we want to get from ++ * the process to the kernel. ++ */ ++ ++/* ++ * The name of the device file ++ */ ++#define DEVICE_FILE_NAME "vcio" ++ ++#endif +diff --git a/arch/arm/mach-bcm2708/include/mach/vmalloc.h b/arch/arm/mach-bcm2708/include/mach/vmalloc.h +new file mode 100644 +index 0000000..502c617 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/include/mach/vmalloc.h +@@ -0,0 +1,20 @@ ++/* ++ * arch/arm/mach-bcm2708/include/mach/vmalloc.h ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * 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. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#define VMALLOC_END (0xe8000000) +diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c +new file mode 100644 +index 0000000..2696be9 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/power.c +@@ -0,0 +1,197 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/power.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This device provides a shared mechanism for controlling the power to ++ * VideoCore subsystems. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "bcm2708_power" ++ ++#define BCM_POWER_MAXCLIENTS 4 ++#define BCM_POWER_NOCLIENT (1<<31) ++ ++/* Some drivers expect there devices to be permanently powered */ ++ ++#ifdef CONFIG_USB ++#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) ++#endif ++ ++#if 1 ++#define DPRINTK printk ++#else ++#define DPRINTK if (0) printk ++#endif ++ ++struct state_struct { ++ uint32_t global_request; ++ uint32_t client_request[BCM_POWER_MAXCLIENTS]; ++ struct semaphore client_mutex; ++ struct semaphore mutex; ++} g_state; ++ ++int bcm_power_open(BCM_POWER_HANDLE_T *handle) ++{ ++ BCM_POWER_HANDLE_T i; ++ int ret = -EBUSY; ++ ++ down(&g_state.client_mutex); ++ ++ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { ++ if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { ++ g_state.client_request[i] = BCM_POWER_NONE; ++ *handle = i; ++ ret = 0; ++ break; ++ } ++ } ++ ++ up(&g_state.client_mutex); ++ ++ DPRINTK("bcm_power_open() -> %d\n", *handle); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(bcm_power_open); ++ ++int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) ++{ ++ int rc = 0; ++ ++ DPRINTK("bcm_power_request(%d, %x)\n", handle, request); ++ ++ if ((handle < BCM_POWER_MAXCLIENTS) && ++ (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { ++ if (down_interruptible(&g_state.mutex) != 0) { ++ DPRINTK("bcm_power_request -> interrupted\n"); ++ return -EINTR; ++ } ++ ++ if (request != g_state.client_request[handle]) { ++ uint32_t others_request = 0; ++ uint32_t global_request; ++ BCM_POWER_HANDLE_T i; ++ ++ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { ++ if (i != handle) ++ others_request |= ++ g_state.client_request[i]; ++ } ++ others_request &= ~BCM_POWER_NOCLIENT; ++ ++ global_request = request | others_request; ++ if (global_request != g_state.global_request) { ++ uint32_t actual; ++ ++ /* Send a request to VideoCore */ ++ bcm_mailbox_write(MBOX_CHAN_POWER, ++ global_request << 4); ++ ++ /* Wait for a response during power-up */ ++ if (global_request & ~g_state.global_request) { ++ rc = bcm_mailbox_read(MBOX_CHAN_POWER, ++ &actual); ++ DPRINTK ++ ("bcm_mailbox_read -> %08x, %d\n", ++ actual, rc); ++ actual >>= 4; ++ } else { ++ rc = 0; ++ actual = global_request; ++ } ++ ++ if (rc == 0) { ++ if (actual != global_request) { ++ printk(KERN_ERR ++ "%s: prev global %x, new global %x, actual %x, request %x, others_request %x\n", ++ __func__, ++ g_state.global_request, ++ global_request, actual, request, others_request); ++ /* A failure */ ++ BUG_ON((others_request & actual) ++ != others_request); ++ request &= actual; ++ rc = -EIO; ++ } ++ ++ g_state.global_request = actual; ++ g_state.client_request[handle] = ++ request; ++ } ++ } ++ } ++ up(&g_state.mutex); ++ } else { ++ rc = -EINVAL; ++ } ++ DPRINTK("bcm_power_request -> %d\n", rc); ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_power_request); ++ ++int bcm_power_close(BCM_POWER_HANDLE_T handle) ++{ ++ int rc; ++ ++ DPRINTK("bcm_power_close(%d)\n", handle); ++ ++ rc = bcm_power_request(handle, BCM_POWER_NONE); ++ if (rc == 0) ++ g_state.client_request[handle] = BCM_POWER_NOCLIENT; ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_power_close); ++ ++static int __init bcm_power_init(void) ++{ ++#if defined(BCM_POWER_ALWAYS_ON) ++ BCM_POWER_HANDLE_T always_on_handle; ++#endif ++ int rc = 0; ++ int i; ++ ++ printk(KERN_INFO "bcm_power: Broadcom power driver\n"); ++ bcm_mailbox_write(MBOX_CHAN_POWER, 0); ++ ++ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) ++ g_state.client_request[i] = BCM_POWER_NOCLIENT; ++ ++ sema_init(&g_state.client_mutex, 1); ++ sema_init(&g_state.mutex, 1); ++ ++ g_state.global_request = 0; ++ ++#if defined(BCM_POWER_ALWAYS_ON) ++ if (BCM_POWER_ALWAYS_ON) { ++ bcm_power_open(&always_on_handle); ++ bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); ++ } ++#endif ++ ++ return rc; ++} ++ ++static void __exit bcm_power_exit(void) ++{ ++ bcm_mailbox_write(MBOX_CHAN_POWER, 0); ++} ++ ++arch_initcall(bcm_power_init); /* Initialize early */ ++module_exit(bcm_power_exit); ++ ++MODULE_AUTHOR("Phil Elwell"); ++MODULE_DESCRIPTION("Interface to BCM2708 power management"); ++MODULE_LICENSE("GPL"); +diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c +new file mode 100644 +index 0000000..2982af7 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/vc_mem.c +@@ -0,0 +1,431 @@ ++/***************************************************************************** ++* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_ARCH_KONA ++#include ++#elif CONFIG_ARCH_BCM2708 ++#else ++#include ++#endif ++ ++#include "mach/vc_mem.h" ++#include ++ ++#define DRIVER_NAME "vc-mem" ++ ++// Device (/dev) related variables ++static dev_t vc_mem_devnum = 0; ++static struct class *vc_mem_class = NULL; ++static struct cdev vc_mem_cdev; ++static int vc_mem_inited = 0; ++ ++#ifdef CONFIG_DEBUG_FS ++static struct dentry *vc_mem_debugfs_entry; ++#endif ++ ++/* ++ * Videocore memory addresses and size ++ * ++ * Drivers that wish to know the videocore memory addresses and sizes should ++ * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in ++ * headers. This allows the other drivers to not be tied down to a a certain ++ * address/size at compile time. ++ * ++ * In the future, the goal is to have the videocore memory virtual address and ++ * size be calculated at boot time rather than at compile time. The decision of ++ * where the videocore memory resides and its size would be in the hands of the ++ * bootloader (and/or kernel). When that happens, the values of these variables ++ * would be calculated and assigned in the init function. ++ */ ++// in the 2835 VC in mapped above ARM, but ARM has full access to VC space ++unsigned long mm_vc_mem_phys_addr = 0x00000000; ++unsigned int mm_vc_mem_size = 0; ++unsigned int mm_vc_mem_base = 0; ++ ++EXPORT_SYMBOL(mm_vc_mem_phys_addr); ++EXPORT_SYMBOL(mm_vc_mem_size); ++EXPORT_SYMBOL(mm_vc_mem_base); ++ ++static uint phys_addr = 0; ++static uint mem_size = 0; ++static uint mem_base = 0; ++ ++ ++/**************************************************************************** ++* ++* vc_mem_open ++* ++***************************************************************************/ ++ ++static int ++vc_mem_open(struct inode *inode, struct file *file) ++{ ++ (void) inode; ++ (void) file; ++ ++ pr_debug("%s: called file = 0x%p\n", __func__, file); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_release ++* ++***************************************************************************/ ++ ++static int ++vc_mem_release(struct inode *inode, struct file *file) ++{ ++ (void) inode; ++ (void) file; ++ ++ pr_debug("%s: called file = 0x%p\n", __func__, file); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_size ++* ++***************************************************************************/ ++ ++static void ++vc_mem_get_size(void) ++{ ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_base ++* ++***************************************************************************/ ++ ++static void ++vc_mem_get_base(void) ++{ ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_current_size ++* ++***************************************************************************/ ++ ++int ++vc_mem_get_current_size(void) ++{ ++ return mm_vc_mem_size; ++} ++ ++EXPORT_SYMBOL_GPL(vc_mem_get_current_size); ++ ++/**************************************************************************** ++* ++* vc_mem_ioctl ++* ++***************************************************************************/ ++ ++static long ++vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ int rc = 0; ++ ++ (void) cmd; ++ (void) arg; ++ ++ pr_debug("%s: called file = 0x%p\n", __func__, file); ++ ++ switch (cmd) { ++ case VC_MEM_IOC_MEM_PHYS_ADDR: ++ { ++ pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", ++ __func__, (void *) mm_vc_mem_phys_addr); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, ++ sizeof (mm_vc_mem_phys_addr)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_SIZE: ++ { ++ // Get the videocore memory size first ++ vc_mem_get_size(); ++ ++ pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, ++ mm_vc_mem_size); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_size, ++ sizeof (mm_vc_mem_size)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_BASE: ++ { ++ // Get the videocore memory base ++ vc_mem_get_base(); ++ ++ pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, ++ mm_vc_mem_base); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_base, ++ sizeof (mm_vc_mem_base)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_LOAD: ++ { ++ // Get the videocore memory base ++ vc_mem_get_base(); ++ ++ pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __func__, ++ mm_vc_mem_base); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_base, ++ sizeof (mm_vc_mem_base)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ default: ++ { ++ return -ENOTTY; ++ } ++ } ++ pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); ++ ++ return rc; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_mmap ++* ++***************************************************************************/ ++ ++static int ++vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) ++{ ++ int rc = 0; ++ unsigned long length = vma->vm_end - vma->vm_start; ++ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; ++ ++ pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", ++ __func__, (long) vma->vm_start, (long) vma->vm_end, ++ (long) vma->vm_pgoff); ++ ++ if (offset + length > mm_vc_mem_size) { ++ pr_err("%s: length %ld is too big\n", __func__, length); ++ return -EINVAL; ++ } ++ // Do not cache the memory map ++ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); ++ ++ rc = remap_pfn_range(vma, vma->vm_start, ++ (mm_vc_mem_phys_addr >> PAGE_SHIFT) + ++ vma->vm_pgoff, length, vma->vm_page_prot); ++ if (rc != 0) { ++ pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); ++ } ++ ++ return rc; ++} ++ ++/**************************************************************************** ++* ++* File Operations for the driver. ++* ++***************************************************************************/ ++ ++static const struct file_operations vc_mem_fops = { ++ .owner = THIS_MODULE, ++ .open = vc_mem_open, ++ .release = vc_mem_release, ++ .unlocked_ioctl = vc_mem_ioctl, ++ .mmap = vc_mem_mmap, ++}; ++ ++#ifdef CONFIG_DEBUG_FS ++static void vc_mem_debugfs_deinit(void) ++{ ++ debugfs_remove_recursive(vc_mem_debugfs_entry); ++ vc_mem_debugfs_entry = NULL; ++} ++ ++ ++static int vc_mem_debugfs_init( ++ struct device *dev) ++{ ++ vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); ++ if (!vc_mem_debugfs_entry) { ++ dev_warn(dev, "could not create debugfs entry\n"); ++ return -EFAULT; ++ } ++ ++ if (!debugfs_create_x32("vc_mem_phys_addr", ++ 0444, ++ vc_mem_debugfs_entry, ++ (u32 *)&mm_vc_mem_phys_addr)) { ++ dev_warn(dev, "%s:could not create vc_mem_phys entry\n", ++ __func__); ++ goto fail; ++ } ++ ++ if (!debugfs_create_x32("vc_mem_size", ++ 0444, ++ vc_mem_debugfs_entry, ++ (u32 *)&mm_vc_mem_size)) { ++ dev_warn(dev, "%s:could not create vc_mem_size entry\n", ++ __func__); ++ goto fail; ++ } ++ ++ if (!debugfs_create_x32("vc_mem_base", ++ 0444, ++ vc_mem_debugfs_entry, ++ (u32 *)&mm_vc_mem_base)) { ++ dev_warn(dev, "%s:could not create vc_mem_base entry\n", ++ __func__); ++ goto fail; ++ } ++ ++ return 0; ++ ++fail: ++ vc_mem_debugfs_deinit(); ++ return -EFAULT; ++} ++ ++#endif /* CONFIG_DEBUG_FS */ ++ ++ ++/**************************************************************************** ++* ++* vc_mem_init ++* ++***************************************************************************/ ++ ++static int __init ++vc_mem_init(void) ++{ ++ int rc = -EFAULT; ++ struct device *dev; ++ ++ pr_debug("%s: called\n", __func__); ++ ++ mm_vc_mem_phys_addr = phys_addr; ++ mm_vc_mem_size = mem_size; ++ mm_vc_mem_base = mem_base; ++ ++ vc_mem_get_size(); ++ ++ pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", ++ mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); ++ ++ if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { ++ pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", ++ __func__, rc); ++ goto out_err; ++ } ++ ++ cdev_init(&vc_mem_cdev, &vc_mem_fops); ++ if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { ++ pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); ++ goto out_unregister; ++ } ++ ++ vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); ++ if (IS_ERR(vc_mem_class)) { ++ rc = PTR_ERR(vc_mem_class); ++ pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); ++ goto out_cdev_del; ++ } ++ ++ dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, ++ DRIVER_NAME); ++ if (IS_ERR(dev)) { ++ rc = PTR_ERR(dev); ++ pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); ++ goto out_class_destroy; ++ } ++ ++#ifdef CONFIG_DEBUG_FS ++ /* don't fail if the debug entries cannot be created */ ++ vc_mem_debugfs_init(dev); ++#endif ++ ++ vc_mem_inited = 1; ++ return 0; ++ ++ device_destroy(vc_mem_class, vc_mem_devnum); ++ ++ out_class_destroy: ++ class_destroy(vc_mem_class); ++ vc_mem_class = NULL; ++ ++ out_cdev_del: ++ cdev_del(&vc_mem_cdev); ++ ++ out_unregister: ++ unregister_chrdev_region(vc_mem_devnum, 1); ++ ++ out_err: ++ return -1; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_exit ++* ++***************************************************************************/ ++ ++static void __exit ++vc_mem_exit(void) ++{ ++ pr_debug("%s: called\n", __func__); ++ ++ if (vc_mem_inited) { ++#if CONFIG_DEBUG_FS ++ vc_mem_debugfs_deinit(); ++#endif ++ device_destroy(vc_mem_class, vc_mem_devnum); ++ class_destroy(vc_mem_class); ++ cdev_del(&vc_mem_cdev); ++ unregister_chrdev_region(vc_mem_devnum, 1); ++ } ++} ++ ++module_init(vc_mem_init); ++module_exit(vc_mem_exit); ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Broadcom Corporation"); ++ ++module_param(phys_addr, uint, 0644); ++module_param(mem_size, uint, 0644); ++module_param(mem_base, uint, 0644); +diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c +new file mode 100644 +index 0000000..5e43e85 +--- /dev/null ++++ b/arch/arm/mach-bcm2708/vcio.c +@@ -0,0 +1,474 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/vcio.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This device provides a shared mechanism for writing to the mailboxes, ++ * semaphores, doorbells etc. that are shared between the ARM and the ++ * VideoCore processor ++ */ ++ ++#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) ++#define SUPPORT_SYSRQ ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#include ++ ++ ++#define DRIVER_NAME BCM_VCIO_DRIVER_NAME ++ ++/* ---------------------------------------------------------------------- ++ * Mailbox ++ * -------------------------------------------------------------------- */ ++ ++/* offsets from a mail box base address */ ++#define MAIL_WRT 0x00 /* write - and next 4 words */ ++#define MAIL_RD 0x00 /* read - and next 4 words */ ++#define MAIL_POL 0x10 /* read without popping the fifo */ ++#define MAIL_SND 0x14 /* sender ID (bottom two bits) */ ++#define MAIL_STA 0x18 /* status */ ++#define MAIL_CNF 0x1C /* configuration */ ++ ++#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) ++#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) ++#define MBOX_CHAN(msg) ((msg) & 0xf) ++#define MBOX_DATA28(msg) ((msg) & ~0xf) ++#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) ++ ++#define MBOX_MAGIC 0xd0d0c0de ++ ++struct vc_mailbox { ++ struct device *dev; /* parent device */ ++ void __iomem *status; ++ void __iomem *config; ++ void __iomem *read; ++ void __iomem *write; ++ uint32_t msg[MBOX_CHAN_COUNT]; ++ struct semaphore sema[MBOX_CHAN_COUNT]; ++ uint32_t magic; ++}; ++ ++static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, ++ uint32_t addr_mbox) ++{ ++ int i; ++ ++ mbox_out->dev = dev; ++ mbox_out->status = __io_address(addr_mbox + MAIL_STA); ++ mbox_out->config = __io_address(addr_mbox + MAIL_CNF); ++ mbox_out->read = __io_address(addr_mbox + MAIL_RD); ++ /* Write to the other mailbox */ ++ mbox_out->write = ++ __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) + ++ MAIL_WRT); ++ ++ for (i = 0; i < MBOX_CHAN_COUNT; i++) { ++ mbox_out->msg[i] = 0; ++ sema_init(&mbox_out->sema[i], 0); ++ } ++ ++ /* Enable the interrupt on data reception */ ++ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config); ++ ++ mbox_out->magic = MBOX_MAGIC; ++} ++ ++static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) ++{ ++ int rc; ++ ++ if (mbox->magic != MBOX_MAGIC) ++ rc = -EINVAL; ++ else { ++ /* wait for the mailbox FIFO to have some space in it */ ++ while (0 != (readl(mbox->status) & ARM_MS_FULL)) ++ cpu_relax(); ++ ++ writel(MBOX_MSG(chan, data28), mbox->write); ++ rc = 0; ++ } ++ return rc; ++} ++ ++static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) ++{ ++ int rc; ++ ++ if (mbox->magic != MBOX_MAGIC) ++ rc = -EINVAL; ++ else { ++ down(&mbox->sema[chan]); ++ *data28 = MBOX_DATA28(mbox->msg[chan]); ++ mbox->msg[chan] = 0; ++ rc = 0; ++ } ++ return rc; ++} ++ ++static irqreturn_t mbox_irq(int irq, void *dev_id) ++{ ++ /* wait for the mailbox FIFO to have some data in it */ ++ struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id; ++ int status = readl(mbox->status); ++ int ret = IRQ_NONE; ++ ++ while (!(status & ARM_MS_EMPTY)) { ++ uint32_t msg = readl(mbox->read); ++ int chan = MBOX_CHAN(msg); ++ if (chan < MBOX_CHAN_COUNT) { ++ if (mbox->msg[chan]) { ++ /* Overflow */ ++ printk(KERN_ERR DRIVER_NAME ++ ": mbox chan %d overflow - drop %08x\n", ++ chan, msg); ++ } else { ++ mbox->msg[chan] = (msg | 0xf); ++ up(&mbox->sema[chan]); ++ } ++ } else { ++ printk(KERN_ERR DRIVER_NAME ++ ": invalid channel selector (msg %08x)\n", msg); ++ } ++ ret = IRQ_HANDLED; ++ status = readl(mbox->status); ++ } ++ return ret; ++} ++ ++static struct irqaction mbox_irqaction = { ++ .name = "ARM Mailbox IRQ", ++ .flags = IRQF_DISABLED | IRQF_IRQPOLL, ++ .handler = mbox_irq, ++}; ++ ++/* ---------------------------------------------------------------------- ++ * Mailbox Methods ++ * -------------------------------------------------------------------- */ ++ ++static struct device *mbox_dev; /* we assume there's only one! */ ++ ++static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) ++{ ++ int rc; ++ ++ struct vc_mailbox *mailbox = dev_get_drvdata(dev); ++ device_lock(dev); ++ rc = mbox_write(mailbox, chan, data28); ++ device_unlock(dev); ++ ++ return rc; ++} ++ ++static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) ++{ ++ int rc; ++ ++ struct vc_mailbox *mailbox = dev_get_drvdata(dev); ++ device_lock(dev); ++ rc = mbox_read(mailbox, chan, data28); ++ device_unlock(dev); ++ ++ return rc; ++} ++ ++extern int bcm_mailbox_write(unsigned chan, uint32_t data28) ++{ ++ if (mbox_dev) ++ return dev_mbox_write(mbox_dev, chan, data28); ++ else ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_write); ++ ++extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) ++{ ++ if (mbox_dev) ++ return dev_mbox_read(mbox_dev, chan, data28); ++ else ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_read); ++ ++static void dev_mbox_register(const char *dev_name, struct device *dev) ++{ ++ mbox_dev = dev; ++} ++ ++static int mbox_copy_from_user(void *dst, const void *src, int size) ++{ ++ if ( (uint32_t)src < TASK_SIZE) ++ { ++ return copy_from_user(dst, src, size); ++ } ++ else ++ { ++ memcpy( dst, src, size ); ++ return 0; ++ } ++} ++ ++static int mbox_copy_to_user(void *dst, const void *src, int size) ++{ ++ if ( (uint32_t)dst < TASK_SIZE) ++ { ++ return copy_to_user(dst, src, size); ++ } ++ else ++ { ++ memcpy( dst, src, size ); ++ return 0; ++ } ++} ++ ++static DEFINE_MUTEX(mailbox_lock); ++extern int bcm_mailbox_property(void *data, int size) ++{ ++ uint32_t success; ++ dma_addr_t mem_bus; /* the memory address accessed from videocore */ ++ void *mem_kern; /* the memory address accessed from driver */ ++ int s = 0; ++ ++ mutex_lock(&mailbox_lock); ++ /* allocate some memory for the messages communicating with GPU */ ++ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC); ++ if (mem_kern) { ++ /* create the message */ ++ mbox_copy_from_user(mem_kern, data, size); ++ ++ /* send the message */ ++ wmb(); ++ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); ++ if (s == 0) { ++ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); ++ } ++ if (s == 0) { ++ /* copy the response */ ++ rmb(); ++ mbox_copy_to_user(data, mem_kern, size); ++ } ++ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); ++ } else { ++ s = -ENOMEM; ++ } ++ if (s != 0) ++ printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s); ++ ++ mutex_unlock(&mailbox_lock); ++ return s; ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_property); ++ ++/* ---------------------------------------------------------------------- ++ * Platform Device for Mailbox ++ * -------------------------------------------------------------------- */ ++ ++/* ++ * Is the device open right now? Used to prevent ++ * concurent access into the same device ++ */ ++static int Device_Open = 0; ++ ++/* ++ * This is called whenever a process attempts to open the device file ++ */ ++static int device_open(struct inode *inode, struct file *file) ++{ ++ /* ++ * We don't want to talk to two processes at the same time ++ */ ++ if (Device_Open) ++ return -EBUSY; ++ ++ Device_Open++; ++ /* ++ * Initialize the message ++ */ ++ try_module_get(THIS_MODULE); ++ return 0; ++} ++ ++static int device_release(struct inode *inode, struct file *file) ++{ ++ /* ++ * We're now ready for our next caller ++ */ ++ Device_Open--; ++ ++ module_put(THIS_MODULE); ++ return 0; ++} ++ ++/* ++ * This function is called whenever a process tries to do an ioctl on our ++ * device file. We get two extra parameters (additional to the inode and file ++ * structures, which all device functions get): the number of the ioctl called ++ * and the parameter given to the ioctl function. ++ * ++ * If the ioctl is write or read/write (meaning output is returned to the ++ * calling process), the ioctl call returns the output of this function. ++ * ++ */ ++static long device_ioctl(struct file *file, /* see include/linux/fs.h */ ++ unsigned int ioctl_num, /* number and param for ioctl */ ++ unsigned long ioctl_param) ++{ ++ unsigned size; ++ /* ++ * Switch according to the ioctl called ++ */ ++ switch (ioctl_num) { ++ case IOCTL_MBOX_PROPERTY: ++ /* ++ * Receive a pointer to a message (in user space) and set that ++ * to be the device's message. Get the parameter given to ++ * ioctl by the process. ++ */ ++ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof size); ++ return bcm_mailbox_property((void *)ioctl_param, size); ++ break; ++ default: ++ printk(KERN_ERR DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Module Declarations */ ++ ++/* ++ * This structure will hold the functions to be called ++ * when a process does something to the device we ++ * created. Since a pointer to this structure is kept in ++ * the devices table, it can't be local to ++ * init_module. NULL is for unimplemented functios. ++ */ ++struct file_operations fops = { ++ .unlocked_ioctl = device_ioctl, ++ .open = device_open, ++ .release = device_release, /* a.k.a. close */ ++}; ++ ++static int bcm_vcio_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ struct vc_mailbox *mailbox; ++ ++ mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); ++ if (NULL == mailbox) { ++ printk(KERN_ERR DRIVER_NAME ": failed to allocate " ++ "mailbox memory\n"); ++ ret = -ENOMEM; ++ } else { ++ struct resource *res; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (res == NULL) { ++ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " ++ "resource\n"); ++ ret = -ENODEV; ++ kfree(mailbox); ++ } else { ++ /* should be based on the registers from res really */ ++ mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD); ++ ++ platform_set_drvdata(pdev, mailbox); ++ dev_mbox_register(DRIVER_NAME, &pdev->dev); ++ ++ mbox_irqaction.dev_id = mailbox; ++ setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); ++ printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n", ++ __io_address(ARM_0_MAIL0_RD)); ++ } ++ } ++ ++ if (ret == 0) { ++ /* ++ * Register the character device ++ */ ++ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); ++ ++ /* ++ * Negative values signify an error ++ */ ++ if (ret < 0) { ++ printk(KERN_ERR DRIVER_NAME ++ "Failed registering the character device %d\n", ret); ++ return ret; ++ } ++ } ++ return ret; ++} ++ ++static int bcm_vcio_remove(struct platform_device *pdev) ++{ ++ struct vc_mailbox *mailbox = platform_get_drvdata(pdev); ++ ++ platform_set_drvdata(pdev, NULL); ++ kfree(mailbox); ++ ++ return 0; ++} ++ ++static struct platform_driver bcm_mbox_driver = { ++ .probe = bcm_vcio_probe, ++ .remove = bcm_vcio_remove, ++ ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init bcm_mbox_init(void) ++{ ++ int ret; ++ ++ printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n"); ++ ++ ret = platform_driver_register(&bcm_mbox_driver); ++ if (ret != 0) { ++ printk(KERN_ERR DRIVER_NAME ": failed to register " ++ "on platform\n"); ++ } ++ ++ return ret; ++} ++ ++static void __exit bcm_mbox_exit(void) ++{ ++ platform_driver_unregister(&bcm_mbox_driver); ++} ++ ++arch_initcall(bcm_mbox_init); /* Initialize early */ ++module_exit(bcm_mbox_exit); ++ ++MODULE_AUTHOR("Gray Girling"); ++MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:bcm-mbox"); +diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig +index 7eb94e6..7b58dae 100644 +--- a/arch/arm/mm/Kconfig ++++ b/arch/arm/mm/Kconfig +@@ -358,7 +358,7 @@ config CPU_PJ4B + + # ARMv6 + config CPU_V6 +- bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX ++ bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || MACH_BCM2708 + select CPU_32v6 + select CPU_ABRT_EV6 + select CPU_CACHE_V6 +diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S +index d0390f4..a042de8 100644 +--- a/arch/arm/mm/proc-v6.S ++++ b/arch/arm/mm/proc-v6.S +@@ -73,10 +73,19 @@ ENDPROC(cpu_v6_reset) + * + * IRQs are already disabled. + */ ++ ++/* See jira SW-5991 for details of this workaround */ + ENTRY(cpu_v6_do_idle) +- mov r1, #0 +- mcr p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode +- mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt ++ .align 5 ++ mov r1, #2 ++1: subs r1, #1 ++ nop ++ mcreq p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode ++ mcreq p15, 0, r1, c7, c0, 4 @ wait for interrupt ++ nop ++ nop ++ nop ++ bne 1b + ret lr + + ENTRY(cpu_v6_dcache_clean_area) +diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types +index a10297d..c9ddd87 100644 +--- a/arch/arm/tools/mach-types ++++ b/arch/arm/tools/mach-types +@@ -522,6 +522,7 @@ torbreck MACH_TORBRECK TORBRECK 3090 + prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 + paz00 MACH_PAZ00 PAZ00 3128 + acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 ++bcm2708 MACH_BCM2708 BCM2708 3138 + ag5evm MACH_AG5EVM AG5EVM 3189 + ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 + wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 +diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 02016fc..fed2b92 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -84,7 +84,7 @@ struct vendor_data { + + static unsigned int get_fifosize_arm(struct amba_device *dev) + { +- return amba_rev(dev) < 3 ? 16 : 32; ++ return 16; //TODO: fix: amba_rev(dev) < 3 ? 16 : 32; + } + + static struct vendor_data vendor_arm = { +diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h +index df0c153..c226105 100644 +--- a/include/linux/mmc/host.h ++++ b/include/linux/mmc/host.h +@@ -290,6 +290,7 @@ struct mmc_host { + #define MMC_CAP2_HS400 (MMC_CAP2_HS400_1_8V | \ + MMC_CAP2_HS400_1_2V) + #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) ++#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31) /* Always use multiblock transfers */ + + mmc_pm_flag_t pm_caps; /* supported pm features */ + +diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h +index dba793e..9300f87 100644 +--- a/include/linux/mmc/sdhci.h ++++ b/include/linux/mmc/sdhci.h +@@ -130,6 +130,7 @@ struct sdhci_host { + #define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ + #define SDHCI_SDR104_NEEDS_TUNING (1<<10) /* SDR104/HS200 needs tuning */ + #define SDHCI_USING_RETUNING_TIMER (1<<11) /* Host is using a retuning timer for the card */ ++#define SDHCI_USE_PLATDMA (1<<12) /* Host uses 3rd party DMA */ + + unsigned int version; /* SDHCI spec. version */ + +-- +1.8.3.2 + -- cgit v1.2.3