Commit 9d7fa5ee authored by Kevin Hilman's avatar Kevin Hilman

[PATCH] ARM: DaVinci: core support plus serial and ethernet

Signed-off-by: default avatarKevin Hilman <khilman@mvista.com>
parent 46c0c428
......@@ -270,6 +270,10 @@ config ARCH_AT91RM9200
Say Y here if you intend to run this kernel on an Atmel
AT91RM9200-based board.
config ARCH_DAVINCI
bool "TI DaVinci"
endchoice
source "arch/arm/mach-clps711x/Kconfig"
......@@ -314,6 +318,8 @@ source "arch/arm/mach-realview/Kconfig"
source "arch/arm/mach-at91rm9200/Kconfig"
source "arch/arm/mach-davinci/Kconfig"
# Definitions to make life easier
config ARCH_ACORN
bool
......@@ -525,7 +531,7 @@ config LEDS
ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
ARCH_AT91RM9200
ARCH_AT91RM9200 || ARCH_DAVINCI
help
If you say Y here, the LEDs on your machine will be used
to provide useful information about your current system status.
......@@ -538,7 +544,9 @@ config LEDS
system, but the driver will do nothing.
config LEDS_TIMER
bool "Timer LED" if !ARCH_CDB89712
bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
MACH_OMAP_H2 || MACH_OMAP_PERSEUS2 || \
MACH_DAVINCI_EVM
depends on LEDS
default y if ARCH_EBSA110
help
......@@ -811,7 +819,7 @@ source "drivers/acorn/block/Kconfig"
if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
|| ARCH_IXP23XX
|| ARCH_IXP23XX || ARCH_DAVINCI
source "drivers/ide/Kconfig"
endif
......
......@@ -116,6 +116,7 @@ endif
machine-$(CONFIG_ARCH_REALVIEW) := realview
machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200
machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_DAVINCI) := davinci
ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.
......
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.17-rc4
# Tue May 16 16:59:57 2006
#
CONFIG_ARM=y
CONFIG_MMU=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_VECTORS_BASE=0xffff0000
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
#
# Block layer
#
# CONFIG_BLK_DEV_IO_TRACE is not set
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
#
# System Type
#
# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_CO285 is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_IOP3XX is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
# CONFIG_ARCH_L7200 is not set
# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_AAEC2000 is not set
# CONFIG_ARCH_AT91RM9200 is not set
CONFIG_ARCH_DAVINCI=y
#
# TI DaVinci Implementations
#
#
# DaVinci Core Type
#
CONFIG_ARCH_DAVINCI644x=y
#
# DaVinci Board Type
#
CONFIG_MACH_DAVINCI_EVM=y
CONFIG_DAVINCI_I2C_EXPANDER=y
CONFIG_DAVINCI_MCBSP=y
#
# DaVinci Options
#
#
# Processor Type
#
CONFIG_CPU_32=y
CONFIG_CPU_ARM926T=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5TJ=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_TLB_V4WBI=y
#
# Processor Features
#
CONFIG_ARM_THUMB=y
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
#
# Bus support
#
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
#
# Kernel Features
#
CONFIG_PREEMPT=y
# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
CONFIG_LEDS=y
# CONFIG_LEDS_TIMER is not set
# CONFIG_LEDS_CPU is not set
CONFIG_ALIGNMENT_TRAP=y
#
# Boot options
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE=""
# CONFIG_XIP_KERNEL is not set
#
# Floating point emulation
#
#
# At least one emulation must be selected
#
# CONFIG_FPE_NWFPE is not set
# CONFIG_FPE_FASTFPE is not set
# CONFIG_VFP is not set
#
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_AOUT is not set
# CONFIG_BINFMT_MISC is not set
# CONFIG_ARTHUR is not set
#
# Power management options
#
# CONFIG_PM is not set
# CONFIG_APM is not set
#
# Networking
#
CONFIG_NET=y
#
# Networking options
#
# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
#
# CONFIG_IP_VS is not set
CONFIG_IPV6=m
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
# CONFIG_IPV6_TUNNEL is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
#
# Core Netfilter Configuration
#
# CONFIG_NETFILTER_NETLINK is not set
# CONFIG_NF_CONNTRACK is not set
# CONFIG_NETFILTER_XTABLES is not set
#
# IP: Netfilter Configuration
#
# CONFIG_IP_NF_CONNTRACK is not set
# CONFIG_IP_NF_QUEUE is not set
#
# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
# CONFIG_IP6_NF_QUEUE is not set
#
# DCCP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
#
# TIPC Configuration (EXPERIMENTAL)
#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_IEEE80211 is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
#
# Connector - unified userspace <-> kernelspace linker
#
# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
#
# RAM/ROM/Flash chip drivers
#
# CONFIG_MTD_CFI is not set
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
#
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
#
# NAND Flash Device Drivers
#
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
#
# OneNAND Flash Device Drivers
#
# CONFIG_MTD_ONENAND is not set
#
# Parallel port support
#
# CONFIG_PARPORT is not set
#
# Plug and Play support
#
#
# Block devices
#
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=1
CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
#
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
CONFIG_IDE_TASK_IOCTL=y
#
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
# CONFIG_IDE_ARM is not set
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=m
CONFIG_SCSI_PROC_FS=y
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=m
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
#
# SCSI Transport Attributes
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
#
# SCSI low-level drivers
#
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_DEBUG is not set
#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
#
#
# I2O device support
#
#
# Network device support
#
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
#
# PHY device support
#
# CONFIG_PHYLIB is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
CONFIG_TI_DAVINCI_EMAC=y
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
#
# Ethernet (1000 Mbit)
#
#
# Ethernet (10000 Mbit)
#
#
# Token Ring devices
#
#
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
CONFIG_PPP=m
# CONFIG_PPP_MULTILINK is not set
# CONFIG_PPP_FILTER is not set
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_PPP_DEFLATE=m
# CONFIG_PPP_BSDCOMP is not set
# CONFIG_PPP_MPPE is not set
# CONFIG_PPPOE is not set
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
CONFIG_NETCONSOLE=y
CONFIG_NETPOLL=y
CONFIG_NETPOLL_RX=y
CONFIG_NETPOLL_TRAP=y
CONFIG_NET_POLL_CONTROLLER=y
#
# ISDN subsystem
#
# CONFIG_ISDN is not set
#
# Input device support
#
CONFIG_INPUT=y
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_LKKBD is not set
CONFIG_KEYBOARD_XTKBD=y
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_SERPORT=y
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set
#
# Character devices
#
CONFIG_VT=y
# CONFIG_VT_CONSOLE is not set
CONFIG_HW_CONSOLE=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
#
# IPMI
#
# CONFIG_IPMI_HANDLER is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_RAW_DRIVER is not set
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
#
# I2C support
#
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
#
# I2C Algorithms
#
# CONFIG_I2C_ALGOBIT is not set
# CONFIG_I2C_ALGOPCF is not set
# CONFIG_I2C_ALGOPCA is not set
#
# I2C Hardware Bus support
#
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_PCA_ISA is not set
CONFIG_I2C_DAVINCI=y
#
# Miscellaneous I2C Chip support
#
# CONFIG_SENSORS_DS1337 is not set
# CONFIG_SENSORS_DS1374 is not set
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
#
# SPI support
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
#
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_FSCHER is not set
# CONFIG_SENSORS_FSCPOS is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM75 is not set
# CONFIG_SENSORS_LM77 is not set
# CONFIG_SENSORS_LM78 is not set
# CONFIG_SENSORS_LM80 is not set
# CONFIG_SENSORS_LM83 is not set
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
#
#
# LED devices
#
# CONFIG_NEW_LEDS is not set
#
# LED drivers
#
#
# LED Triggers
#
#
# Multimedia devices
#
CONFIG_VIDEO_DEV=y
#
# Video For Linux
#
#
# Video Adapters
#
# CONFIG_VIDEO_ADV_DEBUG is not set
# CONFIG_VIDEO_CPIA is not set
# CONFIG_VIDEO_CPIA2 is not set
# CONFIG_VIDEO_SAA5246A is not set
# CONFIG_VIDEO_SAA5249 is not set
# CONFIG_TUNER_3036 is not set
# CONFIG_VIDEO_OVCAMCHIP is not set
#
# Encoders and Decoders
#
# CONFIG_VIDEO_MSP3400 is not set
# CONFIG_VIDEO_CS53L32A is not set
# CONFIG_VIDEO_WM8775 is not set
# CONFIG_VIDEO_WM8739 is not set
# CONFIG_VIDEO_CX25840 is not set
# CONFIG_VIDEO_SAA711X is not set
# CONFIG_VIDEO_SAA7127 is not set
# CONFIG_VIDEO_UPD64031A is not set
# CONFIG_VIDEO_UPD64083 is not set
#
# V4L USB devices
#
# CONFIG_VIDEO_EM28XX is not set
# CONFIG_USB_DSBR is not set
# CONFIG_USB_VICAM is not set
# CONFIG_USB_IBMCAM is not set
# CONFIG_USB_KONICAWC is not set
# CONFIG_USB_ET61X251 is not set
# CONFIG_USB_OV511 is not set
# CONFIG_USB_SE401 is not set
# CONFIG_USB_SN9C102 is not set
# CONFIG_USB_STV680 is not set
# CONFIG_USB_W9968CF is not set
# CONFIG_USB_ZC0301 is not set
# CONFIG_USB_PWC is not set
#
# Radio Adapters
#
# CONFIG_RADIO_MAESTRO is not set
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
# CONFIG_USB_DABUSB is not set
#
# Graphics support
#
CONFIG_FB=y
# CONFIG_FB_CFB_FILLRECT is not set
# CONFIG_FB_CFB_COPYAREA is not set
# CONFIG_FB_CFB_IMAGEBLIT is not set
# CONFIG_FB_MACMODES is not set
CONFIG_FB_FIRMWARE_EDID=y
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
#
# Logo configuration
#
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
CONFIG_SOUND=y
#
# Advanced Linux Sound Architecture
#
# CONFIG_SND is not set
#
# Open Sound System
#
CONFIG_SOUND_PRIME=y
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_TVMIXER is not set
#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
# CONFIG_USB_ARCH_HAS_EHCI is not set
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
#
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
#
# USB Host Controller Drivers
#
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_SL811_HCD is not set
#
# USB Device Class drivers
#
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
#
#
# may also be needed; see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_LIBUSUAL is not set
#
# USB Input Devices
#
CONFIG_USB_HID=m
CONFIG_USB_HIDINPUT=y
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
#
# USB HID Boot Protocol drivers
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_TOUCHSCREEN is not set
# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
CONFIG_USB_MON=y
#
# USB port drivers
#
#
# USB Serial Converter support
#
# CONFIG_USB_SERIAL is not set
#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TEST is not set
#
# USB DSL modem support
#
#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
#
# MMC/SD Card support
#
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
CONFIG_MMC_BLOCK=y
#
# Real Time Clock
#
CONFIG_RTC_LIB=y
# CONFIG_RTC_CLASS is not set
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
CONFIG_XFS_FS=m
CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
# CONFIG_XFS_RT is not set
# CONFIG_OCFS2_FS is not set
CONFIG_MINIX_FS=m
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=m
# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_SUMMARY is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
#
# Network File Systems
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
# CONFIG_SMB_NLS_DEFAULT is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
# CONFIG_9P_FS is not set
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
# CONFIG_BSD_DISKLABEL is not set
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
#
# Native Language Support
#
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=m
#
# Profiling support
#
# CONFIG_PROFILING is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_FS is not set
CONFIG_FRAME_POINTER=y
# CONFIG_UNWIND_INFO is not set
# CONFIG_DEBUG_USER is not set
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
# CONFIG_CRYPTO is not set
#
# Hardware crypto devices
#
#
# Library routines
#
CONFIG_CRC_CCITT=m
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
if ARCH_DAVINCI
menu "TI DaVinci Implementations"
comment "DaVinci Core Type"
config ARCH_DAVINCI644x
default y
bool "DaVinci 644x based system"
comment "DaVinci Board Type"
config MACH_DAVINCI_EVM
bool "TI DaVinci EVM"
default y
depends on ARCH_DAVINCI644x
help
Configure this option to specify the whether the board used
for development is a DaVinci EVM
config DAVINCI_I2C_EXPANDER
bool "TI DaVinci I2C Expander"
default y
depends on ARCH_DAVINCI644x
select I2C_DAVINCI
help
Configure this option to specify whether the board used
has I2C exapnder with ATA, USB, CF.
config DAVINCI_MCBSP
bool "DaVinci McBSP Driver"
depends on ARCH_DAVINCI
---help---
DaVinci McBSP driver. Auto-enabled by DaVinci sound driver.
comment "DaVinci Options"
config DAVINCI_BLK_DEV_CF
bool "TI DaVinci CF Card Support"
default Y
depends on BLK_DEV_DAVINCI
help
Configure this option to enable CF Card support.
endmenu
endif
#
# Makefile for the linux kernel.
#
#
# Common objects
obj-y := time.o irq.o dma.o clock.o serial.o
# Board specific
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o i2c-emac.o
obj-$(CONFIG_DAVINCI_MCBSP) += mcbsp.o
obj-$(CONFIG_I2C_DAVINCI) += i2c-client.o
ifeq ($(CONFIG_LEDS),y)
obj-$(CONFIG_MACH_DAVINCI_EVM) += leds-evm.o
endif
zreladdr-y := 0x80008000
params_phys-y := 0x80000100
initrd_phys-y := 0x80800000
/*
* linux/arch/arm/mach-davinci/board-evm.c
*
* TI DaVinci EVM board
*
* Copyright (C) 2006 Texas Instruments.
*
* ----------------------------------------------------------------------------
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* ----------------------------------------------------------------------------
*
*/
/**************************************************************************
* Included Files
**************************************************************************/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/root_dev.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
#include <linux/usb_musb.h>
#endif
#include <asm/setup.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <asm/arch/hardware.h>
#include "clock.h"
static void davinci_nop_release(struct device *dev)
{
/* Nothing */
}
/*
* USB
*/
#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
static struct musb_hdrc_platform_data usb_data = {
#if defined(CONFIG_USB_MUSB_OTG)
/* OTG requires a Mini-AB connector */
.mode = MUSB_OTG,
#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
.mode = MUSB_PERIPHERAL,
#elif defined(CONFIG_USB_MUSB_HOST)
.mode = MUSB_HOST,
#endif
/* irlml6401 switches 5V */
.power = 255, /* sustains 3.0+ Amps (!) */
.potpgt = 4, /* ~8 msec */
/* REVISIT multipoint is a _chip_ capability; not board specific */
.multipoint = 1,
};
static struct resource usb_resources [] = {
{
/* physical address */
.start = DAVINCI_USB_OTG_BASE,
.end = DAVINCI_USB_OTG_BASE + 0x5ff,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_USBINT,
.flags = IORESOURCE_IRQ,
},
};
static u64 usb_dmamask = DMA_32BIT_MASK;
static struct platform_device usb_dev = {
.name = "musb_hdrc",
.id = -1,
.dev = {
.platform_data = &usb_data,
.dma_mask = &usb_dmamask,
.coherent_dma_mask = DMA_32BIT_MASK,
},
.resource = usb_resources,
.num_resources = ARRAY_SIZE(usb_resources),
};
static inline void setup_usb(void)
{
/* REVISIT: everything except platform_data setup should be
* shared between all DaVinci boards using the same core.
*/
int status;
status = platform_device_register(&usb_dev);
if (status != 0)
pr_debug("setup_usb --> %d\n", status);
else
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_USB, 1);
}
#else
static inline void setup_usb(void)
{
/* NOP */
}
#endif /* CONFIG_USB_MUSB_HDRC */
#ifdef CONFIG_I2C_DAVINCI
static struct resource i2c_resources[] = {
{
.start = IO_ADDRESS(DAVINCI_I2C_BASE),
.end = IO_ADDRESS(DAVINCI_I2C_BASE) + 0x40,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_I2C,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device davinci_i2c_device = {
.name = "i2c_davinci",
.id = 1,
.dev = {
.release = davinci_nop_release,
},
.num_resources = ARRAY_SIZE(i2c_resources),
.resource = i2c_resources,
};
static inline void setup_i2c(void)
{
(void) platform_device_register(&davinci_i2c_device);
}
#else
static inline void setup_i2c(void)
{
/* NOP */
}
#endif
static void board_init(void)
{
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSMSTR, 1);
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSSLV, 1);
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPCC, 1);
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC0, 1);
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC1, 1);
/* Turn on WatchDog timer LPSC. Needed for RESET to work */
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);
}
/*
* DaVinci IO Mapping
*/
static struct map_desc davinci_io_desc[] __initdata = {
{
.virtual = IO_VIRT,
.pfn = __phys_to_pfn(IO_PHYS),
.length = IO_SIZE,
.type = MT_DEVICE
},
{
.virtual = DAVINCI_IRAM_VIRT,
.pfn = __phys_to_pfn(DAVINCI_IRAM_BASE),
.length = SZ_16K,
.type = MT_DEVICE
}
};
static void __init
davinci_map_io(void)
{
iotable_init(davinci_io_desc, ARRAY_SIZE(davinci_io_desc));
/* Initialize the DaVinci EVM board settigs */
board_init ();
}
static __init void evm_init(void)
{
setup_usb();
setup_i2c();
}
extern void davinci_irq_init(void);
extern struct sys_timer davinci_timer;
MACHINE_START(DAVINCI_EVM, "DaVinci EVM")
/* Maintainer: MontaVista Software <source@mvista.com> */
.phys_io = IO_PHYS,
.io_pg_offst = (io_p2v(IO_PHYS) >> 18) & 0xfffc,
.boot_params = (DAVINCI_DDR_BASE + 0x100),
.map_io = davinci_map_io,
.init_irq = davinci_irq_init,
.timer = &davinci_timer,
.init_machine = evm_init,
MACHINE_END
/*
* linux/arch/arm/mach-davinci/clock.c
*
* TI DaVinci clock config file
*
* Copyright (C) 2006 Texas Instruments.
*
* ----------------------------------------------------------------------------
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* ----------------------------------------------------------------------------
*
*/
/**************************************************************************
* Included Files
**************************************************************************/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/root_dev.h>
#include <linux/clk.h>
#include <asm/setup.h>
#include <asm/semaphore.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/arch/hardware.h>
#include "clock.h"
#define DAVINCI_MAX_CLK 9
#define PLL1_PLLM __REG(0x01c40910)
#define PLL2_PLLM __REG(0x01c40D10)
#define PTCMD __REG(0x01C41120)
#define PDSTAT __REG(0x01C41200)
#define PDCTL1 __REG(0x01C41304)
#define EPCPR __REG(0x01C41070)
#define PTSTAT __REG(0x01C41128)
#define MDSTAT IO_ADDRESS(0x01C41800)
#define MDCTL IO_ADDRESS(0x01C41A00)
#define VDD3P3V_PWDN __REG(0x01C40048)
#define PINMUX0 __REG(0x01c40000)
#define PINMUX1 __REG(0x01c40004)
static LIST_HEAD(clocks);
static DECLARE_MUTEX(clocks_sem);
static DEFINE_SPINLOCK(clockfw_lock);
static unsigned int commonrate;
static unsigned int armrate;
static unsigned int fixedrate = 27000000; /* 27 MHZ */
/**************************************
Routine: board_setup_psc
Description: Enable/Disable a PSC domain
**************************************/
void board_setup_psc(unsigned int domain, unsigned int id, char enable)
{
volatile unsigned int *mdstat = (unsigned int *)((int)MDSTAT + 4 * id);
volatile unsigned int *mdctl = (unsigned int *)((int)MDCTL + 4 * id);
if (enable) {
*mdctl |= 0x00000003; /* Enable Module */
} else {
*mdctl &= 0xFFFFFFF2; /* Disable Module */
}
if ((PDSTAT & 0x00000001) == 0) {
PDCTL1 |= 0x1;
PTCMD = (1 << domain);
while ((((EPCPR >> domain) & 1) == 0)) ;
PDCTL1 |= 0x100;
while (!(((PTSTAT >> domain) & 1) == 0)) ;
} else {
PTCMD = (1 << domain);
while (!(((PTSTAT >> domain) & 1) == 0)) ;
}
if (enable) {
while (!((*mdstat & 0x0000001F) == 0x3)) ;
} else {
while (!((*mdstat & 0x0000001F) == 0x2)) ;
}
}
static int board_setup_peripheral(unsigned int id)
{
switch (id) {
case DAVINCI_LPSC_ATA:
PINMUX0 |= (1 << 17) | (1 << 16);
break;
case DAVINCI_LPSC_MMC_SD:
/* VDD power manupulations are done in U-Boot for CPMAC
* so applies to MMC as well
*/
/*Set up the pull regiter for MMC */
VDD3P3V_PWDN = 0x0;
PINMUX1 &= (~(1 << 9));
break;
case DAVINCI_LPSC_I2C:
PINMUX1 |= (1 << 7);
break;
case DAVINCI_LPSC_McBSP:
PINMUX1 |= (1 << 10);
break;
default:
break;
}
}
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
down(&clocks_sem);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
up(&clocks_sem);
return clk;
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
if (clk && !IS_ERR(clk))
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
int __clk_enable(struct clk *clk)
{
if (clk->flags & ALWAYS_ENABLED)
return 0;
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1);
return 0;
}
void __clk_disable(struct clk *clk)
{
if (clk->usecount)
return;
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0);
}
int clk_enable(struct clk *clk)
{
unsigned long flags;
int ret = 0;
if (clk->usecount++ == 0) {
spin_lock_irqsave(&clockfw_lock, flags);
ret = __clk_enable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
board_setup_peripheral(clk->lpsc);
}
return ret;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
unsigned long flags;
if (clk->usecount > 0 && !(--clk->usecount)) {
spin_lock_irqsave(&clockfw_lock, flags);
__clk_disable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
return *(clk->rate);
}
EXPORT_SYMBOL(clk_get_rate);
int clk_register(struct clk *clk)
{
down(&clocks_sem);
list_add(&clk->node, &clocks);
up(&clocks_sem);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
down(&clocks_sem);
list_del(&clk->node);
up(&clocks_sem);
}
EXPORT_SYMBOL(clk_unregister);
static struct clk davinci_clks[DAVINCI_MAX_CLK] = {
{
.name = "ARMCLK",
.rate = &armrate,
.lpsc = -1,
.flags = ALWAYS_ENABLED,
},
{
.name = "UART",
.rate = &fixedrate,
.lpsc = DAVINCI_LPSC_UART0,
.usecount = 1,
},
{
.name = "EMACCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
},
{
.name = "I2CCLK",
.rate = &fixedrate,
.lpsc = DAVINCI_LPSC_I2C,
},
{
.name = "IDECLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_ATA,
},
{
.name = "McBSPCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_McBSP,
},
{
.name = "MMCSDCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_MMC_SD,
},
{
.name = "SPICLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_SPI,
},
{
.name = "AEMIFCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_AEMIF,
.usecount = 1,
}
};
static int davinci_clk_init(void)
{
struct clk *clkp;
int count = 0;
commonrate = ((PLL1_PLLM + 1) * 27000000) / 6;
armrate = ((PLL1_PLLM + 1) * 27000000) / 2;
for (clkp = davinci_clks; count < DAVINCI_MAX_CLK; count++, clkp++) {
clk_register(clkp);
/* Turn on clocks that have been enabled in the
* table above */
if (clkp->usecount) {
clk_enable(clkp);
}
}
return 0;
}
arch_initcall(davinci_clk_init);
/*
* linux/arch/arm/mach-davinci/clock.h
*
* BRIEF MODULE DESCRIPTION
* TI DAVINCI clock definitions
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
#define __ARCH_ARM_DAVINCI_CLOCK_H
struct module;
struct clk {
struct list_head node;
struct module *owner;
const char *name;
unsigned int *rate;
__s8 usecount;
__u8 flags;
__u8 lpsc;
};
/* Clock flags */
#define RATE_CKCTL 1
#define RATE_FIXED 2
#define RATE_PROPAGATES 4
#define VIRTUAL_CLOCK 8
#define ALWAYS_ENABLED 16
#define ENABLE_REG_32BIT 32
int clk_register(struct clk *clk);
void clk_unregister(struct clk *clk);
int clk_init(void);
void board_setup_psc(unsigned int domain, unsigned int id, char enable);
#endif
/*
* linux/arch/arm/mach-davinci/dma.c
*
* TI DaVinci DMA file
*
* Copyright (C) 2006 Texas Instruments.
*
* ----------------------------------------------------------------------------
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* ----------------------------------------------------------------------------
*
*/
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/arch/memory.h>
#include <linux/kernel.h>
#include <asm/arch/hardware.h>
#include <asm/arch/irqs.h>
#include <asm/arch/edma.h>
static spinlock_t dma_chan_lock;
static struct device_driver edma_driver;
static struct platform_device edma_dev;
#define LOCK_INIT spin_lock_init(&dma_chan_lock)
#define LOCK spin_lock(&dma_chan_lock)
#define UNLOCK spin_unlock(&dma_chan_lock)
typedef void (*intr_callback) (void);
static int register_dma_interrupts(intr_callback, intr_callback, intr_callback,
intr_callback);
#define DAVINCI_DMA_REGISTER_BASE DAVINCI_DMA_3PCC_BASE
static edmacc_regs *get_edma_base(void)
{
return ((edmacc_regs *) IO_ADDRESS(DAVINCI_DMA_REGISTER_BASE));
}
static intr_callback cb[4];
/* Structure containing the dma channel parameters */
static struct davinci_dma_lch {
int dev_id;
int in_use; /* 1-used 0-unused */
int link_lch;
int dma_running;
int param_no;
int tcc;
} dma_chan[DAVINCI_EDMA_NUM_PARAMENTRY];
static struct dma_interrupt_data {
void (*callback) (int lch, unsigned short ch_status, void *data);
void *data;
} intr_data[64];
/*
Each bit field of the elements bellow indicate the corresponding EDMA channel
availability on arm side events
*/
static unsigned long edma_channels_arm[] = {
0xffffffff,
0xffffffff
};
/*
Each bit field of the elements bellow indicate the corresponding QDMA channel
availability on arm side events
*/
static unsigned char qdma_channels_arm[] = {
0xff
};
/*
Each bit field of the elements bellow indicate corresponding PARAM entry
availibility on arm side events
*/
static unsigned long param_entry_arm[] = {
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
};
/*
Each bit field of the elements bellow indicate whether a PARAM entry
is free or in use
1 - free
0 - in use
*/
static unsigned long param_entry_use_status[] = {
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff
};
/*
Each bit field of the elements bellow indicate whether a intrerrupt
is free or in use
1 - free
0 - in use
*/
static unsigned long dma_intr_use_status[] = {
0xffffffff,
0xffffffff
};
/*
This lists the DMA channel numbers which does not have any events
associated with it
*/
static int dma_chan_no_event[] = {
0, 1, 12, 13, 14, 15, 25, 30, 31, 45, 46, 47, 55, 56, 57, 58, 59, 60,
61, 62, 63, -1
};
static int channel_queue_mapping[][2] = {
/* {channel no, event queue no } */
{0, 0}, {1, 1}, {2, 0}, {3, 1}, {4, 0}, {5, 1}, {6, 0}, {7, 1},
{8, 0}, {9, 1}, {10, 0}, {11, 1}, {12, 0}, {13, 1}, {14, 0},
{15, 1}, {16, 0}, {17, 1}, {18, 0}, {19, 1}, {20, 0}, {21, 1},
{22, 0}, {23, 1}, {24, 0}, {25, 1}, {26, 0}, {27, 1}, {28, 0},
{29, 1}, {30, 0}, {31, 1}, {32, 0}, {33, 1}, {34, 0}, {35, 1},
{36, 0}, {37, 1}, {38, 0}, {39, 1}, {40, 0}, {41, 1}, {42, 0},
{43, 1}, {44, 0}, {45, 1}, {46, 0}, {47, 1}, {48, 0}, {49, 1},
{50, 0}, {51, 1}, {52, 0}, {53, 1}, {54, 0}, {55, 1}, {56, 0},
{57, 1}, {58, 0}, {59, 1}, {60, 0}, {61, 1}, {62, 0}, {63, 1},
{64, 0}, {65, 1}, {66, 0}, {67, 1}, {68, 0}, {69, 1}, {70, 0},
{71, 1}, {-1, -1}
};
static int queue_tc_mapping[DAVINCI_EDMA_NUM_EVQUE + 1][2] = {
/* {event queue no, TC no} */
{0, 0},
{1, 1},
{-1, -1}
};
static int queue_priority_mapping[DAVINCI_EDMA_NUM_EVQUE + 1][2] = {
/* {event queue no, Priority} */
{0, 0},
{1, 1},
{-1, -1}
};
static int qdam_to_param_mapping[8] = { 0 };
volatile edmacc_regs *ptr_edmacc_regs = NULL;
/*****************************************************************************/
static void map_dmach_queue(int ch_no, int queue_no)
{
if (ch_no < DAVINCI_EDMA_NUM_DMACH) {
int bit_start = (ch_no % 8) * 4;
ptr_edmacc_regs->dmaqnum[ch_no >> 3] &= (~(0x7 << bit_start));
ptr_edmacc_regs->dmaqnum[ch_no >> 3] |=
((queue_no & 0x7) << bit_start);
} else if (ch_no >= DAVINCI_EDMA_NUM_DMACH
&&
ch_no < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
int bit_start = (ch_no - DAVINCI_EDMA_NUM_DMACH) * 4;
ptr_edmacc_regs->qdmaqnum &= (~(0x7 << bit_start));
ptr_edmacc_regs->qdmaqnum |= ((queue_no & 0x7) << bit_start);
}
}
/* For Davinci this Macro supports mapping only for QDMA channels and PaRam
entry */
static void map_dmach_param(int ch_no, int param_no)
{
if (ch_no >= DAVINCI_EDMA_NUM_DMACH
&& ch_no < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
ptr_edmacc_regs->qchmap[ch_no - DAVINCI_EDMA_NUM_DMACH] &=
~(PAENTRY | TRWORD);
ptr_edmacc_regs->qchmap[ch_no - DAVINCI_EDMA_NUM_DMACH] |=
(((param_no & 0x1ff) << 5) | (QDMA_TRWORD << 2));
}
}
static void map_queue_tc(int queue_no, int tc_no)
{
int bit_start = queue_no * 4;
ptr_edmacc_regs->quetcmap &= ~(0x7 << bit_start);
ptr_edmacc_regs->quetcmap |= ((tc_no & 0x7) << bit_start);
}
static void assign_priority_to_queue(int queue_no, int priority)
{
int bit_start = queue_no * 4;
ptr_edmacc_regs->quepri &= ~(0x7 << bit_start);
ptr_edmacc_regs->quepri |= ((priority & 0x7) << bit_start);
}
/******************************************************************************
*
* DMA Param entry requests: Requests for the param structure entry for the dma
* channel passed
* Arguments:
* lch - logical channel for which param entry is being requested.
*
* Return: param number on success, or negative error number on failure
*
*****************************************************************************/
static int request_param(int lch, int dev_id)
{
int i = 0, j = 0, is_break = 0;
if (lch >= 0 && lch < DAVINCI_EDMA_NUM_DMACH) {
/*
In davinci there is 1:1 mapping between edma channels
and param sets
*/
LOCK;
/* It maintains param entry availability bitmap which
could be updated by several thread same channel
and so requires protection
*/
param_entry_use_status[lch / 32] &= (~(1 << (lch % 32)));
UNLOCK;
return lch;
} else {
if (dev_id >= DAVINCI_DMA_QDMA0 &&
dev_id <= DAVINCI_DMA_QDMA7) {
i = 0;
} else if (dev_id == DAVINCI_EDMA_PARAM_ANY) {
i = DAVINCI_EDMA_NUM_DMACH;
}
/* This allocation alogrithm requires complete lock because
availabilty of param entry is checked from structure
param_entry_use_status and same struct is updated back also
once allocated
*/
LOCK;
while (i < DAVINCI_EDMA_NUM_PARAMENTRY) {
j = 0, is_break = 1;
if ((param_entry_arm[i / 32] & (1 << (i % 32))) &&
(param_entry_use_status[i / 32] & (1 << (i % 32))))
{
if (dev_id != DAVINCI_EDMA_PARAM_ANY) {
while (dma_chan_no_event[j] != -1) {
if (dma_chan_no_event[j] == i) {
is_break = 0;
}
j++;
}
if (!is_break) {
break;
}
} else {
break;
}
i++;
} else {
i++;
}
}
if (i < DAVINCI_EDMA_NUM_PARAMENTRY) {
param_entry_use_status[i / 32] &= (~(1 << (i % 32)));
UNLOCK;
dev_dbg(&edma_dev.dev, "param no=%d\r\n", i);
return i;
} else {
UNLOCK;
return -1; /* no free param */
}
}
}
/******************************************************************************
*
* Free dma param entry: Freethe param entry number passed
* Arguments:
* param_no - Param entry to be released or freed out
*
* Return: N/A
*
*****************************************************************************/
static void free_param(int param_no)
{
if (param_no >= 0 && param_no < DAVINCI_EDMA_NUM_PARAMENTRY) {
LOCK;
/* This is global data structure and could be accessed
by several thread
*/
param_entry_use_status[param_no / 32] |= (1 << (param_no % 32));
UNLOCK;
}
}
/******************************************************************************
*
* DMA interrupt requests: Requests for the interrupt on the free channel
*
* Arguments:
* lch - logical channel number for which the interrupt is to be requested
* for the free channel.
* callback - callback function registered for the requested interrupt
* channel
* data - channel private data.
*
* Return: free interrupt channel number on success, or negative error number
* on failure
*
*****************************************************************************/
static int request_dma_interrupt(int lch,
void (*callback) (int lch,
unsigned short ch_status,
void *data),
void *data, int param_no, int requested_tcc)
{
signed int free_intr_no = -1;
int i = 0, j = 0, is_break = 0;
/* edma channels */
if (lch >= 0 && lch < DAVINCI_EDMA_NUM_DMACH) {
/* Bitmap dma_intr_use_status is used to identify availabe tcc
for interrupt purpose. This could be modified by several
thread and same structure is checked availabilty as well as
updated once it's found that resource is avialable */
LOCK;
if (dma_intr_use_status[lch / 32] & (1 << (lch % 32))) {
/* in use */
dma_intr_use_status[lch / 32] &= (~(1 << (lch % 32)));
UNLOCK;
free_intr_no = lch;
dev_dbg(&edma_dev.dev, "interrupt no=%d\r\n", free_intr_no);
} else {
UNLOCK;
dev_dbg(&edma_dev.dev, "EDMA:Error\r\n");
return -1;
}
}
/* qdma channels */
else if (lch >= DAVINCI_EDMA_NUM_DMACH
&& lch < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
if (requested_tcc != TCC_ANY) {
/* Complete allocation algo requires lock and as it's
shared resources could be invoked by several thread.
Structure dma_intr_use_status is used to check
whether resource is availabe or not and latter marked
as not available in the same structure */
LOCK;
if (dma_intr_use_status[requested_tcc / 32] &
(1 << (requested_tcc % 32))) {
j = 0;
is_break = 1;
while (dma_chan_no_event[j] != -1) {
if (dma_chan_no_event[j] ==
requested_tcc) {
is_break = 0;
break;
}
j++;
}
if (!is_break) {
dma_intr_use_status[requested_tcc / 32]
&= (~(1 << (requested_tcc % 32)));
free_intr_no = requested_tcc;
dev_dbg(&edma_dev.dev,
"interrupt no=%d\r\n",
free_intr_no);
} else {
UNLOCK;
dev_dbg(&edma_dev.dev,
"Error - wrong tcc passed\r\n");
return -1;
}
UNLOCK;
} else {
UNLOCK;
dev_dbg(&edma_dev.dev,
"Error - wrong tcc passed\r\n");
return -1;
}
} else {
i = 0;
LOCK;
while (i < DAVINCI_EDMA_NUM_DMACH) {
j = 0;
is_break = 1;
if (dma_intr_use_status[i / 32] &
(1 << (i % 32))) {
while (dma_chan_no_event[j] != -1) {
if (dma_chan_no_event[j] == i) {
is_break = 0;
break;
}
j++;
}
if (!is_break) {
dma_intr_use_status[i / 32] &=
(~(1 << (i % 32)));
free_intr_no = i;
dev_dbg(&edma_dev.dev,
"interrupt no=%d\r\n",
free_intr_no);
break;
}
i++;
} else {
i++;
}
}
UNLOCK;
}
} else {
dev_dbg(&edma_dev.dev, "ERROR lch = %d\r\n", lch);
}
if (is_break) {
dev_dbg(&edma_dev.dev, "While allocating EDMA channel for QDMA");
}
if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
if (free_intr_no < 32) {
ptr_edmacc_regs->dra[0].drae =
ptr_edmacc_regs->dra[0].drae | (1 << free_intr_no);
} else {
ptr_edmacc_regs->dra[0].draeh =
ptr_edmacc_regs->dra[0].
draeh | (1 << (free_intr_no - 32));
}
}
if (free_intr_no >= 0 && free_intr_no < 64) {
(free_intr_no < 32) ?
(ptr_edmacc_regs->shadow[0].iesr |= (1UL << free_intr_no))
: (ptr_edmacc_regs->shadow[0].iesrh |=
(1UL << (free_intr_no - 32)));
intr_data[free_intr_no].callback = callback;
intr_data[free_intr_no].data = data;
}
return free_intr_no;
}
/******************************************************************************
*
* Free the dma interrupt: Releases the dma interrupt on the channel
*
* Arguments:
* intr_no - interrupt number on the channel to be released or freed out
*
* Return: N/A
*
*****************************************************************************/
static void free_dma_interrupt(int intr_no)
{
if (intr_no >= 0 && intr_no < 64) {
(intr_no < 32) ? (ptr_edmacc_regs->shadow[0].icr |=
(1UL << (intr_no))) : (ptr_edmacc_regs->
shadow[0].icrh |=
(1UL <<
(intr_no - 32)));
LOCK;
/* Global structure and could be modified by several task */
dma_intr_use_status[intr_no / 32] |= (1 << (intr_no % 32));
UNLOCK;
intr_data[intr_no].callback = NULL;
intr_data[intr_no].data = NULL;
}
}
/******************************************************************************
*
* DMA interrupt handler
*
*****************************************************************************/
static void dma_irq_handler(void)
{
int i;
unsigned int cnt;
cnt = 0;
if ((ptr_edmacc_regs->shadow[0].ipr == 0)
&& (ptr_edmacc_regs->shadow[0].iprh == 0))
return;
while (1) {
if (ptr_edmacc_regs->shadow[0].ipr) {
dev_dbg(&edma_dev.dev, "IPR =%d\r\n",
ptr_edmacc_regs->shadow[0].ipr);
for (i = 0; i < 32; i++) {
if (ptr_edmacc_regs->shadow[0].ipr & (1 << i)) {
/* Clear the corresponding IPR bits */
ptr_edmacc_regs->shadow[0].icr |=
(1 << i);
if (intr_data[i].callback) {
intr_data[i].callback(i,
DMA_COMPLETE,
intr_data
[i].data);
}
}
}
} else if (ptr_edmacc_regs->shadow[0].iprh) {
dev_dbg(&edma_dev.dev, "IPRH =%d\r\n",
ptr_edmacc_regs->shadow[0].iprh);
for (i = 0; i < 32; i++) {
if (ptr_edmacc_regs->shadow[0].iprh & (1 << i)) {
/* Clear the corresponding IPR bits */
ptr_edmacc_regs->shadow[0].icrh |=
(1 << i);
if (intr_data[32 + i].callback) {
intr_data[32 + i].callback(32 +
i,
DMA_COMPLETE,
intr_data
[32 +
i].
data);
}
}
}
}
if ((ptr_edmacc_regs->shadow[0].ipr == 0)
&& (ptr_edmacc_regs->shadow[0].iprh == 0)) {
break;
}
cnt++;
if (cnt > 10) {
break;
}
}
ptr_edmacc_regs->shadow[0].ieval = 0x1;
}
/******************************************************************************
*
* DMA error interrupt handler
*
*****************************************************************************/
static void dma_ccerr_handler(void)
{
int i;
unsigned int cnt;
cnt = 0;
if ((ptr_edmacc_regs->emr == 0) && (ptr_edmacc_regs->emr == 0) &&
(ptr_edmacc_regs->qemr == 0) && (ptr_edmacc_regs->ccerr == 0))
return;
while (1) {
if (ptr_edmacc_regs->emr) {
dev_dbg(&edma_dev.dev, "EMR =%d\r\n", ptr_edmacc_regs->emr);
for (i = 0; i < 32; i++) {
if (ptr_edmacc_regs->emr & (1 << i)) {
/* Clear the corresponding EMR bits */
ptr_edmacc_regs->emcr |= (1 << i);
/* Clear any SER */
ptr_edmacc_regs->shadow[0].secr |=
(1 << i);
if (intr_data[i].callback) {
intr_data[i].callback(i,
DMA_CC_ERROR,
intr_data
[i].data);
}
}
}
} else if (ptr_edmacc_regs->emrh) {
dev_dbg(&edma_dev.dev, "EMRH =%d\r\n",
ptr_edmacc_regs->emrh);
for (i = 0; i < 32; i++) {
if (ptr_edmacc_regs->emrh & (1 << i)) {
/* Clear the corresponding IPR bits */
ptr_edmacc_regs->emcrh |= (1 << i);
/* Clear any SER */
ptr_edmacc_regs->shadow[0].secrh |=
(1 << i);
if (intr_data[i].callback) {
intr_data[i].callback(i,
DMA_CC_ERROR,
intr_data
[i].data);
}
}
}
} else if (ptr_edmacc_regs->qemr) {
dev_dbg(&edma_dev.dev, "QEMR =%d\r\n",
ptr_edmacc_regs->qemr);
for (i = 0; i < 8; i++) {
if (ptr_edmacc_regs->qemr & (1 << i)) {
/* Clear the corresponding IPR bits */
ptr_edmacc_regs->qemcr |= (1 << i);
ptr_edmacc_regs->shadow[0].qsecr |=
(1 << i);
}
}
} else if (ptr_edmacc_regs->ccerr) {
dev_dbg(&edma_dev.dev, "CCERR =%d\r\n",
ptr_edmacc_regs->ccerr);
for (i = 0; i < 8; i++) {
if (ptr_edmacc_regs->ccerr & (1 << i)) {
/* Clear the corresponding IPR bits */
ptr_edmacc_regs->ccerrclr |= (1 << i);
}
}
}
if ((ptr_edmacc_regs->emr == 0)
&& (ptr_edmacc_regs->emrh == 0)
&& (ptr_edmacc_regs->qemr == 0)
&& (ptr_edmacc_regs->ccerr == 0)) {
break;
}
cnt++;
if (cnt > 10) {
break;
}
}
ptr_edmacc_regs->eeval = 0x1;
}
/******************************************************************************
*
* DMA error interrupt handler
*
*****************************************************************************/
static void dma_tc1err_handler(void)
{
}
/******************************************************************************
*
* DMA error interrupt handler
*
*****************************************************************************/
static void dma_tc2err_handler(void)
{
}
/******************************************************************************
*
* DMA initialisation on davinci
*
*****************************************************************************/
int __init arch_dma_init(void)
{
int i;
edma_driver.name = "edma";
edma_dev.name = "dma";
edma_dev.id = -1;
edma_dev.dev.driver = &edma_driver;
ptr_edmacc_regs = get_edma_base();
dev_dbg(&edma_dev.dev, "DMA REG BASE ADDR=%x\n", ptr_edmacc_regs);
memset(dma_chan, 0x00, sizeof(dma_chan));
memset((void *)&(ptr_edmacc_regs->paramentry[0]), 0x00,
sizeof(ptr_edmacc_regs->paramentry));
i = 0;
/* Channel to queue mapping */
while (channel_queue_mapping[i][0] != -1) {
map_dmach_queue(channel_queue_mapping[i][0],
channel_queue_mapping[i][1]);
i++;
}
i = 0;
/* Event queue to TC mapping */
while (queue_tc_mapping[i][0] != -1) {
map_queue_tc(queue_tc_mapping[i][0], queue_tc_mapping[i][1]);
i++;
}
i = 0;
/* Event queue priority mapping */
while (queue_priority_mapping[i][0] != -1) {
assign_priority_to_queue(queue_priority_mapping[i][0],
queue_priority_mapping[i][1]);
i++;
}
for (i = 0; i < DAVINCI_EDMA_NUM_REGIONS; i++) {
ptr_edmacc_regs->dra[i].drae = 0x0;
ptr_edmacc_regs->dra[i].draeh = 0x0;
ptr_edmacc_regs->qrae[i] = 0x0;
}
LOCK_INIT;
return 0;
}
/******************************************************************************
*
* DMA channel requests: Requests for the dma device passed if it is free
*
* Arguments:
* dev_id - request for the param entry device id
* dev_name - device name
* callback - pointer to the channel callback.
* Arguments:
* lch - channel no, which is the IPR bit position,
* indicating from which channel the interrupt arised.
* data - channel private data, which is received as one of the
* arguments in davinci_request_dma.
* data - private data for the channel to be requested, which is used to
* pass as a parameter in the callback function
* in irq handler.
* lch - contains the device id allocated
* tcc - Transfer Completion Code, used to set the IPR register bit
* after transfer completion on that channel.
* eventq_no - Event Queue no to which the channel will be associated with
* (valied only if you are requesting for a DMA MasterChannel)
* Values : 0 to 7
* -1 for Default queue
* INPUT: dev_id
* OUTPUT: *dma_ch_out
*
* Return: zero on success, or corresponding error no on failure
*
*****************************************************************************/
int davinci_request_dma(int dev_id, const char *dev_name,
void (*callback) (int lch, unsigned short ch_status,
void *data),
void *data, int *lch,
int *tcc, enum dma_event_q eventq_no)
{
int ret_val = 0, i = 0;
static int req_flag = 0;
int temp_ch = 0;
/* checking the ARM side events */
if (dev_id >= 0 && (dev_id < DAVINCI_EDMA_NUM_DMACH)) {
if (!(edma_channels_arm[dev_id / 32] & (0x1 << (dev_id % 32)))) {
dev_dbg(&edma_dev.dev,
"dev_id = %d not supported on ARM side\r\n",
dev_id);
return -EINVAL;
}
} else if (dev_id >= DAVINCI_EDMA_NUM_DMACH
&& dev_id <=
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
if (!(qdma_channels_arm[0] &
(0x1 << (dev_id - DAVINCI_EDMA_NUM_DMACH)))) {
dev_dbg(&edma_dev.dev,
"dev_id = %d not supported on ARM side\r\n",
dev_id);
return -EINVAL;
}
}
if ((dev_id != DAVINCI_DMA_CHANNEL_ANY)
&& (dev_id != DAVINCI_EDMA_PARAM_ANY)) {
if (dev_id >= DAVINCI_EDMA_NUM_DMACH
&&
dev_id < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)
) {
ptr_edmacc_regs->qrae[0] =
ptr_edmacc_regs->qrae[0] |
(1 << (dev_id - DAVINCI_EDMA_NUM_DMACH));
} else {
if (dev_id < 32) {
ptr_edmacc_regs->dra[0].drae =
ptr_edmacc_regs->dra[0].drae |
(1 << dev_id);
} else {
ptr_edmacc_regs->dra[0].draeh =
ptr_edmacc_regs->dra[0].draeh |
(1 << (dev_id - 32));
}
}
}
if (!req_flag) {
if (register_dma_interrupts
(dma_irq_handler, dma_ccerr_handler,
dma_tc1err_handler, dma_tc2err_handler)) {
dev_dbg(&edma_dev.dev,
"register_dma_interrupts failed\r\n");
return -EINVAL;
} else
req_flag = 1;
}
if (dev_id >= 0 && dev_id < (DAVINCI_EDMA_NUM_DMACH)) {
/* The 64 Channels are mapped to the first 64 PARAM entries */
if (!dma_chan[dev_id].in_use) {
*lch = dev_id;
dma_chan[*lch].param_no = request_param(*lch, dev_id);
if (dma_chan[*lch].param_no == -1) {
return -EINVAL;
} else
dev_dbg(&edma_dev.dev, "param_no=%d\r\n",
dma_chan[*lch].param_no);
if (callback) {
dma_chan[*lch].tcc =
request_dma_interrupt(*lch, callback, data,
dma_chan[*lch].
param_no, *tcc);
if (dma_chan[*lch].tcc == -1) {
return -EINVAL;
} else {
*tcc = dma_chan[*lch].tcc;
dev_dbg(&edma_dev.dev, "tcc_no=%d\r\n",
dma_chan[*lch].tcc);
}
} else
dma_chan[*lch].tcc = -1;
map_dmach_queue(dev_id, eventq_no);
ret_val = 0;
} else
ret_val = -EINVAL;
}
else if (dev_id >= DAVINCI_EDMA_NUM_DMACH && dev_id <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
if ((qdam_to_param_mapping[dev_id - DAVINCI_EDMA_NUM_DMACH] !=
-1)
&&
(dma_chan
[qdam_to_param_mapping[dev_id - DAVINCI_EDMA_NUM_DMACH]].
in_use)
) {
ret_val = -EINVAL;
} else {
*lch = dev_id;
dma_chan[*lch].param_no = request_param(*lch, dev_id);
if (dma_chan[*lch].param_no == -1) {
dev_dbg(&edma_dev.dev, "request_param failed\r\n");
return -EINVAL;
} else {
dev_dbg(&edma_dev.dev, "param_no=%d\r\n",
dma_chan[*lch].param_no);
map_dmach_param(*lch, dma_chan[*lch].param_no);
}
if (callback) {
dma_chan[*lch].tcc =
request_dma_interrupt(*lch, callback, data,
dma_chan[*lch].
param_no, *tcc);
if (dma_chan[*lch].tcc == -1) {
return -EINVAL;
} else {
*tcc = dma_chan[*lch].tcc;
dev_dbg(&edma_dev.dev, "tcc_no=%d\r\n",
dma_chan[*lch].tcc);
}
} else
dma_chan[*lch].tcc = -1;
map_dmach_queue(dev_id, eventq_no);
ret_val = 0;
}
} else if (dev_id == DAVINCI_DMA_CHANNEL_ANY) {
i = 0;
ret_val = 0;
while (dma_chan_no_event[i] != -1) {
if (!dma_chan[dma_chan_no_event[i]].in_use) {
*lch = dma_chan_no_event[i];
dma_chan[*lch].param_no =
request_param(*lch, dev_id);
if (dma_chan[*lch].param_no == -1) {
return -EINVAL;
}
dev_dbg(&edma_dev.dev, "param_no=%d\r\n",
dma_chan[*lch].param_no);
if (dma_chan[*lch].param_no >=
DAVINCI_EDMA_NUM_DMACH
&&
dma_chan[*lch].param_no <
(DAVINCI_EDMA_NUM_DMACH +
DAVINCI_EDMA_NUM_QDMACH)
) {
ptr_edmacc_regs->qrae[0] =
ptr_edmacc_regs->qrae[0] |
(1 << (dma_chan[*lch].param_no -
DAVINCI_EDMA_NUM_DMACH));
} else {
if (dma_chan[*lch].param_no < 32) {
ptr_edmacc_regs->dra[0].drae =
ptr_edmacc_regs->dra[0].drae
|
(1 << dma_chan[*lch].
param_no);
} else {
ptr_edmacc_regs->dra[0].draeh =
ptr_edmacc_regs->dra[0].
draeh | (1 <<
(dma_chan[*lch].
param_no - 32));
}
}
if (callback) {
dma_chan[*lch].tcc =
request_dma_interrupt(*lch,
callback,
data,
dma_chan
[*lch].
param_no,
*tcc);
if (dma_chan[*lch].tcc == -1) {
return -EINVAL;
} else {
*tcc = dma_chan[*lch].tcc;
}
} else {
dma_chan[*lch].tcc = -1;
}
map_dmach_queue(dev_id, eventq_no);
ret_val = 0;
break;
}
i++;
}
}
else if (dev_id == DAVINCI_EDMA_PARAM_ANY) {
ret_val = 0;
for (i = (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH);
i < DAVINCI_EDMA_NUM_PARAMENTRY; i++) {
if (!dma_chan[i].in_use) {
dev_dbg(&edma_dev.dev, "any link = %d\r\n", i);
*lch = i;
dma_chan[*lch].param_no =
request_param(*lch, dev_id);
if (dma_chan[*lch].param_no == -1) {
dev_dbg(&edma_dev.dev,
"request_param failed\r\n");
return -EINVAL;
} else {
dev_dbg(&edma_dev.dev, "param_no=%d\r\n",
dma_chan[*lch].param_no);
}
if (*tcc != -1)
dma_chan[*lch].tcc = *tcc;
else
dma_chan[*lch].tcc = -1;
ret_val = 0;
break;
}
}
} else {
ret_val = -EINVAL;
}
if (!ret_val) {
if (dev_id >= DAVINCI_EDMA_NUM_DMACH && dev_id <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
/* Master Channel */
qdam_to_param_mapping[dev_id -
DAVINCI_EDMA_NUM_DMACH] =
dma_chan[*lch].param_no;
LOCK;
/* It's used global data structure and used to find out
whether channel is available or not */
dma_chan[qdam_to_param_mapping
[dev_id - DAVINCI_EDMA_NUM_DMACH]].in_use = 1;
UNLOCK;
dma_chan[qdam_to_param_mapping
[dev_id - DAVINCI_EDMA_NUM_DMACH]].dev_id =
*lch;
dma_chan[qdam_to_param_mapping
[dev_id - DAVINCI_EDMA_NUM_DMACH]].tcc =
dma_chan[*lch].tcc;
temp_ch =
qdam_to_param_mapping[dev_id -
DAVINCI_EDMA_NUM_DMACH];
dma_chan[temp_ch].param_no = dma_chan[*lch].param_no;
if (dma_chan[*lch].tcc != -1) {
ptr_edmacc_regs->paramentry[dma_chan[temp_ch].
param_no].opt &=
(~TCC);
ptr_edmacc_regs->paramentry[dma_chan[temp_ch].
param_no].opt |=
((0x3f & dma_chan[*lch].tcc) << 12);
/* set TCINTEN bit in PARAM entry */
ptr_edmacc_regs->
paramentry[dma_chan[temp_ch].param_no].
opt |= TCINTEN;
} else {
ptr_edmacc_regs->paramentry[dma_chan[temp_ch].
param_no].opt &=
~TCINTEN;
}
/* assign the link field to no link. i.e 0xffff */
ptr_edmacc_regs->paramentry[dma_chan[temp_ch].
param_no].
link_bcntrld |= 0xffff;
} else {
/* Slave Channel */
LOCK;
/* Global structure to identify whether resoures is
available or not */
dma_chan[*lch].in_use = 1;
UNLOCK;
dma_chan[*lch].dev_id = *lch;
if (dma_chan[*lch].tcc != -1) {
ptr_edmacc_regs->paramentry[dma_chan[*lch].
param_no].opt &=
(~TCC);
ptr_edmacc_regs->paramentry[dma_chan[*lch].
param_no].opt |=
((0x3f & dma_chan[*lch].tcc) << 12);
/* set TCINTEN bit in PARAM entry */
ptr_edmacc_regs->paramentry[dma_chan[*lch].
param_no].opt |=
TCINTEN;
} else {
ptr_edmacc_regs->paramentry[dma_chan[*lch].
param_no].opt &=
~TCINTEN;
}
/* assign the link field to no link. i.e 0xffff */
ptr_edmacc_regs->paramentry[dma_chan[*lch].
param_no].
link_bcntrld |= 0xffff;
}
}
return ret_val;
}
/******************************************************************************
*
* DMA channel free: Free dma channle
* Arguments:
* dev_id - request for the param entry device id
*
* Return: zero on success, or corresponding error no on failure
*
*****************************************************************************/
void davinci_free_dma(int lch)
{
int temp_ch = 0;
if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];
lch = temp_ch;
}
LOCK;
dma_chan[lch].in_use = 0;
UNLOCK;
free_param(dma_chan[lch].param_no);
if (lch >= 0
&& lch < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
free_dma_interrupt(dma_chan[lch].tcc);
}
}
/******************************************************************************
*
* DMA source parameters setup
* ARGUMENTS:
* lch - channel for which the source parameters to be configured
* src_port - Source port address
* addressMode - indicates wether addressing mode is fifo.
*
*****************************************************************************/
void davinci_set_dma_src_params(int lch, unsigned long src_port,
enum address_mode mode, enum fifo_width width)
{
int temp_ch = 0;
if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];
lch = temp_ch;
}
if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {
/* set the source port address
in source register of param structure */
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src =
src_port;
/* set the fifo addressing mode */
if (mode) { /* reset SAM and FWID */
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt
&= (~(SAM | EDMA_FWID));
/* set SAM and program FWID */
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt
|= (mode | ((width & 0x7) << 8));
}
}
}
/******************************************************************************
*
* DMA destination parameters setup
* ARGUMENTS:
* lch - channel or param device for destination parameters to be configured
* dest_port - Destination port address
* addressMode - indicates wether addressing mode is fifo.
*
*****************************************************************************/
void davinci_set_dma_dest_params(int lch, unsigned long dest_port,
enum address_mode mode, enum fifo_width width)
{
int temp_ch = 0;
if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];
lch = temp_ch;
}
if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {
/* set the destination port address
in dest register of param structure */
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].dst =
dest_port;
/* set the fifo addressing mode */
if (mode) { /* reset DAM and FWID */
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt
&= (~(DAM | EDMA_FWID));
/* set DAM and program FWID */
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt
|= ((mode << 1) | ((width & 0x7) << 8));
}
}
}
/******************************************************************************
*
* DMA source index setup
* ARGUMENTS:
* lch - channel or param device for configuration of source index
* srcbidx - source B-register index
* srccidx - source C-register index
*
*****************************************************************************/
void davinci_set_dma_src_index(int lch, short src_bidx, short src_cidx)
{
int temp_ch = 0;
if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];
lch = temp_ch;
}
if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_bidx
&= 0xffff0000;
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_bidx
|= src_bidx;
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_cidx
&= 0xffff0000;
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_cidx
|= src_cidx;
}
}
/******************************************************************************
*
* DMA destination index setup
* ARGUMENTS:
* lch - channel or param device for configuration of destination index
* srcbidx - dest B-register index
* srccidx - dest C-register index
*
*****************************************************************************/
void davinci_set_dma_dest_index(int lch, short dest_bidx, short dest_cidx)
{
int temp_ch = 0;
if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];
lch = temp_ch;
}
if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_bidx
&= 0x0000ffff;
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_bidx
|= ((unsigned long)dest_bidx << 16);
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_cidx
&= 0x0000ffff;
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].src_dst_cidx
|= ((unsigned long)dest_cidx << 16);
}
}
/******************************************************************************
*
* DMA transfer parameters setup
* ARGUMENTS:
* lch - channel or param device for configuration of aCount, bCount and
* cCount regs.
* acnt - acnt register value to be configured
* bcnt - bcnt register value to be configured
* ccnt - ccnt register value to be configured
*
*****************************************************************************/
void davinci_set_dma_transfer_params(int lch, unsigned short acnt,
unsigned short bcnt, unsigned short ccnt,
unsigned short bcntrld,
enum sync_dimension sync_mode)
{
int temp_ch = 0;
if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];
lch = temp_ch;
}
if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].link_bcntrld
&= 0x0000ffff;
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].link_bcntrld
|= (bcntrld << 16);
if (sync_mode == ASYNC)
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt
&= (~SYNCDIM);
else
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].opt
|= SYNCDIM;
/* Set the acount, bcount, ccount registers */
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].a_b_cnt =
(bcnt << 16) | acnt;
ptr_edmacc_regs->paramentry[dma_chan[lch].param_no].ccnt = ccnt;
}
}
/******************************************************************************
*
* davinci_set_dma_params -
* ARGUMENTS:
* lch - logical channel number
*
*****************************************************************************/
void davinci_set_dma_params(int lch, edmacc_paramentry_regs * temp)
{
int temp_ch = 0;
if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];
lch = temp_ch;
}
if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {
memcpy((void *)
&(ptr_edmacc_regs->
paramentry[dma_chan[lch].param_no].opt),
(void *)temp, sizeof(edmacc_paramentry_regs));
}
}
/******************************************************************************
*
* davinci_get_dma_params -
* ARGUMENTS:
* lch - logical channel number
*
*****************************************************************************/
void davinci_get_dma_params(int lch, edmacc_paramentry_regs * temp)
{
int temp_ch = 0;
if (lch >= DAVINCI_EDMA_NUM_DMACH && lch <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch = qdam_to_param_mapping[lch - DAVINCI_EDMA_NUM_DMACH];
lch = temp_ch;
}
if (lch >= 0 && lch < DAVINCI_EDMA_NUM_PARAMENTRY) {
memcpy((void *)temp,
(void *)&(ptr_edmacc_regs->
paramentry[dma_chan[lch].param_no].opt),
sizeof(edmacc_paramentry_regs));
}
}
/******************************************************************************
*
* DMA Strat - Starts the dma on the channel passed
* ARGUMENTS:
* lch - logical channel number
*
*****************************************************************************/
int davinci_start_dma(int lch)
{
int ret_val;
if (lch >= 0 && (lch < DAVINCI_EDMA_NUM_DMACH)) {
int i = 0;
int flag = 0;
/* If the dma start request is for the unused events */
while (dma_chan_no_event[i] != -1) {
if (dma_chan_no_event[i] == lch) {
/* EDMA channels without event association */
dev_dbg(&edma_dev.dev, "ESR=%x\r\n",
ptr_edmacc_regs->shadow[0].esr);
(lch < 32) ?
(ptr_edmacc_regs->shadow[0].esr |=
(1UL << lch)) : (ptr_edmacc_regs->
shadow[0].esrh |=
(1UL << (lch - 32)));
flag = 1;
ret_val = 0;
break;
}
i++;
}
if (!flag) {
/* EDMA channel with event association */
dev_dbg(&edma_dev.dev, "ER=%d\r\n",
ptr_edmacc_regs->shadow[0].er);
/* Clear any pedning error */
(lch < 32) ?
(ptr_edmacc_regs->emcr |=
(1UL << lch)) :
(ptr_edmacc_regs->emcrh |= (1UL << (lch - 32)));
/* Clear any SER */
(lch < 32) ?
(ptr_edmacc_regs->shadow[0].secr |=
(1UL << lch)) :
(ptr_edmacc_regs->shadow[0].secrh |=
(1UL << (lch - 32)));
(lch < 32) ?
(ptr_edmacc_regs->shadow[0].eesr |=
(1UL << lch)) :
(ptr_edmacc_regs->shadow[0].eesrh |=
(1UL << (lch - 32)));
dev_dbg(&edma_dev.dev, "EER=%d\r\n",
ptr_edmacc_regs->shadow[0].eer);
ret_val = 0;
}
} else if ((lch >= DAVINCI_EDMA_NUM_DMACH)
&& (lch <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH))) {
ptr_edmacc_regs->shadow[0].qeesr |=
(1 << (lch - DAVINCI_EDMA_NUM_DMACH));
ret_val = 0;
} else { /* for slaveChannels */
ret_val = EINVAL;
}
return ret_val;
}
/******************************************************************************
*
* DMA Stop - Stops the dma on the channel passed
* ARGUMENTS:
* lch - logical channel number
*
*****************************************************************************/
void davinci_stop_dma(int lch)
{
if (lch < DAVINCI_EDMA_NUM_DMACH) {
int flag = 0;
int i = 0;
/* If the dma stop request is for the unused events */
while (dma_chan_no_event[i] != -1) {
if (dma_chan_no_event[i] == lch) {
/* EDMA channels without event association */
/* if the requested channel is one of the
unused channels then reset the coresponding
bit of ESR-Event Set Register */
flag = 1;
break;
}
i++;
}
if (!flag) {
/* EDMA channel with event association */
(lch < 32) ? (ptr_edmacc_regs->shadow[0].eecr |=
(1UL << lch)) :
(ptr_edmacc_regs->shadow[0].eecrh |=
(1UL << (lch - 32)));
if (lch < 32) {
if (ptr_edmacc_regs->shadow[0].er & (1 << lch)) {
dev_dbg(&edma_dev.dev, "ER=%x\n",
ptr_edmacc_regs->shadow[0].er);
ptr_edmacc_regs->shadow[0].ecr |=
(1 << lch);
}
} else {
if (ptr_edmacc_regs->shadow[0].erh
& (1 << (lch - 32))) {
dev_dbg(&edma_dev.dev, "ERH=%x\n",
ptr_edmacc_regs->shadow[0].erh);
ptr_edmacc_regs->shadow[0].ecrh |=
(1 << (lch - 32));
}
}
if (lch < 32) {
if (ptr_edmacc_regs->shadow[0].ser & (1 << lch)) {
dev_dbg(&edma_dev.dev, "SER=%x\n",
ptr_edmacc_regs->shadow[0].ser);
ptr_edmacc_regs->shadow[0].secr |=
(1 << lch);
} else {
}
} else {
if (ptr_edmacc_regs->
shadow[0].serh & (1 << (lch - 32))) {
dev_dbg(&edma_dev.dev, "SERH=%x\n",
ptr_edmacc_regs->shadow[0].
serh);
ptr_edmacc_regs->shadow[0].secrh |=
(1 << (lch - 32));
}
}
if (lch < 32) {
if (ptr_edmacc_regs->emr & (1 << lch)) {
dev_dbg(&edma_dev.dev, "EMR=%x\n",
ptr_edmacc_regs->emr);
ptr_edmacc_regs->emcr |= (1 << lch);
}
} else {
if (ptr_edmacc_regs->emrh & (1 << (lch - 32))) {
dev_dbg(&edma_dev.dev, "EMRH=%x\n",
ptr_edmacc_regs->emrh);
ptr_edmacc_regs->emcrh |=
(1 << (lch - 32));
}
}
dev_dbg(&edma_dev.dev, "EER=%d\r\n",
ptr_edmacc_regs->shadow[0].eer);
/* if the requested channel is one of the event channels
then just set the link field of the corresponding
param entry to 0xffff */
}
} else if ((lch >= DAVINCI_EDMA_NUM_DMACH)
&&
(lch < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH))) {
/* for QDMA channels */
ptr_edmacc_regs->qeecr |= (1 << (lch - DAVINCI_EDMA_NUM_DMACH));
dev_dbg(&edma_dev.dev, "QER=%d\r\n", ptr_edmacc_regs->qer);
dev_dbg(&edma_dev.dev, "QEER=%d\r\n", ptr_edmacc_regs->qeer);
} else if ((lch >= (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH))
&& lch < DAVINCI_EDMA_NUM_PARAMENTRY) {
/* for slaveChannels */
ptr_edmacc_regs->paramentry[lch].link_bcntrld &= 0xffff0000;
ptr_edmacc_regs->paramentry[lch].link_bcntrld |= 0xffff;
} else {
}
}
/******************************************************************************
*
* DMA channel link - link the two logical channels passed through by linking
* the link field of head to the param pointed by the lch_queue.
* ARGUMENTS:
* lch_head - logical channel number, in which the link field is linked
* to the param pointed to by lch_queue
* lch_queue - logical channel number or the param entry number, which is to be
* linked to the lch_head
*
*****************************************************************************/
void davinci_dma_link_lch(int lch_head, int lch_queue)
{
unsigned long link;
int temp_ch = 0;
if (lch_head >=
DAVINCI_EDMA_NUM_DMACH
&& lch_head < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch =
qdam_to_param_mapping[lch_head - DAVINCI_EDMA_NUM_DMACH];
lch_head = temp_ch;
}
if (lch_queue >=
DAVINCI_EDMA_NUM_DMACH
&& lch_queue < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch =
qdam_to_param_mapping[lch_queue - DAVINCI_EDMA_NUM_DMACH];
lch_queue = temp_ch;
}
if ((lch_head >= 0 && lch_head < DAVINCI_EDMA_NUM_PARAMENTRY)
&& (lch_queue >= 0 && lch_queue < DAVINCI_EDMA_NUM_PARAMENTRY)) {
/* program LINK */
link =
(unsigned
long)(&
(ptr_edmacc_regs->
paramentry[dma_chan[lch_queue].param_no].opt));
ptr_edmacc_regs->
paramentry[dma_chan
[lch_head].param_no].link_bcntrld &= 0xffff0000;
ptr_edmacc_regs->
paramentry[dma_chan
[lch_head].
param_no].link_bcntrld |= ((unsigned short)
link);
dma_chan[lch_head].link_lch = lch_queue;
}
}
/******************************************************************************
*
* DMA channel unlink - unlink the two logical channels passed through by
* setting the link field of head to 0xffff.
* ARGUMENTS:
* lch_head - logical channel number, from which the link field is to be removed
* lch_queue - logical channel number or the param entry number, which is to be
* unlinked from lch_head
*
*****************************************************************************/
void davinci_dma_unlink_lch(int lch_head, int lch_queue)
{
int temp_ch = 0;
if (lch_head >=
DAVINCI_EDMA_NUM_DMACH
&& lch_head < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch =
qdam_to_param_mapping[lch_head - DAVINCI_EDMA_NUM_DMACH];
lch_head = temp_ch;
}
if (lch_queue >=
DAVINCI_EDMA_NUM_DMACH
&& lch_queue < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch =
qdam_to_param_mapping[lch_queue - DAVINCI_EDMA_NUM_DMACH];
lch_queue = temp_ch;
}
if ((lch_head >= 0 && lch_head < DAVINCI_EDMA_NUM_PARAMENTRY)
&& (lch_queue >= 0 && lch_queue < DAVINCI_EDMA_NUM_PARAMENTRY)) {
ptr_edmacc_regs->
paramentry[dma_chan
[lch_head].param_no].link_bcntrld |= 0xffff;
dma_chan[lch_head].link_lch = -1;
}
}
/******************************************************************************
*
* DMA channel chain - chains the two logical channels passed through by
* ARGUMENTS:
* lch_head - logical channel number, from which the link field is to be removed
* lch_queue - logical channel number or the param entry number, which is to be
* unlinked from lch_head
*
*****************************************************************************/
void davinci_dma_chain_lch(int lch_head, int lch_queue)
{
int temp_ch = 0;
if (lch_head >=
DAVINCI_EDMA_NUM_DMACH
&& lch_head < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch =
qdam_to_param_mapping[lch_head - DAVINCI_EDMA_NUM_DMACH];
lch_head = temp_ch;
}
if (lch_queue >=
DAVINCI_EDMA_NUM_DMACH
&& lch_queue < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch =
qdam_to_param_mapping[lch_queue - DAVINCI_EDMA_NUM_DMACH];
lch_queue = temp_ch;
}
if ((lch_head >= 0
&& lch_head < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH))
&&
(lch_queue >= 0
&& lch_queue < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH))
) { /* set TCCHEN */
/* set TCCHEN */
ptr_edmacc_regs->paramentry[lch_head].opt |= TCCHEN;
/* program tcc */
ptr_edmacc_regs->paramentry[lch_head].opt &= (~TCC);
ptr_edmacc_regs->
paramentry[lch_head].opt |= (lch_queue & 0x3f) << 12;
}
}
/******************************************************************************
*
* DMA channel unchain - unchain the two logical channels passed through by
* ARGUMENTS:
* lch_head - logical channel number, from which the link field is to be removed
* lch_queue - logical channel number or the param entry number, which is to be
* unlinked from lch_head
*
*****************************************************************************/
void davinci_dma_unchain_lch(int lch_head, int lch_queue)
{
int temp_ch = 0;
if (lch_head >=
DAVINCI_EDMA_NUM_DMACH
&& lch_head < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch =
qdam_to_param_mapping[lch_head - DAVINCI_EDMA_NUM_DMACH];
lch_head = temp_ch;
}
if (lch_queue >=
DAVINCI_EDMA_NUM_DMACH
&& lch_queue < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH)) {
temp_ch =
qdam_to_param_mapping[lch_queue - DAVINCI_EDMA_NUM_DMACH];
lch_queue = temp_ch;
}
if ((lch_head >= 0
&& lch_head < (DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH))
&& (lch_queue >= 0
&& lch_queue <
(DAVINCI_EDMA_NUM_DMACH + DAVINCI_EDMA_NUM_QDMACH))) {
/* reset TCCHEN */
ptr_edmacc_regs->paramentry[lch_head].opt &= ~TCCHEN;
}
}
/******************************************************************************
*
* It cleans ParamEntry qand bring back EDMA to initial state if media has
* been removed before EDMA has finished.It is usedful for removable media.
* Arguments:
* ch_no - channel no
*
* Return: zero on success, or corresponding error no on failure
*
*****************************************************************************/
void davinci_clean_channel(int ch_no)
{
int i;
dev_dbg(&edma_dev.dev, "EMR =%d\r\n", ptr_edmacc_regs->emr);
if (ch_no < 32) {
for (i = 0; i < 32; i++) {
if (ch_no == i) {
ptr_edmacc_regs->shadow[0].ecr |= (1 << i);
/* Clear the corresponding EMR bits */
ptr_edmacc_regs->emcr |= (1 << i);
/* Clear any SER */
ptr_edmacc_regs->shadow[0].secr |= (1 << i);
ptr_edmacc_regs->ccerrclr |= ((1 << 16) | 0x3);
}
}
}
if (ch_no > 32) {
dev_dbg(&edma_dev.dev, "EMRH =%d\r\n", ptr_edmacc_regs->emrh);
for (i = 0; i < 32; i++) {
if (ch_no == (i + 32)) {
ptr_edmacc_regs->shadow[0].ecrh |= (1 << i);
/* Clear the corresponding IPR bits */
ptr_edmacc_regs->emcrh |= (1 << i);
/* Clear any SER */
ptr_edmacc_regs->shadow[0].secrh |= (1 << i);
ptr_edmacc_regs->ccerrclr |= ((1 << 16) | 0x3);
}
}
}
}
/******************************************************************************
*
* DMA interrupt handlers
*
*****************************************************************************/
static int dma_irq_handler_l(int sound_curr_lch, void
*ch_status, struct
pt_regs
*data)
{
dev_dbg(&edma_dev.dev, "dma_irq_handler\n");
(*cb[0]) ();
return IRQ_HANDLED;
}
static int
dma_ccerr_handler_l
(int sound_curr_lch, void *ch_status, struct pt_regs *data) {
dev_dbg(&edma_dev.dev, "dma_ccerr_handler\n");
(*cb[1]) ();
return IRQ_HANDLED;
}
static int
dma_tc1err_handler_l
(int sound_curr_lch, void *ch_status, struct pt_regs *data) {
dev_dbg(&edma_dev.dev, "dma_tc1err_handler\n");
(*cb[2]) ();
return IRQ_HANDLED;
}
static int
dma_tc2err_handler_l
(int sound_curr_lch, void *ch_status, struct pt_regs *data) {
dev_dbg(&edma_dev.dev, "dma_tc2err_handler\n");
(*cb[3]) ();
return IRQ_HANDLED;
}
int register_dma_interrupts
(intr_callback cb1,
intr_callback cb2, intr_callback cb3, intr_callback cb4) {
cb[0] = cb1;
cb[1] = cb2;
cb[2] = cb3;
cb[3] = cb4;
if (!cb1 || !cb2 || !cb3 || !cb4) {
dev_dbg(&edma_dev.dev, "NULL callback\n");
return -1;
}
if (request_irq(IRQ_CCINT0, dma_irq_handler_l, 0, "EDMA", NULL)) {
dev_dbg(&edma_dev.dev, "request_irq failed\n");
return -1;
}
if (request_irq
(IRQ_CCERRINT, dma_ccerr_handler_l, 0, "EDMA CC Err", NULL)) {
dev_dbg(&edma_dev.dev, "request_irq failed\n");
return -1;
}
if (request_irq
(IRQ_TCERRINT0, dma_tc1err_handler_l, 0, "EDMA TC1 Err", NULL)) {
dev_dbg(&edma_dev.dev, "request_irq failed\n");
return -1;
}
if (request_irq
(IRQ_TCERRINT, dma_tc2err_handler_l, 0, "EDMA TC2 Err", NULL)) {
dev_dbg(&edma_dev.dev, "request_irq failed\n");
return -1;
}
return 0;
}
arch_initcall(arch_dma_init);
EXPORT_SYMBOL(davinci_start_dma);
EXPORT_SYMBOL(davinci_dma_link_lch);
EXPORT_SYMBOL(davinci_set_dma_params);
EXPORT_SYMBOL(davinci_get_dma_params);
EXPORT_SYMBOL(davinci_set_dma_transfer_params);
EXPORT_SYMBOL(davinci_set_dma_dest_index);
EXPORT_SYMBOL(davinci_set_dma_src_index);
EXPORT_SYMBOL(davinci_set_dma_dest_params);
EXPORT_SYMBOL(davinci_set_dma_src_params);
EXPORT_SYMBOL(davinci_request_dma);
EXPORT_SYMBOL(davinci_stop_dma);
EXPORT_SYMBOL(davinci_clean_channel);
EXPORT_SYMBOL(davinci_free_dma);
EXPORT_SYMBOL(davinci_dma_chain_lch);
EXPORT_SYMBOL(davinci_dma_unchain_lch);
EXPORT_SYMBOL(davinci_dma_unlink_lch);
/*
* linux/drivers/davinci/i2c-davinci-client.c
*
* Copyright (C) 2006 Texas Instruments Inc
*
* 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 <linux/config.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/clk.h>
#include <asm/semaphore.h>
#include <asm/arch/i2c-client.h>
static unsigned long initialized;
static struct semaphore expander_sema;
static struct i2c_client *client_handle;
/* This function is used for internal initialization */
int davinci_i2c_read(u8 size, u8 * val, u16 client_addr)
{
int err;
struct i2c_client *client = client_handle;
struct i2c_msg msg[1];
if (!client->adapter)
return -ENODEV;
msg->addr = client_addr;
msg->flags = I2C_M_RD;
msg->len = size;
msg->buf = val;
err = i2c_transfer(client->adapter, msg, 1);
if (err >= 0) {
return 0;
}
return err;
}
EXPORT_SYMBOL(davinci_i2c_read);
/* This function is used for internal initialization */
int davinci_i2c_write(u8 size, u8 * val, u16 client_addr)
{
int err;
struct i2c_client *client = client_handle;
struct i2c_msg msg[1];
if (!client->adapter)
return -ENODEV;
msg->addr = client_addr;
msg->flags = 0;
msg->len = size;
msg->buf = val;
err = i2c_transfer(client->adapter, msg, 1);
if (err >= 0)
return 0;
return err;
}
EXPORT_SYMBOL(davinci_i2c_write);
int davinci_i2c_expander_op(u16 client_addr, u35_expander_ops pin, u8 val)
{
int err = 0;
char cmd[4] = { 4, 6, 0x00, 0x09 };
u8 data_to_u35 = 0;
if (val > 1)
return -1;
down(&expander_sema);
err = davinci_i2c_read(1, &data_to_u35, 0x3A);
if (client_addr == 0x3A) {
switch (pin) {
case USB_DRVVBUS:
if (val)
data_to_u35 |= val;
else {
data_to_u35 &= (val | 0xFE);
}
break;
case VDDIMX_EN:
if (val)
data_to_u35 |= (val << 1);
else {
data_to_u35 &= (val | 0xFD);
}
break;
case VLYNQ_ON:
if (val)
data_to_u35 |= (val << 2);
else {
data_to_u35 &= (val | 0xFB);
}
break;
case CF_RESET:
if (val)
data_to_u35 |= (val << 3);
else {
data_to_u35 &= (val | 0xF7);
}
break;
case WLAN_RESET:
if (val)
data_to_u35 |= (val << 5);
else {
data_to_u35 &= (val | 0xDF);
}
break;
case ATA_SEL:
if (val)
data_to_u35 |= (val << 6);
else {
data_to_u35 &= (val | 0xBF);
}
break;
case CF_SEL:
davinci_i2c_write(4, cmd, 0x23);
if (val)
data_to_u35 |= (val << 7);
else {
data_to_u35 &= (val | 0x7F);
}
break;
default:
break;
}
} else {
printk("Only IO Expander at address 0x3A is suuported\n");
up(&expander_sema);
return -1;
}
err = davinci_i2c_write(1, &data_to_u35, 0x3A);
up(&expander_sema);
return err;
}
EXPORT_SYMBOL(davinci_i2c_expander_op);
static struct i2c_driver davinci_i2c_client_driver;
static int davinci_i2c_attach_client(struct i2c_adapter *adap, int addr)
{
struct i2c_client *client;
int err;
u8 data_to_u35 = 0xf6;
if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client_handle = client;
if (client->adapter)
return -EBUSY; /* our client is already attached */
client->addr = addr;
client->flags = 0;
client->driver = &davinci_i2c_client_driver;
client->adapter = adap;
strlcpy(client->name, "i2c_davinci_client", I2C_NAME_SIZE);
err = i2c_attach_client(client);
if (err) {
client->adapter = NULL;
goto exit_kfree;
}
err = davinci_i2c_write(1, &data_to_u35, 0x3A);
return 0;
exit_kfree:
kfree(client);
exit:
return err;
}
static int davinci_i2c_detach_client(struct i2c_client *client)
{
int err;
if (!client->adapter)
return -ENODEV; /* our client isn't attached */
err = i2c_detach_client(client);
client->adapter = NULL;
return err;
}
static int davinci_i2c_probe_adapter(struct i2c_adapter *adap)
{
return davinci_i2c_attach_client(adap, 0x3A);
}
/* This is the driver that will be inserted */
static struct i2c_driver davinci_i2c_client_driver = {
.driver = {
.name = "davinci_i2c_client",
},
.attach_adapter = davinci_i2c_probe_adapter,
.detach_client = davinci_i2c_detach_client,
};
static int __init davinci_i2c_client_init(void)
{
return i2c_add_driver(&davinci_i2c_client_driver);
}
static void __exit davinci_i2c_client_exit(void)
{
i2c_del_driver(&davinci_i2c_client_driver);
}
module_init(davinci_i2c_client_init);
module_exit(davinci_i2c_client_exit);
/*
* <arch/arm/mach-davinci/i2c-emac.c
*
* Read MAC address from i2c-attached EEPROM
* FIXME: Move into network driver once stabilized
*
* Author: Texas Instruments
*
* 2006 (c) Texas Instruments, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <asm/arch/i2c-client.h>
/* Get Ethernet address from kernel boot params */
static unsigned char cpmac_eth_string[20] = "deadbeaf";
/* This function gets the Ethernet MAC address from EEPROM
* Input buffer to be of atlease 20 bytes in length
*/
int davinci_get_macaddr (char *ptr)
{
#ifndef CONFIG_I2C_DAVINCI
printk(KERN_INFO "DaVinci EMAC: Unable to read MAC from EEPROM, "
"no i2c support in kernel.\n");
#else
char data[2] = { 0x7f, 0 };
char temp[20];
int i = 0;
if (ptr == NULL) {
return -EFAULT;
}
davinci_i2c_write (2, data, 0x50);
davinci_i2c_read (8, temp, 0x50);
/* check whether MAC address is available in ERPROM else try to
* to get it from bootparams for now. From Delta EVM MAC address
* should be available from I2C EEPROM.
*/
if ((temp [0] != 0xFF) |
(temp [1] != 0xFF) |
(temp [2] != 0xFF) |
(temp [3] != 0xFF) |
(temp [4] != 0xFF) |
(temp [5] != 0xFF) |
(temp [6] != 0xFF) )
{
ptr[0] = (*(temp+0) & 0xF0) >> 4;
ptr[1] = (*(temp+0) & 0x0F);
ptr[2] = ':';
ptr[3] = (*(temp+1) & 0xF0) >> 4;
ptr[4] = (*(temp+1) & 0x0F);
ptr[5] = ':';
ptr[6] = (*(temp+2) & 0xF0) >> 4;
ptr[7] = (*(temp+2) & 0x0F);
ptr[8] = ':';
ptr[9] = (*(temp+3) & 0xF0) >> 4;
ptr[10]= (*(temp+3) & 0x0F);
ptr[11]= ':';
ptr[12]= (*(temp+4) & 0xF0) >> 4;
ptr[13]= (*(temp+4) & 0x0F);
ptr[14]= ':';
ptr[15]= (*(temp+5) & 0xF0) >> 4;
ptr[16]= (*(temp+5) & 0x0F);
for (i = 0; i < 17; i++)
{
if (ptr[i] == ':')
continue;
else if (ptr[i] <= 9)
ptr[i] = ptr[i] + 48;
else
ptr[i] = ptr[i] + 87;
}
} else
#endif
{
strcpy (ptr, cpmac_eth_string);
}
return 0;
}
EXPORT_SYMBOL(davinci_get_macaddr);
static int davinci_cpmac_eth_setup(char *str)
{
/* The first char passed from the bootloader is '=', so ignore it */
strcpy(&cpmac_eth_string[0], &str[1]);
printk("TI DaVinci EMAC: Kernel Boot params Eth address: %s\n",
cpmac_eth_string);
return (1);
}
__setup("eth", davinci_cpmac_eth_setup);
/*
* linux/arch/arm/mach-davinci/irq.c
*
* TI DaVinci INTC config file
*
* Copyright (C) 2006 Texas Instruments.
*
* ----------------------------------------------------------------------------
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* ----------------------------------------------------------------------------
*
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/mach/irq.h>
#include <asm/arch/irq.h>
#include <asm/arch/irqs.h>
#include <asm/arch/memory.h>
#include <asm/arch/hardware.h>
void intcInit(void);
#define INTNUM DAVINCI_MAXIRQNUM
#define EXCNUM ( 8 - 1 )
#define INTC_NUM_INTS_ONE_REGISTER 32
#define INTC_CLEAR_INTERRUPTS 0xFFFFFFFF
#define INTC_IDT_BASE DAVINCI_IRAM_VIRT
#define INTC_DISABLE_WHEN_CLEARED_MODE 0x4
#define INTC_IRQ_ENTRY_RAW 0x2
#define INTC_FIQ_ENTRY_RAW 0x1
#define INTC_VECT_OFFSET 0x100
volatile intc_registers *pintc = (intc_registers *) IO_ADDRESS(DAVINCI_ARM_INTC_BASE);
void davinci_intcinit(void);
/* Disable interrupt */
static void davinci_xdisable_int(unsigned int intno)
{
unsigned int mask;
if (intno < INTC_NUM_INTS_ONE_REGISTER) {
mask = 1 << intno;
pintc->eint0 &= ~mask;
} else if (intno <= INTNUM) {
mask = 1 << (intno - INTC_NUM_INTS_ONE_REGISTER);
pintc->eint1 &= ~mask;
}
}
/* Enable interrupt */
static void davinci_xenable_int(unsigned int intno)
{
unsigned int mask;
if (intno < INTC_NUM_INTS_ONE_REGISTER) {
mask = 1 << intno;
pintc->eint0 |= mask;
} else if (intno <= INTNUM) {
mask = 1 << (intno - INTC_NUM_INTS_ONE_REGISTER);
pintc->eint1 |= mask;
}
}
/* EOI interrupt */
void davinci_xeoi_pic(unsigned int intno)
{
unsigned int mask;
if (intno < INTC_NUM_INTS_ONE_REGISTER) {
mask = 1 << intno;
pintc->irq0 = mask;
} else if (intno < INTNUM) {
mask = 1 << (intno - INTC_NUM_INTS_ONE_REGISTER);
pintc->irq1 = mask;
}
}
static struct irqchip irqchip_0 = {
.ack = davinci_xeoi_pic,
.mask = davinci_xdisable_int,
.unmask = davinci_xenable_int,
};
void davinci_irq_init(void)
{
int i;
unsigned int *ptr = (unsigned int *)INTC_IDT_BASE;
davinci_intcinit();
ptr += INTC_VECT_OFFSET / (sizeof(*ptr));
for (i = 0; i < INTNUM; i++) {
if (i == 0) {
*ptr = 0xFFFFFFFF;
} else {
*ptr = i - 1;
}
ptr++;
}
/* Proggam the irqchip structures for ARM INTC */
for (i = 0; i < NR_IRQS; i++) {
if (i != IRQ_TINT1_TINT34)
set_irq_handler(i, do_edge_IRQ);
else
set_irq_handler(i, do_level_IRQ);
set_irq_chip(i, &irqchip_0);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
}
/* Interrupt Controller Initialize */
void davinci_intcinit(void)
{
/* Clear all interrupt requests - write 1 to clear the interrupt */
pintc->fiq0 = pintc->irq0 = INTC_CLEAR_INTERRUPTS;
pintc->fiq1 = pintc->irq1 = INTC_CLEAR_INTERRUPTS;
/* Disable all interrupts */
pintc->eint0 = pintc->eint1 = 0;
/* Interrupts disabled immediately. IRQ entry reflects all interrupts */
pintc->inctl = 0;
/* Set vector table base address
* last two bits are zero which means 4 byte entry */
pintc->eabase = (unsigned int)INTC_VECT_OFFSET;
/* Clear all interrupt requests - write 1 to clear the interrupt */
pintc->fiq0 = pintc->irq0 = INTC_CLEAR_INTERRUPTS;
pintc->fiq1 = pintc->irq1 = INTC_CLEAR_INTERRUPTS;
return;
}
/*
* <arch/arm/mach-davinci/leds-evm.c>
*
* LED support for TI DaVinci EVM
*
* 2006 (c) Texas Instruments, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/errno.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/leds.h>
#include <asm/system.h>
/* eight leds on a pcf8574a I2C gpio expander; 0 == ON, 1 == OFF
* - drivers can use leds_event(led_{green,amber,red,blue}_{on,off})
* - userspace can do the same with /sys/devices/leds/leds0/event
*/
#define LED_DS8 (1 << 0)
#define LED_DS7 (1 << 1)
#define LED_DS6 (1 << 2)
#define LED_DS5 (1 << 3)
#define LED_DS4 (1 << 4)
#define LED_DS3 (1 << 5)
#define LED_DS2 (1 << 6)
#define LED_DS1 (1 << 7)
#define LED_STATE_ENABLED (1 << 8)
#define LED_STATE_CLAIMED (1 << 9)
static u16 hw_led_state;
static u8 leds_change;
/* these leds use I2C not GPIO, so we can't change values
* and remain "idle" ... so there's no "idle" LED.
*/
#define TIMER_LED LED_DS8
#define GREEN_LED LED_DS1
#define AMBER_LED LED_DS2
#define RED_LED LED_DS3
#define BLUE_LED LED_DS4
#define APP_LEDS (GREEN_LED | AMBER_LED | RED_LED | BLUE_LED)
static DEFINE_SPINLOCK(lock);
#define EVM_I2C_ADDR 0x38
#ifdef CONFIG_PREEMPT_RT
static void pcf_work(unsigned long unused)
#else
static void pcf_work(void *unused)
#endif
{
struct i2c_adapter *adap;
int err;
struct i2c_msg msg;
adap = i2c_get_adapter(0);
if (!adap)
return;
for (;;) {
static u8 leds;
spin_lock_irq(&lock);
leds = (u8) hw_led_state;
err= leds_change;
leds_change = 0;
spin_unlock_irq(&lock);
if (!err)
break;
msg.addr = EVM_I2C_ADDR;
msg.flags = 0;
msg.len = 1;
msg.buf = &leds;
err = i2c_transfer(adap, &msg, 1);
if (err < 0)
pr_debug("LED: set to %02x, err %d\n", leds, err);
}
}
/* Under PREEMPT_RT, this code may be called from the timer interrupt
* with is a real hard IRQ. Therefore, workqueues cannot be used
* because 'schedule_work()' can sleep. OTOH, for non-RT, tasklets
* cannot be used to call sleeping functions (such as i2c stack) */
#ifdef CONFIG_PREEMPT_RT
static DECLARE_TASKLET(work, pcf_work, 0);
#define doit() tasklet_schedule(&work)
#else
static DECLARE_WORK(work, pcf_work, NULL);
#define doit() schedule_work(&work)
#endif
static void evm_leds_event(led_event_t evt)
{
unsigned long flags;
u16 leds;
spin_lock_irqsave(&lock, flags);
if (!(hw_led_state & LED_STATE_ENABLED) && evt != led_start)
goto done;
leds = hw_led_state;
switch (evt) {
case led_start:
hw_led_state = LED_STATE_ENABLED | 0xff;
leds = 0;
break;
case led_halted:
case led_stop:
hw_led_state = 0xff;
// NOTE: work may still be pending!!
break;
case led_claim:
hw_led_state |= LED_STATE_CLAIMED;
hw_led_state |= APP_LEDS;
break;
case led_release:
hw_led_state &= ~LED_STATE_CLAIMED;
hw_led_state |= APP_LEDS;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
hw_led_state ^= TIMER_LED;
break;
#endif
/* actually all the LEDs are green */
case led_green_on:
if (leds & LED_STATE_CLAIMED)
hw_led_state &= ~GREEN_LED;
break;
case led_green_off:
if (leds & LED_STATE_CLAIMED)
hw_led_state |= GREEN_LED;
break;
case led_amber_on:
if (leds & LED_STATE_CLAIMED)
hw_led_state &= ~AMBER_LED;
break;
case led_amber_off:
if (leds & LED_STATE_CLAIMED)
hw_led_state |= AMBER_LED;
break;
case led_red_on:
if (leds & LED_STATE_CLAIMED)
hw_led_state &= ~RED_LED;
break;
case led_red_off:
if (leds & LED_STATE_CLAIMED)
hw_led_state |= RED_LED;
break;
case led_blue_on:
if (leds & LED_STATE_CLAIMED)
hw_led_state &= ~BLUE_LED;
break;
case led_blue_off:
if (leds & LED_STATE_CLAIMED)
hw_led_state |= BLUE_LED;
break;
default:
break;
}
leds ^= hw_led_state;
if (leds & 0xff) {
leds_change = (u8) leds;
doit();
}
done:
spin_unlock_irqrestore(&lock, flags);
}
static int __init evm_leds_init(void)
{
if (!machine_is_davinci_evm())
return 0;
leds_event = evm_leds_event;
leds_event(led_start);
return 0;
}
/* i2c is subsys_initcall, davinci i2c is device_initcall;
* this needs to follow both of them (sigh)
*/
late_initcall(evm_leds_init);
/*
* arch/arm/mach-davinci/mcbsp.c
*
* Copyright (C) 2004 Nokia Corporation
* Author: Samuel Ortiz <samuel.ortiz@nokia.com>
*
* 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.
*
* Multichannel mode not supported.
*
* 2005-10-01 Rishi Bhattacharya / Sharath Kumar - Modified to support TI
* Davinci DM644x processor
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <asm/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch/memory.h>
#include <asm/arch/edma.h>
#include <asm/arch/irqs.h>
#include <asm/arch/mcbsp.h>
struct clk *mbspclk = NULL;
/* #define CONFIG_MCBSP_DEBUG */
#ifdef CONFIG_MCBSP_DEBUG
#define DBG(x...) printk(KERN_INFO x)
#else
#define DBG(x...) do { } while (0)
#endif
struct davinci_mcbsp {
u32 io_base;
u8 id;
u8 free;
davinci_mcbsp_word_length rx_word_length;
davinci_mcbsp_word_length tx_word_length;
/* IRQ based TX/RX */
int rx_irq;
int tx_irq;
/* DMA stuff */
u8 dma_rx_sync;
short dma_rx_lch;
u8 dma_tx_sync;
short dma_tx_lch;
/* Completion queues */
struct completion tx_irq_completion;
struct completion rx_irq_completion;
struct completion tx_dma_completion;
struct completion rx_dma_completion;
spinlock_t lock;
};
static struct davinci_mcbsp mcbsp[DAVINCI_MAX_MCBSP_COUNT];
unsigned short DAVINCI_MCBSP_READ(int base, int reg)
{
unsigned long data, temp, *p = (unsigned long *)(base + reg);
temp = (unsigned long)p;
if (temp & 0x2) {
/*non word offset */
temp &= 0xfffffffc;
p = (unsigned long *)temp;
data = inl(p);
return (unsigned short)(data >> 16);
} else {
/*word offset */
return ((unsigned short)inl(p));
}
}
void DAVINCI_MCBSP_WRITE(int base, int reg, unsigned short val)
{
unsigned long data, temp, *p = (unsigned long *)(base + reg);
temp = (unsigned long)p;
if (temp & 0x2) {
/*non word offset */
temp &= 0xfffffffc;
p = (unsigned long *)temp;
data = inl(p);
data &= 0x0000ffff;
data |= ((unsigned long)val << 16);
outl(data, p);
} else {
/*word offset */
data = inl(p);
data &= 0xffff0000;
data |= val;
outl(data, p);
}
}
#if 0
static void davinci_mcbsp_dump_reg(u8 id)
{
DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
DBG("SPCR2: 0x%04x\n", DAVINCI_MCBSP_READ(mcbsp[id].io_base, SPCR2));
DBG("SPCR1: 0x%04x\n", DAVINCI_MCBSP_READ(mcbsp[id].io_base, SPCR1));
DBG("RCR2: 0x%04x\n", DAVINCI_MCBSP_READ(mcbsp[id].io_base, RCR2));
DBG("RCR1: 0x%04x\n", DAVINCI_MCBSP_READ(mcbsp[id].io_base, RCR1));
DBG("XCR2: 0x%04x\n", DAVINCI_MCBSP_READ(mcbsp[id].io_base, XCR2));
DBG("XCR1: 0x%04x\n", DAVINCI_MCBSP_READ(mcbsp[id].io_base, XCR1));
DBG("SRGR2: 0x%04x\n", DAVINCI_MCBSP_READ(mcbsp[id].io_base, SRGR2));
DBG("SRGR1: 0x%04x\n", DAVINCI_MCBSP_READ(mcbsp[id].io_base, SRGR1));
DBG("PCR0: 0x%04x\n", DAVINCI_MCBSP_READ(mcbsp[id].io_base, PCR0));
DBG("***********************\n");
}
#endif
static void davinci_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
{
struct davinci_mcbsp *mcbsp_dma_tx = (struct davinci_mcbsp *)(data);
DBG("TX DMA callback : 0x%x\n",
DAVINCI_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
/* We can free the channels */
DBG("mcbsp_dma_tx->dma_tx_lch = %d\n",
mcbsp_dma_tx->dma_tx_lch);
davinci_stop_dma(mcbsp_dma_tx->dma_tx_lch);
davinci_free_dma(mcbsp_dma_tx->dma_tx_lch);
mcbsp_dma_tx->dma_tx_lch = -1;
complete(&mcbsp_dma_tx->tx_dma_completion);
}
static void davinci_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
{
struct davinci_mcbsp *mcbsp_dma_rx = (struct davinci_mcbsp *)(data);
DBG("RX DMA callback : 0x%x\n",
DAVINCI_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
/* We can free the channels */
davinci_free_dma(mcbsp_dma_rx->dma_rx_lch);
mcbsp_dma_rx->dma_rx_lch = -1;
complete(&mcbsp_dma_rx->rx_dma_completion);
}
/*
* davinci_mcbsp_config simply write a config to the
* appropriate McBSP.
* You either call this function or set the McBSP registers
* by yourself before calling davinci_mcbsp_start().
*/
void davinci_mcbsp_config(unsigned int id,
const struct davinci_mcbsp_reg_cfg *config)
{
u32 io_base = mcbsp[id].io_base;
DBG("davinci-McBSP: McBSP%d io_base: 0x%8x\n", id + 1, io_base);
DAVINCI_MCBSP_WRITE(io_base, PCR0, config->pcr0);
DAVINCI_MCBSP_WRITE(io_base, RCR2, config->rcr2);
DAVINCI_MCBSP_WRITE(io_base, RCR1, config->rcr1);
DAVINCI_MCBSP_WRITE(io_base, XCR2, config->xcr2);
DAVINCI_MCBSP_WRITE(io_base, XCR1, config->xcr1);
DAVINCI_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
DAVINCI_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
/* We write the given config */
DAVINCI_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
DAVINCI_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
return;
}
static int davinci_mcbsp_check(unsigned int id)
{
if (id > DAVINCI_MAX_MCBSP_COUNT - 1) {
DBG("DAVINCI-McBSP: McBSP%d doesn't exist\n", id + 1);
return -1;
}
return 0;
}
int davinci_mcbsp_request(unsigned int id)
{
if (davinci_mcbsp_check(id) < 0)
return -EINVAL;
spin_lock(&mcbsp[id].lock);
if (!mcbsp[id].free) {
DBG("DAVINCI-McBSP: McBSP%d is currently in use\n", id + 1);
spin_unlock(&mcbsp[id].lock);
return -1;
}
mcbsp[id].free = 0;
spin_unlock(&mcbsp[id].lock);
return 0;
}
void davinci_mcbsp_free(unsigned int id)
{
if (davinci_mcbsp_check(id) < 0)
return;
spin_lock(&mcbsp[id].lock);
if (mcbsp[id].free) {
DBG("DAVINCI-McBSP: McBSP%d was not reserved\n", id + 1);
spin_unlock(&mcbsp[id].lock);
return;
}
mcbsp[id].free = 1;
spin_unlock(&mcbsp[id].lock);
return;
}
/*
* Here we start the McBSP, by enabling the sample
* generator, both transmitter and receivers,
* and the frame sync.
*/
void davinci_mcbsp_start(unsigned int id)
{
u32 io_base;
u16 w;
if (davinci_mcbsp_check(id) < 0)
return;
io_base = mcbsp[id].io_base;
mcbsp[id].rx_word_length =
((DAVINCI_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
mcbsp[id].tx_word_length =
((DAVINCI_MCBSP_READ(io_base, XCR1) >> 5) & 0x7);
/* Start the sample generator */
w = DAVINCI_MCBSP_READ(io_base, SPCR2);
DAVINCI_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
/* Enable transmitter and receiver */
w = DAVINCI_MCBSP_READ(io_base, SPCR2);
DAVINCI_MCBSP_WRITE(io_base, SPCR2, w | 1);
w = DAVINCI_MCBSP_READ(io_base, SPCR1);
DAVINCI_MCBSP_WRITE(io_base, SPCR1, w | 1);
udelay(100);
/* Start frame sync */
w = DAVINCI_MCBSP_READ(io_base, SPCR2);
DAVINCI_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
return;
}
void davinci_mcbsp_stop(unsigned int id)
{
u32 io_base;
u16 w;
if (davinci_mcbsp_check(id) < 0)
return;
io_base = mcbsp[id].io_base;
/* Reset transmitter */
w = DAVINCI_MCBSP_READ(io_base, SPCR2);
DAVINCI_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
/* Reset receiver */
w = DAVINCI_MCBSP_READ(io_base, SPCR1);
DAVINCI_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
/* Reset the sample rate generator */
w = DAVINCI_MCBSP_READ(io_base, SPCR2);
DAVINCI_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
/* Reset the frame sync generator */
w = DAVINCI_MCBSP_READ(io_base, SPCR2);
DAVINCI_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 7));
return;
}
/*
* IRQ based word transmission.
*/
void davinci_mcbsp_xmit_word(unsigned int id, u32 word)
{
u32 io_base;
davinci_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
if (davinci_mcbsp_check(id) < 0)
return;
io_base = mcbsp[id].io_base;
DBG(" io_base = 0x%x\n", io_base);
if (word_length > DAVINCI_MCBSP_WORD_16) {
DBG(" writing DXR2 register \n");
DAVINCI_MCBSP_WRITE(io_base, DXR2, word >> 16);
}
DBG(" writing DXR1 register \n");
DAVINCI_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
}
u32 davinci_mcbsp_recv_word(unsigned int id)
{
u32 io_base;
u16 word_lsb, word_msb = 0;
davinci_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
if (davinci_mcbsp_check(id) < 0)
return -EINVAL;
io_base = mcbsp[id].io_base;
if (word_length > DAVINCI_MCBSP_WORD_16)
word_msb = DAVINCI_MCBSP_READ(io_base, DRR2);
word_lsb = DAVINCI_MCBSP_READ(io_base, DRR1);
return (word_lsb | (word_msb << 16));
}
/*
* Simple DMA based buffer rx/tx routines.
* Nothing fancy, just a single buffer tx/rx through DMA.
* The DMA resources are released once the transfer is done.
* For anything fancier, you should use your own customized DMA
* routines and callbacks.
*/
int davinci_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
unsigned int length)
{
int dma_tx_ch;
int tcc;
if (davinci_mcbsp_check(id) < 0)
return -EINVAL;
if (davinci_request_dma
(mcbsp[id].dma_tx_sync, "McBSP TX", davinci_mcbsp_tx_dma_callback,
&mcbsp[id], &dma_tx_ch, &tcc, EVENTQ_0)) {
DBG("DAVINCI-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n",
id + 1);
return -EAGAIN;
}
mcbsp[id].dma_tx_lch = dma_tx_ch;
DBG("TX DMA on channel %d\n", dma_tx_ch);
init_completion(&(mcbsp[id].tx_dma_completion));
davinci_set_dma_transfer_params(mcbsp[id].dma_tx_lch, 2, length / 2, 1,
0, ASYNC);
davinci_set_dma_dest_params(mcbsp[id].dma_tx_lch,
(unsigned long)0x01E02004, 0, 0);
davinci_set_dma_src_params(mcbsp[id].dma_tx_lch, (buffer), 0, 0);
davinci_set_dma_src_index(mcbsp[id].dma_tx_lch, 2, 0);
davinci_set_dma_dest_index(mcbsp[id].dma_tx_lch, 0, 0);
davinci_start_dma(mcbsp[id].dma_tx_lch);
wait_for_completion(&(mcbsp[id].tx_dma_completion));
return 0;
}
int davinci_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
unsigned int length)
{
int dma_rx_ch;
int tcc;
if (davinci_mcbsp_check(id) < 0)
return -EINVAL;
if (davinci_request_dma
(mcbsp[id].dma_rx_sync, "McBSP RX", davinci_mcbsp_rx_dma_callback,
&mcbsp[id], &dma_rx_ch, &tcc, EVENTQ_0)) {
DBG("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n",
id + 1);
return -EAGAIN;
}
mcbsp[id].dma_rx_lch = dma_rx_ch;
DBG("RX DMA on channel %d\n", dma_rx_ch);
init_completion(&(mcbsp[id].rx_dma_completion));
davinci_set_dma_transfer_params(mcbsp[id].dma_rx_lch, 2, length / 2, 1,
0, ASYNC);
davinci_set_dma_src_params(mcbsp[id].dma_rx_lch,
(unsigned long)0x01E02000, 0, 0);
davinci_set_dma_dest_params(mcbsp[id].dma_rx_lch,
(unsigned long)virt_to_phys((void *)buffer),
0, 0);
davinci_set_dma_src_index(mcbsp[id].dma_rx_lch, 0, 0);
davinci_set_dma_dest_index(mcbsp[id].dma_rx_lch, 2, 0);
davinci_start_dma(mcbsp[id].dma_rx_lch);
wait_for_completion(&(mcbsp[id].rx_dma_completion));
DBG(" davinci_mcbsp_recv_buffer: after wait_for_completion\n");
return 0;
}
struct clk * davinci_mcbsp_get_clock(void)
{
return mbspclk;
}
struct davinci_mcbsp_info {
u32 virt_base;
u8 dma_rx_sync, dma_tx_sync;
u16 rx_irq, tx_irq;
};
static const struct davinci_mcbsp_info mcbsp_davinci[] = {
[0] = {.virt_base = IO_ADDRESS(DAVINCI_MCBSP1_BASE),
.dma_rx_sync = DAVINCI_DMA_MCBSP1_RX,
.dma_tx_sync = DAVINCI_DMA_MCBSP1_TX,
.rx_irq = DAVINCI_McBSP1RX,
.tx_irq = DAVINCI_McBSP1TX},
};
static int __init davinci_mcbsp_init(void)
{
int mcbsp_count = 0, i;
static const struct davinci_mcbsp_info *mcbsp_info;
struct clk *clkp;
clkp = clk_get (NULL, "McBSPCLK");
if (IS_ERR(clkp)) {
return -1;
}
else
{
mbspclk = clkp;
clk_enable (mbspclk);
mcbsp_info = mcbsp_davinci;
mcbsp_count = ARRAY_SIZE(mcbsp_davinci);
for (i = 0; i < DAVINCI_MAX_MCBSP_COUNT; i++) {
if (i >= mcbsp_count) {
mcbsp[i].io_base = 0;
mcbsp[i].free = 0;
continue;
}
mcbsp[i].id = i + 1;
mcbsp[i].free = 1;
mcbsp[i].dma_tx_lch = -1;
mcbsp[i].dma_rx_lch = -1;
mcbsp[i].io_base = mcbsp_info[i].virt_base;
mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
spin_lock_init(&mcbsp[i].lock);
}
}
return 0;
}
static void __exit davinci_mcbsp_exit(void)
{
int i;
for( i = 0; i < DAVINCI_MAX_MCBSP_COUNT; i++) {
mcbsp[i].free = 0;
mcbsp[i].dma_tx_lch = -1;
mcbsp[i].dma_rx_lch = -1;
}
clk_disable (mbspclk);
return;
}
module_init(davinci_mcbsp_init);
module_exit(davinci_mcbsp_exit);
EXPORT_SYMBOL(davinci_mcbsp_config);
EXPORT_SYMBOL(davinci_mcbsp_request);
EXPORT_SYMBOL(davinci_mcbsp_free);
EXPORT_SYMBOL(davinci_mcbsp_start);
EXPORT_SYMBOL(davinci_mcbsp_stop);
EXPORT_SYMBOL(davinci_mcbsp_xmit_word);
EXPORT_SYMBOL(davinci_mcbsp_recv_word);
EXPORT_SYMBOL(davinci_mcbsp_xmit_buffer);
EXPORT_SYMBOL(davinci_mcbsp_recv_buffer);
EXPORT_SYMBOL(davinci_mcbsp_get_clock);
MODULE_AUTHOR("Texas Instruments");
MODULE_DESCRIPTION("McBSP driver for DaVinci.");
MODULE_LICENSE("GPL");
/*
* linux/arch/arm/mach-davinci/serial_davinci.c
*
* TI DaVinci serial driver hookup file
*
* Copyright (C) 2006 Texas Instruments.
*
* ----------------------------------------------------------------------------
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* ----------------------------------------------------------------------------
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/serial.h>
#include <asm/arch/hardware.h>
#include <asm/arch/irqs.h>
#define UART_DAVINCI_PWREMU 0x0c
static inline unsigned int davinci_serial_in(struct plat_serial8250_port *up,
int offset)
{
offset <<= up->regshift;
return (unsigned int)__raw_readb(up->membase + offset);
}
static inline void davinci_serial_outp(struct plat_serial8250_port *p,
int offset, int value)
{
offset <<= p->regshift;
__raw_writeb(value, p->membase + offset);
}
static struct plat_serial8250_port serial_platform_data[] = {
{
.membase = (unsigned char __iomem *)IO_ADDRESS(DAVINCI_UART0_BASE),
.mapbase = (unsigned long)DAVINCI_UART0_BASE,
.irq = IRQ_UARTINT0,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = 27000000,
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = serial_platform_data,
},
};
static void __init davinci_serial_reset(struct plat_serial8250_port *p)
{
/* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
unsigned int pwremu = 0;
davinci_serial_outp(p, UART_IER, 0); /* disable all interrupts */
davinci_serial_outp(p, UART_DAVINCI_PWREMU, pwremu);
mdelay(10);
pwremu |= (0x3 << 13);
pwremu |= 0x1;
davinci_serial_outp(p, UART_DAVINCI_PWREMU, pwremu);
}
static int __init davinci_serial_init(void)
{
struct clk *clk;
struct device *dev = &serial_device.dev;
davinci_serial_reset(&serial_platform_data[0]);
clk = clk_get(dev, "UART");
if (!clk) {
printk(KERN_ERR "%s:%d: failed to get UART clock\n",
__FUNCTION__, __LINE__);
return -ENODEV;
}
clk_enable(clk);
return platform_device_register(&serial_device);
}
arch_initcall(davinci_serial_init);
/*
* linux/arch/arm/mach-davinci/time.c
*
* DaVinci timer subsystem
*
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* Copyright 2005 (c) MontaVista Software, Inc. This file is licensed
* under the terms of the GNU General Public License version 2. This
* program is licensed "as is" without any warranty of any kind,
* whether express or implied.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/system.h>
#include <asm/leds.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/arch/timex.h>
#include <asm/arch/irqs.h>
#include <asm/errno.h>
enum {
T0_BOT = 0, T0_TOP, T1_BOT, T1_TOP, NUM_TIMERS,
};
#define IS_TIMER1(id) (id & 0x2)
#define IS_TIMER0(id) (!IS_TIMER1(id))
#define IS_TIMER_TOP(id) ((id & 0x1))
#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id))
int timer_irqs[NUM_TIMERS] = {
IRQ_TINT0_TINT12,
IRQ_TINT0_TINT34,
IRQ_TINT1_TINT12,
IRQ_TINT1_TINT34,
};
/*
* This driver configures the 2 64-bit DaVinci timers as 4 independent
* 32-bit timers used as follows:
*
* T0_BOT: Timer 0, bottom: free-running counter, used for cycle counter
* T0_TOP: Timer 0, top : reserved for high-res timers
* T1_BOT: Timer 1, bottom: reserved for DSP
* T1_TOP: Timer 1, top : Linux system tick
*/
#define TID_SYSTEM T1_TOP
#define TID_FREERUN T0_BOT
#define TID_HRT T0_TOP
/* timer regs */
typedef struct davinci_timer_regs_s {
unsigned int pid12; /* 0x0 */
unsigned int emumgt_clksped; /* 0x4 */
unsigned int gpint_en; /* 0x8 */
unsigned int gpdir_dat; /* 0xC */
unsigned int tim12; /* 0x10 */
unsigned int tim34; /* 0x14 */
unsigned int prd12; /* 0x18 */
unsigned int prd34; /* 0x1C */
unsigned int tcr; /* 0x20 */
unsigned int tgcr; /* 0x24 */
unsigned int wdtcr; /* 0x28 */
unsigned int tlgc; /* 0x2C */
unsigned int tlmr; /* 0x30 */
} davinci_timer_regs_t;
typedef struct davinci_timer_s {
char *name;
unsigned int id;
unsigned long period;
unsigned long opts;
davinci_timer_regs_t *regs;
struct irqaction irqaction;
} davinci_timer_t;
static davinci_timer_t davinci_timers[];
/* values for 'opts' field of davinci_timer_t */
#define TIMER_DISABLED 0x00
#define TIMER_ONE_SHOT 0x01
#define TIMER_CONTINUOUS 0x02
#define davinci_timer_base(id) \
(IS_TIMER1(id) ? \
(volatile davinci_timer_regs_t*)IO_ADDRESS(DAVINCI_TIMER1_BASE) : \
(volatile davinci_timer_regs_t*)IO_ADDRESS(DAVINCI_TIMER0_BASE))
/* cycles to nsec conversions taken from arch/i386/kernel/timers/timer_tsc.c,
* converted to use kHz by Kevin Hilman */
/* convert from cycles(64bits) => nanoseconds (64bits)
* basic equation:
* ns = cycles / (freq / ns_per_sec)
* ns = cycles * (ns_per_sec / freq)
* ns = cycles * (10^9 / (cpu_khz * 10^3))
* ns = cycles * (10^6 / cpu_khz)
*
* Then we use scaling math (suggested by george at mvista.com) to get:
* ns = cycles * (10^6 * SC / cpu_khz / SC
* ns = cycles * cyc2ns_scale / SC
*
* And since SC is a constant power of two, we can convert the div
* into a shift.
* -johnstul at us.ibm.com "math is hard, lets go shopping!"
*/
static unsigned long cyc2ns_scale;
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
static inline void set_cyc2ns_scale(unsigned long cpu_khz)
{
cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
}
static inline unsigned long long cycles_2_ns(unsigned long long cyc)
{
return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
}
static int davinci_timer32_config(davinci_timer_t *t) {
volatile davinci_timer_regs_t *regs = t->regs;
u32 enamode_shift, reset_shift;
int ret = 0;
if (IS_TIMER_BOT(t->id)) {
regs->prd12 = t->period;
enamode_shift = 6;
reset_shift = 0;
}
else {
regs->prd34 = t->period;
enamode_shift = 22;
reset_shift = 1;
}
/* reset timer */
regs->tgcr &= ~(0x1 << reset_shift);
/* Register interrupt */
if (t->irqaction.handler != NULL) {
ret = setup_irq(timer_irqs[t->id], &t->irqaction);
}
/* Set enable mode */
if (t->opts & TIMER_ONE_SHOT) {
regs->tcr |= 0x1 << enamode_shift;
}
else if (t->opts & TIMER_CONTINUOUS) {
regs->tcr |= 0x2 << enamode_shift;
}
else { /* TIMER_DISABLED */
regs->tcr &= ~(0x3 << enamode_shift);
}
/* unreset */
regs->tgcr |= (0x1 << reset_shift);
return ret;
}
static inline u32 davinci_timer32_read(davinci_timer_t *t) {
volatile davinci_timer_regs_t *regs = t->regs;
if IS_TIMER_TOP(t->id) {
return regs->tim34;
}
else {
return regs->tim12;
}
}
/*
* Last processed system timer interrupt
*/
static unsigned long davinci_timer32_last = 0;
static irqreturn_t system_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long now, latency;
write_seqlock(&xtime_lock);
now = davinci_timer32_read(&davinci_timers[TID_FREERUN]);
latency = davinci_timer32_read(&davinci_timers[TID_SYSTEM]);
davinci_timer32_last = now - latency;
/* Do the Linux timer operations */
timer_tick(regs);
write_sequnlock(&xtime_lock);
return IRQ_HANDLED;
}
unsigned long davinci_gettimeoffset(void)
{
unsigned long now, elapsed, nsec;
now = davinci_timer32_read(&davinci_timers[TID_FREERUN]);
elapsed = now - davinci_timer32_last;
nsec = (unsigned long)cycles_2_ns(elapsed);
return nsec / 1000;
}
static irqreturn_t freerun_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
/* TODO: keep track of roll-overs for 64-bit cycle-count */
return IRQ_HANDLED;
}
cycles_t davinci_get_cycles(void) {
return davinci_timer32_read(&davinci_timers[TID_FREERUN]);
}
static davinci_timer_t davinci_timers[NUM_TIMERS] = {
[TID_SYSTEM] = {
.name = "system tick",
.period = (CLOCK_TICK_RATE / (HZ)),
.opts = TIMER_CONTINUOUS,
.irqaction = {
.flags = SA_INTERRUPT,
.handler = system_timer_interrupt,
}
},
[TID_FREERUN] = {
.name = "free-run counter",
.period = 0xffffffff,
.opts = TIMER_CONTINUOUS,
.irqaction = {
.flags = SA_INTERRUPT,
.handler = freerun_interrupt,
}
},
};
void __init davinci_timer_init(void)
{
volatile davinci_timer_regs_t *t0 = davinci_timer_base(T0_BOT);
volatile davinci_timer_regs_t *t1 = davinci_timer_base(T1_BOT);
int i;
/* Disabled, Internal clock source */
t0->tcr = 0x0;
t1->tcr = 0x0;
/* reset both timers, no pre-scaler for timer34 */
t0->tgcr = 0;
t1->tgcr = 0;
/* Set both timers to unchained 32-bit */
t0->tgcr |= 0x4;
t1->tgcr |= 0x4;
/* Unreset timers */
t0->tgcr |= 0x3;
t1->tgcr |= 0x3;
/* Init both counters to zero */
t0->tim12 = 0;
t0->tim34 = 0;
t1->tim12 = 0;
t1->tim34 = 0;
set_cyc2ns_scale(CLOCK_TICK_RATE / 1000);
for(i=0; i<sizeof(davinci_timers)/sizeof(davinci_timer_t); i++) {
davinci_timer_t *t = &davinci_timers[i];
if (t->name) {
t->id = i;
t->regs =
(davinci_timer_regs_t *)davinci_timer_base(t->id);
t->irqaction.name = t->name;
t->irqaction.dev_id = (void *)t;
davinci_timer32_config(&davinci_timers[i]);
}
}
}
struct sys_timer davinci_timer = {
.init = davinci_timer_init,
.offset = davinci_gettimeoffset,
};
void davinci_watchdog_reset(void) {
volatile davinci_timer_regs_t *davinci_wdt = (davinci_timer_regs_t *)IO_ADDRESS(DAVINCI_WDOG_BASE);
davinci_wdt->tgcr = 0x8;
davinci_wdt->tgcr |= 0x3;
davinci_wdt->tim12 = 0;
davinci_wdt->tim34 = 0;
davinci_wdt->prd12 = 0;
davinci_wdt->prd34 = 0;
davinci_wdt->wdtcr |= 0x4000;
davinci_wdt->tcr |= 0x40;
davinci_wdt->wdtcr = 0xA5C64000;
davinci_wdt->wdtcr = 0xDA7E4000;
}
......@@ -121,8 +121,8 @@ config CPU_ARM925T
# ARM926T
config CPU_ARM926T
bool "Support ARM926T processor"
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_DAVINCI
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_DAVINCI
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_CACHE_VIVT
......
......@@ -524,4 +524,9 @@ config I2C_OMAP
help
Support for TI OMAP I2C driver. Say yes if you want to use the OMAP
I2C interface.
config I2C_DAVINCI
tristate "Davinci i2c driver"
depends on I2C && ARCH_DAVINCI
endmenu
......@@ -43,6 +43,7 @@ obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o
obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
EXTRA_CFLAGS += -DDEBUG
......
/*
* linux/drivers/i2c/i2c-davinci.c
*
* TI DAVINCI I2C unified algorith+adapter driver
*
* Copyright (C) 2006 Texas Instruments.
*
* ----------------------------------------------------------------------------
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* ----------------------------------------------------------------------------
Modifications:
ver. 1.0: Feb 2005, Vinod/Sudhakar
-
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/version.h>
#include <linux/i2c.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <asm/arch/hardware.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/err.h>
#include <linux/proc_fs.h>
#include <linux/sysctl.h>
#include <linux/wait.h>
#include <asm/arch/irqs.h>
#include "i2c-davinci.h"
MODULE_AUTHOR("Texas Instruments India");
MODULE_DESCRIPTION("TI DaVinci I2C bus adapter");
MODULE_LICENSE("GPL");
static int bus_freq;
module_param(bus_freq, int, 0);
MODULE_PARM_DESC(bus_freq,
"Set I2C bus frequency in KHz: 100 (Standard Mode) or 400 (Fast Mode)");
/* ----- global defines ----------------------------------------------- */
static const char driver_name[] = "i2c_davinci";
#define DAVINCI_I2C_TIMEOUT (1*HZ)
#define MAX_MESSAGES 65536 /* max number of messages */
#define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_ICIMR_AAS_MASK | \
DAVINCI_I2C_ICIMR_SCD_MASK | \
/*DAVINCI_I2C_ICIMR_ICXRDY_MASK | */\
/*DAVINCI_I2C_ICIMR_ICRRDY_MASK | */\
/*DAVINCI_I2C_ICIMR_ARDY_MASK | */\
DAVINCI_I2C_ICIMR_NACK_MASK | \
DAVINCI_I2C_ICIMR_AL_MASK)
/* Following are the default values for the module parameters */
static int bus_freq = 20; /* Fast Mode = 400 KHz, Standard Mode = 100 KHz */
static int own_addr = 0xa; /* Randomly assigned own address */
/* Instance of the private I2C device structure */
static struct i2c_davinci_device i2c_davinci_dev;
/*
* This functions configures I2C and brings I2C out of reset.
* This function is called during I2C init function. This function
* also gets called if I2C encounetrs any errors. Clock calculation portion
* of this function has been taken from some other driver.
*/
static int i2c_davinci_reset(struct i2c_davinci_device *dev)
{
u16 psc;
u32 clk;
u32 input_clock = clk_get_rate(dev->clk);
/* put I2C into reset */
dev->regs->icmdr &= ~DAVINCI_I2C_ICMDR_IRS_MASK;
/* NOTE: I2C Clock divider programming info
* As per I2C specs the following formulas provide prescalar
* and low/high divider values
*
* input clk --> PSC Div -----------> ICCL/H Div --> output clock
* module clk
*
* output clk = module clk / (PSC + 1) [ (ICCL + d) + (ICCH + d) ]
*
* Thus,
* (ICCL + ICCH) = clk = (input clk / ((psc +1) * output clk)) - 2d;
*
* where if PSC == 0, d = 7,
* if PSC == 1, d = 6
* if PSC > 1 , d = 5
*/
psc = 26; /* To get 1MHz clock */
clk = ((input_clock/(psc + 1)) / (bus_freq * 1000)) - 10;
dev->regs->icpsc = psc;
dev->regs->icclkh = (27 * clk) / 100; /* duty cycle should be 27% */
dev->regs->icclkl = (clk - dev->regs->icclkh);
dev_dbg(dev->dev, "CLK = %d\n", clk);
dev_dbg(dev->dev, "PSC = %d\n", dev->regs->icpsc);
dev_dbg(dev->dev, "CLKL = %d\n", dev->regs->icclkl);
dev_dbg(dev->dev, "CLKH = %d\n", dev->regs->icclkh);
/* Set Own Address: */
dev->regs->icoar = own_addr;
/* Enable interrupts */
dev->regs->icimr = I2C_DAVINCI_INTR_ALL;
/* Take the I2C module out of reset: */
dev->regs->icmdr |= DAVINCI_I2C_ICMDR_IRS_MASK;
return 0;
}
/*
* Waiting on Bus Busy
*/
static int i2c_davinci_wait_for_bb(char allow_sleep)
{
unsigned long timeout;
timeout = jiffies + DAVINCI_I2C_TIMEOUT;
while ((i2c_davinci_dev.regs->icstr) & DAVINCI_I2C_ICSTR_BB_MASK) {
if (time_after(jiffies, timeout)) {
return -ETIMEDOUT;
}
if (allow_sleep)
schedule_timeout(1);
}
return 0;
}
/*
* Low level master read/write transaction. This function is called
* from i2c_davinci_xfer.
*/
static int
i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
{
struct i2c_davinci_device *dev = i2c_get_adapdata(adap);
u8 zero_byte = 0;
u32 flag = 0, stat = 0, cnt = 2000;
int r;
/* Introduce a 20musec delay. Required for Davinci EVM */
while (cnt--);
/* set the slave address */
dev->regs->icsar = msg->addr;
/* Sigh, seems we can't do zero length transactions. Thus, we
* can't probe for devices w/o actually sending/receiving at least
* a single byte. So we'll set count to 1 for the zero length
* transaction case and hope we don't cause grief for some
* arbitrary device due to random byte write/read during
* probes.
*/
if (msg->len == 0) {
dev->buf = &zero_byte;
dev->buf_len = 1;
} else {
dev->buf = msg->buf;
dev->buf_len = msg->len;
}
dev->regs->iccnt = dev->buf_len;
init_completion(&dev->cmd_complete);
dev->cmd_err = 0;
/* Clear any pending interrupts by reading the IVR */
stat = dev->regs->icivr;
/* Take I2C out of reset, configure it as master and set the
* start bit */
flag =
DAVINCI_I2C_ICMDR_IRS_MASK | DAVINCI_I2C_ICMDR_MST_MASK |
DAVINCI_I2C_ICMDR_STT_MASK;
/* if the slave address is ten bit address, enable XA bit */
if (msg->flags & I2C_M_TEN)
flag |= DAVINCI_I2C_ICMDR_XA_MASK;
if (!(msg->flags & I2C_M_RD))
flag |= DAVINCI_I2C_ICMDR_TRX_MASK;
if (stop)
flag |= DAVINCI_I2C_ICMDR_STP_MASK;
/* write the data into mode register */
dev->regs->icmdr = flag;
/* Enable receive and transmit interrupts */
if (msg->flags & I2C_M_RD)
dev->regs->icimr |= DAVINCI_I2C_ICIMR_ICRRDY_MASK;
else
dev->regs->icimr |= DAVINCI_I2C_ICIMR_ICXRDY_MASK;
r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
DAVINCI_I2C_TIMEOUT);
dev->buf_len = 0;
if (r < 0)
return r;
if (r == 0) {
dev_err(dev->dev, "controller timed out\n");
i2c_davinci_reset(dev);
return -ETIMEDOUT;
}
/* no error */
if (!dev->cmd_err)
return msg->len;
/* We have an error */
if (dev->cmd_err & DAVINCI_I2C_ICSTR_NACK_MASK) {
if (msg->flags & I2C_M_IGNORE_NAK)
return msg->len;
if (stop)
dev->regs->icmdr |= DAVINCI_I2C_ICMDR_STP_MASK;
return -EREMOTEIO;
}
if (dev->cmd_err & DAVINCI_I2C_ICSTR_AL_MASK ||
dev->cmd_err & DAVINCI_I2C_ICSTR_RSFULL_MASK) {
i2c_davinci_reset(dev);
return -EIO;
}
return msg->len;
}
/*
* Prepare controller for a transaction and call i2c_davinci_xfer_msg
*/
static int
i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
struct i2c_davinci_device *dev = i2c_get_adapdata(adap);
int count;
int ret = 0;
char retries = 5;
dev_dbg(dev->dev, "%s: msgs: %d\n", __FUNCTION__, num);
if (num < 1 || num > MAX_MESSAGES)
return -EINVAL;
/* Check for valid parameters in messages */
for (count = 0; count < num; count++)
if (msgs[count].buf == NULL)
return -EINVAL;
if ((ret = i2c_davinci_wait_for_bb(1)) < 0) {
dev_warn(dev->dev, "timeout waiting for bus ready");
return ret;
}
for (count = 0; count < num; count++) {
dev_dbg(dev->dev,
"%s: %d, addr: 0x%04x, len: %d, flags: 0x%x\n",
__FUNCTION__,
count, msgs[count].addr, msgs[count].len,
msgs[count].flags);
do {
ret = i2c_davinci_xfer_msg(adap, &msgs[count],
(count == (num - 1)));
if (ret < 0) {
dev_dbg(dev->dev, "Retrying ...\n");
mdelay (1);
retries--;
} else
break;
} while (retries);
dev_dbg(dev->dev, "%s:%d ret: %d\n",
__FUNCTION__, __LINE__, ret);
if (ret != msgs[count].len)
break;
}
if (ret >= 0 && num > 1)
ret = num;
dev_dbg(dev->dev, "%s:%d ret: %d\n",
__FUNCTION__, __LINE__, ret);
return ret;
}
static u32 i2c_davinci_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
/*
* This function marks a transaction as complete.
*/
static inline void i2c_davinci_complete_cmd(struct i2c_davinci_device *dev)
{
complete(&dev->cmd_complete);
wake_up(&dev->cmd_wait);
}
/*
* Interrupt service routine. This gets called whenever an I2C interrupt
* occurs.
*/
static irqreturn_t
i2c_davinci_isr(int this_irq, void *dev_id, struct pt_regs *reg)
{
struct i2c_davinci_device *dev = dev_id;
u32 stat;
while ((stat = dev->regs->icivr) != 0) {
dev_dbg(dev->dev, "%s: stat=0x%x\n", __FUNCTION__, stat);
switch (stat) {
case DAVINCI_I2C_ICIVR_INTCODE_AL:
dev->cmd_err |= DAVINCI_I2C_ICSTR_AL_MASK;
i2c_davinci_complete_cmd(dev);
break;
case DAVINCI_I2C_ICIVR_INTCODE_NACK:
dev->cmd_err |= DAVINCI_I2C_ICSTR_NACK_MASK;
i2c_davinci_complete_cmd(dev);
break;
case DAVINCI_I2C_ICIVR_INTCODE_RAR:
dev->regs->icstr |= DAVINCI_I2C_ICSTR_ARDY_MASK;
break;
case DAVINCI_I2C_ICIVR_INTCODE_RDR:
if (dev->buf_len) {
*dev->buf++ = dev->regs->icdrr;
dev->buf_len--;
if (dev->buf_len) {
continue;
} else {
dev->regs->icimr &=
~DAVINCI_I2C_ICIMR_ICRRDY_MASK;
}
}
break;
case DAVINCI_I2C_ICIVR_INTCODE_TDR:
if (dev->buf_len) {
dev->regs->icdxr = *dev->buf++;
dev->buf_len--;
if (dev->buf_len)
continue;
else {
dev->regs->icimr &=
~DAVINCI_I2C_ICIMR_ICXRDY_MASK;
}
}
break;
case DAVINCI_I2C_ICIVR_INTCODE_SCD:
dev->regs->icstr |= DAVINCI_I2C_ICSTR_SCD_MASK;
i2c_davinci_complete_cmd(dev);
break;
case DAVINCI_I2C_ICIVR_INTCODE_AAS:
dev_warn(dev->dev, "Address as slave interrupt");
break;
default:
break;
} /* switch */
} /* while */
return IRQ_HANDLED;
}
static struct i2c_algorithm i2c_davinci_algo = {
.master_xfer = i2c_davinci_xfer,
.functionality = i2c_davinci_func,
};
static int
davinci_i2c_probe(struct platform_device *pdev)
{
struct i2c_davinci_device *dev = &i2c_davinci_dev;
struct i2c_adapter *adap;
struct resource *mem, *irq;
int r;
/* NOTE: driver uses the static register mapping */
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n");
return -ENODEV;
}
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq) {
dev_err(&pdev->dev, "no irq resource?\n");
return -ENODEV;
}
r = (int) request_mem_region(mem->start, (mem->end - mem->start) + 1,
driver_name);
if (!r) {
dev_err(&pdev->dev, "I2C region already claimed\n");
return -EBUSY;
}
memset(dev, 0, sizeof(struct i2c_davinci_device));
init_waitqueue_head(&dev->cmd_wait);
dev->dev = &pdev->dev;
dev->clk = clk_get (&pdev->dev, "I2CCLK");
if (IS_ERR(dev->clk))
return -1;
clk_enable(dev->clk);
dev->regs = (davinci_i2cregsovly)mem->start;
i2c_davinci_reset(dev);
dev->irq = irq->start;
platform_set_drvdata(pdev, dev);
r = request_irq(dev->irq, i2c_davinci_isr, 0, driver_name, dev);
if (r) {
dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
goto do_unuse_clocks;
}
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON;
strncpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name));
adap->algo = &i2c_davinci_algo;
adap->dev.parent = &pdev->dev;
adap->client_register = NULL;
adap->client_unregister = NULL;
adap->timeout = 1;
adap->retries = 1;
/* i2c device drivers may be active on return from add_adapter() */
r = i2c_add_adapter(adap);
if (r) {
dev_err(&pdev->dev, "failure adding adapter\n");
goto do_free_irq;
}
return 0;
do_free_irq:
free_irq(dev->irq, dev);
do_unuse_clocks:
clk_disable(dev->clk);
clk_put(dev->clk);
dev->clk = NULL;
do_free_mem:
do_release_region:
release_mem_region(mem->start, (mem->end - mem->start) + 1);
return r;
}
static int
davinci_i2c_remove(struct platform_device *pdev)
{
struct i2c_davinci_device *dev = platform_get_drvdata(pdev);
struct resource *mem;
clk_disable(dev->clk);
clk_put(dev->clk);
dev->clk = NULL;
i2c_davinci_dev.regs->icmdr = 0;
free_irq(IRQ_I2C, &i2c_davinci_dev);
i2c_del_adapter(&dev->adapter);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, (mem->end - mem->start) + 1);
return 0;
}
static struct platform_driver davinci_i2c_driver = {
.probe = davinci_i2c_probe,
.remove = davinci_i2c_remove,
.driver = {
.name = (char *)driver_name,
},
};
/* I2C may be needed to bring up other drivers */
static int __init
davinci_i2c_init_driver(void)
{
return platform_driver_register(&davinci_i2c_driver);
}
subsys_initcall(davinci_i2c_init_driver);
static void __exit davinci_i2c_exit_driver(void)
{
platform_driver_unregister(&davinci_i2c_driver);
}
module_exit(davinci_i2c_exit_driver);
/*
* linux/drivers/i2c/busses/davinci/i2c_davinci.h
*
* Copyright (C) 2006 Texas Instruments.
*
* ----------------------------------------------------------------------------
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* ----------------------------------------------------------------------------
Modifications:
ver. 1.0: Feb 2005, Vinod/Sudhakar
-
*
*/
#define DAVINCI_I2C_ICOAR_OADDR_MASK (0x03FFu)
#define DAVINCI_I2C_ICIMR_AAS_MASK (0x0040u)
#define DAVINCI_I2C_ICIMR_SCD_MASK (0x0020u)
#define DAVINCI_I2C_ICIMR_ICXRDY_MASK (0x0010u)
#define DAVINCI_I2C_ICIMR_ICRRDY_MASK (0x0008u)
#define DAVINCI_I2C_ICIMR_ARDY_MASK (0x0004u)
#define DAVINCI_I2C_ICIMR_NACK_MASK (0x0002u)
#define DAVINCI_I2C_ICIMR_AL_MASK (0x0001u)
#define DAVINCI_I2C_ICSTR_SDIR_MASK (0x4000u)
#define DAVINCI_I2C_ICSTR_NACKSNT_MASK (0x2000u)
#define DAVINCI_I2C_ICSTR_BB_MASK (0x1000u)
#define DAVINCI_I2C_ICSTR_RSFULL_MASK (0x0800u)
#define DAVINCI_I2C_ICSTR_XSMT_MASK (0x0400u)
#define DAVINCI_I2C_ICSTR_AAS_MASK (0x0200u)
#define DAVINCI_I2C_ICSTR_AD0_MASK (0x0100u)
#define DAVINCI_I2C_ICSTR_SCD_MASK (0x0020u)
#define DAVINCI_I2C_ICSTR_ICXRDY_MASK (0x0010u)
#define DAVINCI_I2C_ICSTR_ICRRDY_MASK (0x0008u)
#define DAVINCI_I2C_ICSTR_ARDY_MASK (0x0004u)
#define DAVINCI_I2C_ICSTR_NACK_MASK (0x0002u)
#define DAVINCI_I2C_ICSTR_AL_MASK (0x0001u)
#define DAVINCI_I2C_ICCLKL_ICCL_MASK (0xFFFFu)
#define DAVINCI_I2C_ICCLKH_ICCH_MASK (0xFFFFu)
#define DAVINCI_I2C_ICCNT_ICDC_MASK (0xFFFFu)
#define DAVINCI_I2C_ICDRR_D_MASK (0x00FFu)
#define DAVINCI_I2C_ICSAR_SADDR_MASK (0x03FFu)
#define DAVINCI_I2C_ICDXR_D_MASK (0x00FFu)
#define DAVINCI_I2C_ICMDR_NACKMOD_MASK (0x8000u)
#define DAVINCI_I2C_ICMDR_FREE_MASK (0x4000u)
#define DAVINCI_I2C_ICMDR_STT_MASK (0x2000u)
#define DAVINCI_I2C_ICMDR_STP_MASK (0x0800u)
#define DAVINCI_I2C_ICMDR_MST_MASK (0x0400u)
#define DAVINCI_I2C_ICMDR_TRX_MASK (0x0200u)
#define DAVINCI_I2C_ICMDR_XA_MASK (0x0100u)
#define DAVINCI_I2C_ICMDR_RM_MASK (0x0080u)
#define DAVINCI_I2C_ICMDR_DLB_MASK (0x0040u)
#define DAVINCI_I2C_ICMDR_IRS_MASK (0x0020u)
#define DAVINCI_I2C_ICMDR_STB_MASK (0x0010u)
#define DAVINCI_I2C_ICMDR_FDF_MASK (0x0008u)
#define DAVINCI_I2C_ICMDR_BC_MASK (0x0007u)
#define DAVINCI_I2C_ICIVR_TESTMD_MASK (0x0F00u)
#define DAVINCI_I2C_ICIVR_INTCODE_MASK (0x0007u)
#define DAVINCI_I2C_ICIVR_INTCODE_NONE (0x0000u)
#define DAVINCI_I2C_ICIVR_INTCODE_AL (0x0001u)
#define DAVINCI_I2C_ICIVR_INTCODE_NACK (0x0002u)
#define DAVINCI_I2C_ICIVR_INTCODE_RAR (0x0003u)
#define DAVINCI_I2C_ICIVR_INTCODE_RDR (0x0004u)
#define DAVINCI_I2C_ICIVR_INTCODE_TDR (0x0005u)
#define DAVINCI_I2C_ICIVR_INTCODE_SCD (0x0006u)
#define DAVINCI_I2C_ICIVR_INTCODE_AAS (0x0007u)
#define DAVINCI_I2C_ICEMDR_BCM_MASK (0x0001u)
#define DAVINCI_I2C_ICPSC_IPSC_MASK (0x00FFu)
#define DAVINCI_I2C_ICPID1_CLASS_MASK (0xFF00u)
#define DAVINCI_I2C_ICPID1_REVISION_MASK (0x00FFu)
#define DAVINCI_I2C_ICPID2_TYPE_MASK (0x00FFu)
#define DAVINCI_I2C_ICPFUNC_PFUNC_MASK (0x00000001u)
#define DAVINCI_I2C_ICPDIR_PDIR1_MASK (0x00000002u)
#define DAVINCI_I2C_ICPDIR_PDIR0_MASK (0x00000001u)
#define DAVINCI_I2C_ICPDIN_PDIN1_MASK (0x00000002u)
#define DAVINCI_I2C_ICPDIN_PDIN0_MASK (0x00000001u)
#define DAVINCI_I2C_ICPDOUT_PDOUT1_MASK (0x00000002u)
#define DAVINCI_I2C_ICPDOUT_PDOUT0_MASK (0x00000001u)
#define DAVINCI_I2C_ICPDSET_PDSET1_MASK (0x00000002u)
#define DAVINCI_I2C_ICPDSET_PDSET0_MASK (0x00000001u)
#define DAVINCI_I2C_ICPDCLR_PDCLR1_MASK (0x00000002u)
#define DAVINCI_I2C_ICPDCLR_PDCLR0_MASK (0x00000001u)
/**************************************************************************\
* Register Overlay Structure
\**************************************************************************/
typedef struct {
u16 icoar;
u8 rsvd0[2];
u16 icimr;
u8 rsvd1[2];
u16 icstr;
u8 rsvd2[2];
u16 icclkl;
u8 rsvd3[2];
u16 icclkh;
u8 rsvd4[2];
u16 iccnt;
u8 rsvd5[2];
u16 icdrr;
u8 rsvd6[2];
u16 icsar;
u8 rsvd7[2];
u16 icdxr;
u8 rsvd8[2];
u16 icmdr;
u8 rsvd9[2];
u16 icivr;
u8 rsvd10[2];
u16 icemdr;
u8 rsvd11[2];
u16 icpsc;
u8 rsvd12[2];
u16 icpid1;
u8 rsvd13[2];
u16 icpid2;
u8 rsvd14[14];
u32 ipcfunc;
u32 icpdir;
u32 icpdin;
u32 icpdout;
u32 icpdset;
u32 icpdclr;
} davinci_i2cregs;
/**************************************************************************\
* Overlay structure typedef definition
\**************************************************************************/
typedef volatile davinci_i2cregs *davinci_i2cregsovly;
struct i2c_davinci_device {
int cmd_err;
struct completion cmd_complete;
wait_queue_head_t cmd_wait;
u8 *buf;
size_t buf_len;
davinci_i2cregsovly regs;
int irq;
struct i2c_adapter adapter;
struct clk *clk;
struct device *dev;
};
......@@ -819,6 +819,15 @@ config ULTRA32
<file:Documentation/networking/net-modules.txt>. The module
will be called smc-ultra32.
config TI_DAVINCI_EMAC
tristate "TI DaVinci EMAC Support"
depends on NETDEVICES && MACH_DAVINCI_EVM
help
This driver supports TI's DaVinci Ethernet .
To compile this driver as a module, choose M here: the module
will be called ti_davinci_emac. This is recommended.
config SMC91X
tristate "SMC 91C9x/91C1xxx support"
select CRC32
......
......@@ -6,6 +6,8 @@ ifeq ($(CONFIG_ISDN_PPP),y)
obj-$(CONFIG_ISDN) += slhc.o
endif
davinci_emac_driver-objs := davinci_emac.o davinci_emac_phy.o
obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac_driver.o
obj-$(CONFIG_E1000) += e1000/
obj-$(CONFIG_IBM_EMAC) += ibm_emac/
obj-$(CONFIG_IXGB) += ixgb/
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* linux/drivers/net/davinci_emac_phy.c
*
* EMAC MII-MDIO Module - Polling State Machine.
*
* Copyright (C) 2006 Texas Instruments.
*
* ----------------------------------------------------------------------------
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* ----------------------------------------------------------------------------
Modifications:
* HISTORY:
* Date Modifier Notes
* 2001/02 Denis, Bill, Michael Original
* 14Feb2006 Anant Gole Re-written for linux
*/
#include <linux/kernel.h>
#include "davinci_emac_phy.h"
#define EMAC_PHY_DEBUG
#ifdef EMAC_PHY_DEBUG
/* note: prints function name for you */
#define DPRINTK(fmt, args...) if (emac_phy->debug_mode) printk(KERN_ERR "\n%s: " fmt, __FUNCTION__ , ## args)
#else
#define DPRINTK(fmt, args...)
#endif
/* Phy Registers */
#define PHY_CONTROL_REG 0
#define MII_PHY_RESET (1<<15)
#define MII_PHY_LOOP (1<<14)
#define MII_PHY_100 (1<<13)
#define MII_AUTO_NEGOTIATE_EN (1<<12)
#define MII_PHY_PDOWN (1<<11)
#define MII_PHY_ISOLATE (1<<10)
#define MII_RENEGOTIATE (1<<9)
#define MII_PHY_FD (1<<8)
#define PHY_STATUS_REG 1
#define MII_NWAY_COMPLETE (1<<5)
#define MII_NWAY_CAPABLE (1<<3)
#define MII_PHY_LINKED (1<<2)
#define NWAY_ADVERTIZE_REG 4
#define NWAY_REMADVERTISE_REG 5
#define MII_NWAY_FD100 (1<<8)
#define MII_NWAY_HD100 (1<<7)
#define MII_NWAY_FD10 (1<<6)
#define MII_NWAY_HD10 (1<<5)
#define MII_NWAY_SEL (1<<0)
/* Timeout values - since timer tikc is expected to be 10 mSecs fixed these
* values are in (value * 10 mSecs) */
#define PHY_FIND_TIMEOUT (2)
#define PHY_RECK_TIMEOUT (200)
#define PHY_LINK_TIMEOUT (500)
#define PHY_NWST_TIMEOUT (500)
#define PHY_NWDN_TIMEOUT (800)
#define PHY_MDIX_TIMEOUT (274) /* 2.74 Seconds <--Spec and empirical */
/* Mask & Control defines */
#define MDIO_CONTROL_CLKDIV (0xFF)
#define MDIO_CONTROL_ENABLE (1 << 30)
#define MDIO_USERACCESS_GO (1 << 31)
#define MDIO_USERACCESS_WRITE (1 << 30)
#define MDIO_USERACCESS_READ (0 << 30)
#define MDIO_USERACCESS_WRITE (1 << 30)
#define MDIO_USERACCESS_REGADR (0x1F << 21)
#define MDIO_USERACCESS_PHYADR (0x1F << 16)
#define MDIO_USERACCESS_DATA (0xFFFF)
#define MDIO_USERPHYSEL_LINKSEL (1 << 7)
#define MDIO_VER_MODID (0xFFFF << 16)
#define MDIO_VER_REVMAJ (0xFF << 8)
#define MDIO_VER_REVMIN (0xFF)
/* PHY Registers */
#define MDIO_VER (0x00)
#define MDIO_CONTROL (0x04)
#define MDIO_ALIVE (0x08)
#define MDIO_LINK (0x0C)
#define MDIO_LINKINTRAW (0x10)
#define MDIO_LINKINTMASKED (0x14)
#define MDIO_USERINTRAW (0x20)
#define MDIO_USERINTMASKED (0x24)
#define MDIO_USERINTMASKED_SET (0x28)
#define MDIO_USERINTMASKED_CLR (0x2C)
#define MDIO_USERACCESS(inst) (0x80+(inst*8))
#define MDIO_USERPHYSEL(inst) (0x84+(inst*8))
#define MDIO_REG(reg) (*((volatile unsigned int *)(emac_phy->base + (reg))))
#define MDIO_REG_VER MDIO_REG(MDIO_VER)
#define MDIO_REG_CONTROL MDIO_REG(MDIO_CONTROL)
#define MDIO_REG_ALIVE MDIO_REG(MDIO_ALIVE)
#define MDIO_REG_LINK MDIO_REG(MDIO_LINK)
#define MDIO_REG_LINKINTRAW MDIO_REG(MDIO_LINKINTRAW)
#define MDIO_REG_LINKINTMASKED MDIO_REG(MDIO_LINKINTMASKED)
#define MDIO_REG_USERINTMASKED MDIO_REG(MDIO_USERINTMASKED)
#define MDIO_REG_USERINTMASKED_SET MDIO_REG(MDIO_USERINTMASKED_SET)
#define MDIO_REG_USERINTMASKED_CLR MDIO_REG(MDIO_USERINTMASKED_CLR)
#define MDIO_REG_USERACCESS MDIO_REG(MDIO_USERACCESS(emac_phy->inst))
#define MDIO_REG_USERPHYSEL MDIO_REG(MDIO_USERPHYSEL(emac_phy->inst))
/* Phy State */
#define PHY_NULL (0)
#define PHY_INIT (1)
#define PHY_FINDING (2)
#define PHY_FOUND (3)
#define PHY_NWAY_START (4)
#define PHY_NWAY_WAIT (5)
#define PHY_LINK_WAIT (6)
#define PHY_LINKED (7)
#define PHY_LOOPBACK (8)
static char *phy_state_str[] = {
"NULL", "INIT", "FINDING", "FOUND", "NWAY_START", "NWAY_WAIT",
"LINK_WAIT", "LINKED", "LOOPBACK"
};
#define PHY_NOT_FOUND 0xFFFF /* Used in Phy Detection */
struct phy_info {
int inst; /* Instance of PHY - for user sel register */
unsigned int base; /* Base address of mdio module */
int state; /* state of phy */
int state_change; /* phy state change ? */
unsigned int timeout; /* Timeout counter */
unsigned int phy_mode; /* requested phy mode */
unsigned int speed; /* current Speed - 10 / 100 */
unsigned int duplex; /* 0=Auto Negotiate, Full=3; Half=2, Unknown=1 */
unsigned int phy_addr; /* phy address */
unsigned int phy_mask; /* phy mask */
unsigned int mlink_mask;/* mlink mask */
int debug_mode; /* debug mode */
};
/* Global phy structure instance */
struct phy_info emac_phy_info;
struct phy_info *emac_phy = &emac_phy_info;
void emac_mdio_get_ver(unsigned int mdio_base, unsigned int *module_id,
unsigned int *rev_major, unsigned int *rev_minor)
{
unsigned int ver;
emac_phy->base = mdio_base;
ver = MDIO_REG_VER;
*module_id = (ver & MDIO_VER_MODID) >> 16;
*rev_major = (ver & MDIO_VER_REVMAJ) >> 8;
*rev_minor = (ver & MDIO_VER_REVMIN);
}
/* Initialize mdio module */
int emac_mdio_init(unsigned int mdio_base,
unsigned int inst,
unsigned int phy_mask,
unsigned int mlink_mask,
unsigned int mdio_bus_freq,
unsigned int mdio_clock_freq, unsigned int verbose)
{
unsigned int clk_div;
/* Set base addr and init phy state */
emac_phy->inst = inst;
emac_phy->base = mdio_base;
emac_phy->phy_mask = phy_mask;
emac_phy->mlink_mask = mlink_mask;
emac_phy->state = PHY_INIT;
emac_phy->debug_mode = verbose;
emac_phy->speed = 10;
emac_phy->duplex = 2; /* Half duplex */
if (mdio_clock_freq & mdio_bus_freq) {
clk_div = ((mdio_bus_freq / mdio_clock_freq) - 1);
} else {
clk_div = 0xFF;
}
clk_div &= MDIO_CONTROL_CLKDIV;
/* Set enable and clock divider in MDIOControl */
MDIO_REG_CONTROL = (clk_div | MDIO_CONTROL_ENABLE);
return (0);
}
/* Set PHY mode - autonegotiation or any other */
void emac_mdio_set_phy_mode(unsigned int phy_mode)
{
emac_phy->phy_mode = phy_mode;
if ((emac_phy->state == PHY_NWAY_START) ||
(emac_phy->state == PHY_NWAY_WAIT) ||
(emac_phy->state == PHY_LINK_WAIT) ||
(emac_phy->state == PHY_LINKED) ||
(emac_phy->state == PHY_LOOPBACK)) {
emac_phy->state = PHY_FOUND;
emac_phy->state_change = 1;
}
DPRINTK("PhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d\n",
phy_mode,
phy_mode & NWAY_AUTO, phy_mode & MII_NWAY_FD10,
phy_mode & MII_NWAY_HD10, phy_mode & MII_NWAY_FD100,
phy_mode & MII_NWAY_HD100);
}
/* Get linked status - check if link is on - 1=link on, 0=link off */
int emac_mdio_is_linked(void)
{
return ((emac_phy->state == PHY_LINKED) ? 1 : 0);
}
/* Get speed - 10 / 100 Mbps */
int emac_mdio_get_speed(void)
{
return (emac_phy->speed);
}
/* Get duplex - 0=Auto Negotiate, Full Duplex = 3; Half Duplex = 2 Unknown = 1 */
int emac_mdio_get_duplex(void)
{
return (emac_phy->duplex);
}
/* Get Phy number/address */
int emac_mdio_get_phy_num(void)
{
return (emac_phy->phy_addr);
}
/* Check if loopback enabled on phy */
int emac_mdio_is_loopback(void)
{
return ((emac_phy->state == PHY_LOOPBACK) ? 1 : 0);
}
/* Wait until mdio is ready for next command */
#define MDIO_WAIT_FOR_USER_ACCESS while ((MDIO_REG_USERACCESS & MDIO_USERACCESS_GO) != 0) {}
/* Read from a phy register via mdio interface */
unsigned int emac_mdio_read(unsigned int phy_addr, unsigned int phy_reg)
{
unsigned int phy_data = 0;
unsigned int phy_control;
/* Wait until mdio is ready for next command */
MDIO_WAIT_FOR_USER_ACCESS;
phy_control = (MDIO_USERACCESS_GO |
MDIO_USERACCESS_READ |
((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
((phy_addr << 16) & MDIO_USERACCESS_PHYADR) |
(phy_data & MDIO_USERACCESS_DATA));
MDIO_REG_USERACCESS = phy_control;
/* Wait until mdio is ready for next command */
MDIO_WAIT_FOR_USER_ACCESS;
return (MDIO_REG_USERACCESS & MDIO_USERACCESS_DATA);
}
/* Write to a phy register via mdio interface */
void emac_mdio_write(unsigned int phy_addr, unsigned int phy_reg,
unsigned int phy_data)
{
unsigned int control;
/* Wait until mdio is ready for next command */
MDIO_WAIT_FOR_USER_ACCESS;
control = (MDIO_USERACCESS_GO |
MDIO_USERACCESS_WRITE |
((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
((phy_addr << 16) & MDIO_USERACCESS_PHYADR) |
(phy_data & MDIO_USERACCESS_DATA));
MDIO_REG_USERACCESS = control;
}
/* Reset the selected phy */
void emac_mdio_phy_reset(unsigned int phy_addr)
{
unsigned int control;
emac_mdio_write(phy_addr, PHY_CONTROL_REG, MII_PHY_RESET);
do {
control = emac_mdio_read(phy_addr, PHY_CONTROL_REG);
} while (control & MII_PHY_RESET);
/* CRITICAL: Fix for increasing PHY signal drive strength for
* TX lockup issue. On DaVinci EVM, the Intel LXT971 PHY
* signal strength was low causing TX to fail randomly. The
* fix is to Set bit 11 (Increased MII drive strength) of PHY
* register 26 (Digital Config register) on this phy. */
control = emac_mdio_read(phy_addr, 26);
emac_mdio_write(phy_addr, 26, (control | 0x800));
control = emac_mdio_read(phy_addr, 26);
}
/* Timeout condition handler in PHY state machine */
void emac_mdio_phy_timeout(void)
{
emac_phy->state = PHY_FOUND;
emac_phy->state_change = 1;
/* If MDI/MDIX is supported then switch MDIX state */
}
/* PHY state machine : Init state handler */
void emac_mdio_init_state(void)
{
emac_phy->state = PHY_FINDING;
emac_phy->state_change = 1;
emac_phy->timeout = PHY_FIND_TIMEOUT;
}
/* PHY state machine : Finding state handler */
void emac_mdio_finding_state(void)
{
unsigned int phy_alive_status;
int i, j;
emac_phy->phy_addr = PHY_NOT_FOUND;
/* Find if timeout complete */
if (emac_phy->timeout) {
/* Allow some time for phy to show up in alive register */
--emac_phy->timeout;
} else {
phy_alive_status = MDIO_REG_LINK;
/* Check phys based upon user mask */
phy_alive_status &= emac_phy->phy_mask;
/* Find the first interesting alive phy */
for (i = 0, j = 1;
(i < 32) && ((j & phy_alive_status) == 0); i++, j <<= 1) ;
if ((phy_alive_status) && (i < 32)) {
emac_phy->phy_addr = i;
}
if (emac_phy->phy_addr != PHY_NOT_FOUND) {
DPRINTK("PHY Found. Phy Number=%d\n",
emac_phy->phy_addr);
emac_phy->state = PHY_FOUND;
emac_phy->state_change = 1;
} else {
/* Set Timer for finding timeout */
DPRINTK("PHY NOT Found. Starting timeout\n");
emac_phy->timeout = PHY_RECK_TIMEOUT;
}
}
}
/* PHY state machine : Found state handler */
void emac_mdio_found_state(void)
{
unsigned int phy_status;
unsigned int phy_num;
unsigned int cnt;
unsigned int nway_advertise;
/* Check if there is any phy mode requested by the user */
if (emac_phy->phy_mode == 0) {
return;
}
/* Check alive phy's */
phy_status = MDIO_REG_LINK;
phy_status &= emac_phy->phy_mask; /* Check phys based upon user mask */
/* we will now isolate all our phys, except the one we have decided to use */
for (phy_num = 0, cnt = 1; phy_num < 32; phy_num++, cnt <<= 1) {
if (phy_status & cnt) {
if (phy_num != emac_phy->phy_addr) {
/* Disable a phy that we are not using */
/* CRITICAL: Note that this code assums that there is only 1 phy connected
* if this is not the case then the next statement should be commented
*/
emac_mdio_write(emac_phy->phy_addr,
PHY_CONTROL_REG,
(MII_PHY_ISOLATE |
MII_PHY_PDOWN));
}
}
}
/* Reset the Phy and proceed with auto-negotiation */
emac_mdio_phy_reset(emac_phy->phy_addr);
/* Set the way Link will be Monitored, Check the Link Selection Method */
if ((1 << emac_phy->phy_addr) & emac_phy->mlink_mask) {
MDIO_REG_USERPHYSEL =
(emac_phy->phy_addr | MDIO_USERPHYSEL_LINKSEL);
}
/* For Phy Internal loopback , need to wait until Phy found */
if (emac_phy->phy_mode & NWAY_LPBK) {
/* Set Phy in Loopback and read mdio to confirm */
emac_mdio_write(emac_phy->phy_addr, PHY_CONTROL_REG,
(MII_PHY_LOOP | MII_PHY_FD));
emac_mdio_read(emac_phy->phy_addr, PHY_STATUS_REG);
emac_phy->state = PHY_LOOPBACK;
emac_phy->state_change = 1;
return;
}
/* Start negotiation */
nway_advertise = MII_NWAY_SEL;
if (emac_phy->phy_mode & NWAY_FD100)
nway_advertise |= MII_NWAY_FD100;
if (emac_phy->phy_mode & NWAY_HD100)
nway_advertise |= MII_NWAY_HD100;
if (emac_phy->phy_mode & NWAY_FD10)
nway_advertise |= MII_NWAY_FD10;
if (emac_phy->phy_mode & NWAY_HD10)
nway_advertise |= MII_NWAY_HD10;
phy_status = emac_mdio_read(emac_phy->phy_addr, PHY_STATUS_REG);
if ((phy_status & MII_NWAY_CAPABLE) && (emac_phy->phy_mode & NWAY_AUTO)) {
/* NWAY Phy Detected - following procedure for NWAY compliant Phys */
emac_mdio_write(emac_phy->phy_addr, NWAY_ADVERTIZE_REG,
nway_advertise);
if (emac_phy->debug_mode) {
DPRINTK("NWAY Advertising: ");
if (nway_advertise & MII_NWAY_FD100)
DPRINTK("100 Mbps FullDuplex");
if (nway_advertise & MII_NWAY_HD100)
DPRINTK("100 Mbps HalfDuplex");
if (nway_advertise & MII_NWAY_FD10)
DPRINTK("10 Mbps FullDuplex");
if (nway_advertise & MII_NWAY_HD10)
DPRINTK("10 Mbps HalfDuplex");
DPRINTK("\n");
}
/* Start/Restart autonegotiation */
emac_mdio_write(emac_phy->phy_addr, PHY_CONTROL_REG,
MII_AUTO_NEGOTIATE_EN);
emac_mdio_write(emac_phy->phy_addr, PHY_CONTROL_REG,
(MII_AUTO_NEGOTIATE_EN | MII_RENEGOTIATE));
emac_phy->state = PHY_NWAY_START;
emac_phy->state_change = 1;
emac_phy->timeout = PHY_NWST_TIMEOUT;
} else {
/* Phy cannot do auto negotiation */
emac_phy->phy_mode &= ~NWAY_AUTO;
nway_advertise &= ~MII_NWAY_SEL;
phy_status = 0;
if (nway_advertise & (MII_NWAY_FD100 | MII_NWAY_HD100)) {
phy_status = MII_PHY_100; /* Set 100 Mbps if requested */
nway_advertise &= (MII_NWAY_FD100 | MII_NWAY_HD100);
} else {
nway_advertise &= (MII_NWAY_FD10 | MII_NWAY_HD10);
}
if (nway_advertise & (MII_NWAY_FD100 | MII_NWAY_FD10)) {
phy_status |= MII_PHY_FD; /* Set Full duplex if requested */
}
/* Set requested speed and duplex mode on phy */
emac_mdio_write(emac_phy->phy_addr, PHY_CONTROL_REG,
phy_status);
/* Set the phy speed and duplex mode */
emac_phy->speed = (phy_status & MII_PHY_100) ? 100 : 10;
emac_phy->duplex = (phy_status & MII_PHY_FD) ? 3 : 2;
emac_phy->state = PHY_LINK_WAIT;
emac_phy->state_change = 1;
emac_phy->timeout = PHY_LINK_TIMEOUT;
}
/* TODO: When Auto MDIX is supported, add delay here
emac_mdio_mdix_delay();
*/
}
/* PHY state machine : NWAY Start state handler */
void emac_mdio_nwaystart_state(void)
{
unsigned int status;
status = emac_mdio_read(emac_phy->phy_addr, PHY_CONTROL_REG);
if ((status & MII_RENEGOTIATE) == 0) {
/* Flush pending latched bits */
status = emac_mdio_read(emac_phy->phy_addr, PHY_STATUS_REG);
emac_phy->state = PHY_NWAY_WAIT;
emac_phy->state_change = 1;
emac_phy->timeout = PHY_NWDN_TIMEOUT;
} else {
if (emac_phy->timeout) {
--emac_phy->timeout;
} else {
/* Timed Out for NWAY to start - very unlikely condition, back to Found */
emac_mdio_phy_timeout();
}
}
}
/* PHY state machine : NWAY Wait state handler */
void emac_mdio_nwaywait_state(void)
{
unsigned int status;
unsigned int my_cap, partner_cap, neg_mode;
/* Check if nway negotiation complete */
status = emac_mdio_read(emac_phy->phy_addr, PHY_STATUS_REG);
if (status & MII_NWAY_COMPLETE) {
/* negotiation complete, check for partner capabilities */
emac_phy->state_change = 1;
my_cap = emac_mdio_read(emac_phy->phy_addr, NWAY_ADVERTIZE_REG);
partner_cap =
emac_mdio_read(emac_phy->phy_addr, NWAY_REMADVERTISE_REG);
/* Negotiated mode is what we and partnet have in common */
neg_mode = my_cap & partner_cap;
if (emac_phy->debug_mode) {
DPRINTK
("Phy %d, neg_mode %04X, my_cap %04X, partner_cap %04X\n",
emac_phy->phy_addr, neg_mode, my_cap, partner_cap);
}
/* Limit negotiation to fields below */
neg_mode &=
(MII_NWAY_FD100 | MII_NWAY_HD100 | MII_NWAY_FD10 |
MII_NWAY_HD10);
if (neg_mode == 0)
DPRINTK
("WARNING: Negotiation complete but NO agreement, default is 10HD\n");
if (neg_mode & MII_NWAY_FD100)
DPRINTK("100 Mbps FullDuplex");
if (neg_mode & MII_NWAY_HD100)
DPRINTK("100 Mbps HalfDuplex");
if (neg_mode & MII_NWAY_FD10)
DPRINTK("10 Mbps FullDuplex");
if (neg_mode & MII_NWAY_HD10)
DPRINTK("10 Mbps HalfDuplex");
DPRINTK("\n");
if (neg_mode != 0) {
if (status & MII_PHY_LINKED) {
emac_phy->state = PHY_LINKED;
} else {
emac_phy->state = PHY_LINK_WAIT;
}
}
/* Set the phy speed and duplex mode */
emac_phy->speed =
(neg_mode & (MII_NWAY_FD100 | MII_NWAY_HD100)) ? 100 : 10;
emac_phy->duplex =
(neg_mode & (MII_NWAY_FD100 | MII_NWAY_FD10)) ? 3 : 2;
} else {
if (emac_phy->timeout) {
--emac_phy->timeout;
} else {
/* Timed Out for NWAY to start - very unlikely condition, back to Found */
emac_mdio_phy_timeout();
}
}
}
/* PHY state machine : Link Wait state handler */
void emac_mdio_linkwait_state(void)
{
unsigned int status;
/* Check if nway negotiation complete */
status = emac_mdio_read(emac_phy->phy_addr, PHY_STATUS_REG);
if (status & MII_PHY_LINKED) {
emac_phy->state = PHY_LINKED;
emac_phy->state_change = 1;
} else {
if (emac_phy->timeout) {
--emac_phy->timeout;
} else {
/* Timed Out for link - very unlikely condition, back to Found */
emac_mdio_phy_timeout();
}
}
}
/* PHY state machine : Linked handler */
void emac_mdio_linked_state(void)
{
if (MDIO_REG_LINK & (1 << emac_phy->phy_addr)) {
return; /* do nothing if already linked */
}
/* If not linked, move mode to nway down or waiting for link */
emac_phy->state_change = 1;
if (emac_phy->phy_mode & NWAY_AUTO) {
emac_phy->state = PHY_NWAY_WAIT;
emac_phy->timeout = PHY_NWDN_TIMEOUT;
} else {
emac_phy->state = PHY_LINK_WAIT;
emac_phy->timeout = PHY_LINK_TIMEOUT;
}
/* TODO: When Auto MDIX is supported, add delay here
emac_mdio_mdix_delay();
*/
}
/* PHY state machine : Loopback handler */
void emac_mdio_loopback_state(void)
{
return;
}
/* PHY state machine : Default handler */
void emac_mdio_default_state(void)
{
/* Awaiting a init call */
emac_phy->state_change = 1;
}
/* Detailed PHY dump for debug */
void emac_mdio_phy_dump(void)
{
unsigned int status;
DPRINTK("\n");
DPRINTK("PHY Addr/Num=%d, PHY State=%s, Speed=%d, Duplex=%d\n",
emac_phy->phy_addr, phy_state_str[emac_phy->state],
emac_phy->speed, emac_phy->duplex);
/* 0: Control register */
status = emac_mdio_read(emac_phy->phy_addr, PHY_CONTROL_REG);
DPRINTK("PhyControl: %04X, Loopback=%s, Speed=%s, Duplex=%s\n",
status,
status & MII_PHY_LOOP ? "On" : "Off",
status & MII_PHY_100 ? "100" : "10",
status & MII_PHY_FD ? "Full" : "Half");
/* 1: Status register */
status = emac_mdio_read(emac_phy->phy_addr, PHY_STATUS_REG);
DPRINTK("PhyStatus: %04X, AutoNeg=%s, Link=%s\n",
status,
status & MII_NWAY_COMPLETE ? "Complete" : "NotComplete",
status & MII_PHY_LINKED ? "Up" : "Down");
/* 4: Auto Negotiation Advertisement register */
status = emac_mdio_read(emac_phy->phy_addr, NWAY_ADVERTIZE_REG);
DPRINTK("PhyMyCapability: %04X, 100FD=%s, 100HD=%s, 10FD=%s, 10HD=%s\n",
status,
status & MII_NWAY_FD100 ? "Yes" : "No",
status & MII_NWAY_HD100 ? "Yes" : "No",
status & MII_NWAY_FD10 ? "Yes" : "No",
status & MII_NWAY_HD10 ? "Yes" : "No");
/* 5: Auto Negotiation Advertisement register */
status = emac_mdio_read(emac_phy->phy_addr, NWAY_REMADVERTISE_REG);
DPRINTK
("PhyPartnerCapability: %04X, 100FD=%s, 100HD=%s, 10FD=%s, 10HD=%s\n",
status, status & MII_NWAY_FD100 ? "Yes" : "No",
status & MII_NWAY_HD100 ? "Yes" : "No",
status & MII_NWAY_FD10 ? "Yes" : "No",
status & MII_NWAY_HD10 ? "Yes" : "No");
}
/* emac_mdio_tick is called every 10 mili seconds to process Phy states */
int emac_mdio_tick(void)
{
switch (emac_phy->state) {
case PHY_INIT:
emac_mdio_init_state();
break;
case PHY_FINDING:
emac_mdio_finding_state();
break;
case PHY_FOUND:
emac_mdio_found_state();
break;
case PHY_NWAY_START:
emac_mdio_nwaystart_state();
break;
case PHY_NWAY_WAIT:
emac_mdio_nwaywait_state();
break;
case PHY_LINK_WAIT:
emac_mdio_linkwait_state();
break;
case PHY_LINKED:
emac_mdio_linked_state();
break;
case PHY_LOOPBACK:
emac_mdio_loopback_state();
break;
default:
emac_mdio_default_state();
break;
}
/* Check is MDI/MDIX mode switch is needed - not supported in DaVinci hardware */
/* Return state change to user */
if (emac_phy->state_change) {
emac_mdio_phy_dump();
emac_phy->state_change = 0;
return (1);
} else {
return (0);
}
}
/*
* linux/drivers/net/davinci_emac_phy.h
*
* MDIO Polling State Machine API. Functions will enable mii-Phy
* negotiation.
*
* Copyright (C) 2006 Texas Instruments.
*
* ----------------------------------------------------------------------------
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* ----------------------------------------------------------------------------
* Modifications:
* HISTORY:
* Date Modifier Ver Notes
* 27Mar02 Michael Hanrahan Original (modified from emacmdio.h)
* 04Apr02 Michael Hanrahan Added Interrupt Support * 01Jan01 Denis, Bill Original
*/
#ifndef _DAVINCI_EMAC_PHY_H_
#define _DAVINCI_EMAC_PHY_H_
/* phy mode values */
#define NWAY_AUTOMDIX (1<<16)
#define NWAY_FD1000 (1<<13)
#define NWAY_HD1000 (1<<12)
#define NWAY_NOPHY (1<<10)
#define NWAY_LPBK (1<<9)
#define NWAY_FD100 (1<<8)
#define NWAY_HD100 (1<<7)
#define NWAY_FD10 (1<<6)
#define NWAY_HD10 (1<<5)
#define NWAY_AUTO (1<<0)
/*
* Tic() return values
*/
#define _MIIMDIO_MDIXFLIP (1<<28)
#define _AUTOMDIX_DELAY_MIN 80 /* milli-seconds */
#define _AUTOMDIX_DELAY_MAX 200 /* milli-seconds */
/* Get module version */
void emac_mdio_get_ver(unsigned int mdio_base, unsigned int *module_id,
unsigned int *rev_major, unsigned int *rev_minor);
/* Initialize mdio module */
int emac_mdio_init(unsigned int mdio_base,
unsigned int inst,
unsigned int phy_mask,
unsigned int mlink_mask,
unsigned int mdio_bus_freq,
unsigned int mdio_clock_freq, unsigned int verbose);
/* Set PHY mode - autonegotiation or any other */
void emac_mdio_set_phy_mode(unsigned int phy_mode);
/* Get linked status - check if link is on - 1=link on, 0=link off */
int emac_mdio_is_linked(void);
/* Get speed - 10 / 100 Mbps */
int emac_mdio_get_speed(void);
/* Get duplex - 2=full duplex, 1=half duplex */
int emac_mdio_get_duplex(void);
/* Get Phy number/address */
int emac_mdio_get_phy_num(void);
/* Check if loopback enabled on phy */
int emac_mdio_is_loopback(void);
/* Read from a phy register via mdio interface */
unsigned int emac_mdio_read(unsigned int phy_addr, unsigned int phy_reg);
/* Write to a phy register via mdio interface */
void emac_mdio_write(unsigned int phy_addr, unsigned int phy_reg,
unsigned int phy_data);
/* MDIO tick function - to be called every 10 mSecs */
int emac_mdio_tick(void);
#endif /* _DAVINIC_EMAC_PHY_H_ */
/* linux/include/asm-arm/arch-davinci/debug-macro.S
*
* Debugging macro include header
*
* 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.
*
*/
.macro addruart, rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
moveq \rx, #0x01c00000 @ physical base address
movne \rx, #0xe1000000 @ virtual base
orr \rx, \rx, #0x00020000 @ UART 0
.endm
.macro senduart,rd,rx
strb \rd, [\rx]
.endm
.macro busyuart,rd,rx
1001: ldrb \rd, [\rx, #(0x5 << 2)]
and \rd, \rd, #0x60
teq \rd, #0x60
bne 1001b
.endm
.macro waituart,rd,rx
.endm
/*
* linux/include/asm-arm/arch-davinci/dma.h
*
* BRIEF MODULE DESCRIPTION
* DAVINCI DMA Info
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H
#include <asm/arch/hardware.h>
#include <asm/arch/edma.h>
#define MAX_DMA_ADDRESS 0xffffffff
#endif /* __ASM_ARCH_DMA_H */
/*
* linux/include/asm-arm/arch-davinci/edma.h
*
* BRIEF MODULE DESCRIPTION
* TI DAVINCI dma definitions
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/******************************************************************************
* DMA driver for DaVinci
* DMA driver for Davinci abstractes each ParamEntry as a Logical DMA channel
* for the user.So on Davinci the user can request 128 DAM channels
*
* Actual Physical DMA channels = 64 EDMA channels + 8 QDMA channels
*
* On davinci user can request for two kinds of Logical DMA channels
* DMA MasterChannel -> ParamEntry which is associated with a DMA channel.
* On Davinci there are (64 + 8) MasterChanneles
* MasterChannel can be triggered by an event or manually
*
* DMA SlaveChannel -> ParamEntry which is not associated with DMA cahnnel but
* which can be used to associate with MasterChannel.
* On Davinci there are (128-(64 + 8)) SlaveChannels
* SlaveChannel can only be triggered by a MasterChannel
*
*/
#ifndef EDMA_H_
#define EDMA_H_
/*Used by driver*/
/**************************************************************************\
* Register Overlay Structure for DRA
\**************************************************************************/
typedef struct {
unsigned int drae;
unsigned int draeh;
} edmacc_dra_regs;
/**************************************************************************\
* Register Overlay Structure for QUEEVTENTRY
\**************************************************************************/
typedef struct {
unsigned int evt_entry;
} edmacc_que_evtentry_regs;
/**************************************************************************\
* Register Overlay Structure for SHADOW
\**************************************************************************/
typedef struct {
unsigned int er;
unsigned int erh;
unsigned int ecr;
unsigned int ecrh;
unsigned int esr;
unsigned int esrh;
unsigned int cer;
unsigned int cerh;
unsigned int eer;
unsigned int eerh;
unsigned int eecr;
unsigned int eecrh;
unsigned int eesr;
unsigned int eesrh;
unsigned int ser;
unsigned int serh;
unsigned int secr;
unsigned int secrh;
unsigned char rsvd0[8];
unsigned int ier;
unsigned int ierh;
unsigned int iecr;
unsigned int iecrh;
unsigned int iesr;
unsigned int iesrh;
unsigned int ipr;
unsigned int iprh;
unsigned int icr;
unsigned int icrh;
unsigned int ieval;
unsigned char rsvd1[4];
unsigned int qer;
unsigned int qeer;
unsigned int qeecr;
unsigned int qeesr;
unsigned int qser;
unsigned int qsecr;
unsigned char rsvd2[360];
} edmacc_shadow_regs;
/**************************************************************************\
* Register Overlay Structure for PARAMENTRY
\**************************************************************************/
typedef struct {
unsigned int opt;
unsigned int src;
unsigned int a_b_cnt;
unsigned int dst;
unsigned int src_dst_bidx;
unsigned int link_bcntrld;
unsigned int src_dst_cidx;
unsigned int ccnt;
} edmacc_paramentry_regs;
/**************************************************************************\
* Register Overlay Structure
\**************************************************************************/
typedef struct {
unsigned int rev;
unsigned int cccfg;
unsigned char rsvd0[504];
unsigned int qchmap[8];
unsigned char rsvd1[32];
unsigned int dmaqnum[8];
unsigned int qdmaqnum;
unsigned char rsvd2[28];
unsigned int quetcmap;
unsigned int quepri;
unsigned char rsvd3[120];
unsigned int emr;
unsigned int emrh;
unsigned int emcr;
unsigned int emcrh;
unsigned int qemr;
unsigned int qemcr;
unsigned int ccerr;
unsigned int ccerrclr;
unsigned int eeval;
unsigned char rsvd4[28];
edmacc_dra_regs dra[4];
unsigned char rsvd5[32];
unsigned int qrae[4];
unsigned char rsvd6[112];
edmacc_que_evtentry_regs queevtentry[2][16];
unsigned char rsvd7[384];
unsigned int qstat[2];
unsigned char rsvd8[24];
unsigned int qwmthra;
unsigned int qwmthrb;
unsigned char rsvd9[24];
unsigned int ccstat;
unsigned char rsvd10[188];
unsigned int aetctl;
unsigned int aetstat;
unsigned int aetcmd;
unsigned char rsvd11[2292];
unsigned int er;
unsigned int erh;
unsigned int ecr;
unsigned int ecrh;
unsigned int esr;
unsigned int esrh;
unsigned int cer;
unsigned int cerh;
unsigned int eer;
unsigned int eerh;
unsigned int eecr;
unsigned int eecrh;
unsigned int eesr;
unsigned int eesrh;
unsigned int ser;
unsigned int serh;
unsigned int secr;
unsigned int secrh;
unsigned char rsvd12[8];
unsigned int ier;
unsigned int ierh;
unsigned int iecr;
unsigned int iecrh;
unsigned int iesr;
unsigned int iesrh;
unsigned int ipr;
unsigned int iprh;
unsigned int icr;
unsigned int icrh;
unsigned int ieval;
unsigned char rsvd13[4];
unsigned int qer;
unsigned int qeer;
unsigned int qeecr;
unsigned int qeesr;
unsigned int qser;
unsigned int qsecr;
unsigned char rsvd14[3944];
edmacc_shadow_regs shadow[4];
unsigned char rsvd15[6144];
edmacc_paramentry_regs paramentry[128];
} edmacc_regs;
#define CCINT0_INTERRUPT 16
#define CCERRINT_INTERRUPT 17
#define TCERRINT0_INTERRUPT 18
#define TCERRINT1_INTERRUPT 19
#define SAM (1)
#define DAM (1<<1)
#define SYNCDIM (1<<2)
#define STATIC (1<<3)
#define EDMA_FWID (0x7<<8)
#define TCCMODE (0x1<<11)
#define TCC (0x3f<<12)
#define WIMODE (0x1<<19)
#define TCINTEN (0x1<<20)
#define ITCINTEN (0x1<<21)
#define TCCHEN (0x1<<22)
#define ITCCHEN (0x1<<23)
#define SECURE (0x1<<30)
#define PRIV (0x1<<31)
#define TRWORD (0x7<<2)
#define PAENTRY (0x1ff<<5)
/*if changing the QDMA_TRWORD do appropriate change in davinci_start_dma */
#define QDMA_TRWORD (7 & 0x7)
/*Used by driver*/
#define DAVINCI_EDMA_NUM_DMACH 64
#define DAVINCI_EDMA_NUM_QDMACH 8
#define DAVINCI_EDMA_NUM_PARAMENTRY 128
#define DAVINCI_EDMA_NUM_EVQUE 2
#define DAVINCI_EDMA_CHMAPEXIST 0
#define DAVINCI_EDMA_NUM_REGIONS 4
#define DAVINCI_EDMA_MEMPROTECT 0
#define DAVINCI_NUM_UNUSEDCH 21
#define TCC_ANY -1
#define DAVINCI_EDMA_PARAM_ANY -2
#define DAVINCI_DMA_CHANNEL_ANY -1
#define DAVINCI_DMA_MCBSP_TX 2
#define DAVINCI_DMA_MCBSP_RX 3
#define DAVINCI_DMA_VPSS_HIST 4
#define DAVINCI_DMA_VPSS_H3A 5
#define DAVINCI_DMA_VPSS_PRVU 6
#define DAVINCI_DMA_VPSS_RSZ 7
#define DAVINCI_DMA_IMCOP_IMXINT 8
#define DAVINCI_DMA_IMCOP_VLCDINT 9
#define DAVINCI_DMA_IMCO_PASQINT 10
#define DAVINCI_DMA_IMCOP_DSQINT 11
#define DAVINCI_DMA_SPI_SPIX 16
#define DAVINCI_DMA_SPI_SPIR 17
#define DAVINCI_DMA_UART0_URXEVT0 18
#define DAVINCI_DMA_UART0_UTXEVT0 19
#define DAVINCI_DMA_UART1_URXEVT1 20
#define DAVINCI_DMA_UART1_UTXEVT1 21
#define DAVINCI_DMA_UART2_URXEVT2 22
#define DAVINCI_DMA_UART2_UTXEVT2 23
#define DAVINCI_DMA_MEMSTK_MSEVT 24
#define DAVINCI_DMA_MMCRXEVT 26
#define DAVINCI_DMA_MMCTXEVT 27
#define DAVINCI_DMA_I2C_ICREVT 28
#define DAVINCI_DMA_I2C_ICXEVT 29
#define DAVINCI_DMA_GPIO_GPINT0 32
#define DAVINCI_DMA_GPIO_GPINT1 33
#define DAVINCI_DMA_GPIO_GPINT2 34
#define DAVINCI_DMA_GPIO_GPINT3 35
#define DAVINCI_DMA_GPIO_GPINT4 36
#define DAVINCI_DMA_GPIO_GPINT5 37
#define DAVINCI_DMA_GPIO_GPINT6 38
#define DAVINCI_DMA_GPIO_GPINT7 39
#define DAVINCI_DMA_GPIO_GPBNKINT0 40
#define DAVINCI_DMA_GPIO_GPBNKINT1 41
#define DAVINCI_DMA_GPIO_GPBNKINT2 42
#define DAVINCI_DMA_GPIO_GPBNKINT3 43
#define DAVINCI_DMA_GPIO_GPBNKINT4 44
#define DAVINCI_DMA_TIMER0_TINT0 48
#define DAVINCI_DMA_TIMER1_TINT1 49
#define DAVINCI_DMA_TIMER2_TINT2 50
#define DAVINCI_DMA_TIMER3_TINT3 51
#define DAVINCI_DMA_PWM0 52
#define DAVINCI_DMA_PWM1 53
#define DAVINCI_DMA_PWM2 54
#define DAVINCI_DMA_QDMA0 64
#define DAVINCI_DMA_QDMA1 65
#define DAVINCI_DMA_QDMA2 66
#define DAVINCI_DMA_QDMA3 67
#define DAVINCI_DMA_QDMA4 68
#define DAVINCI_DMA_QDMA5 69
#define DAVINCI_DMA_QDMA6 71
#define DAVINCI_DMA_QDMA7 72
/*ch_status paramater of callback function possible values*/
#define DMA_COMPLETE 1
#define DMA_CC_ERROR 2
#define DMA_TC1_ERROR 3
#define DMA_TC2_ERROR 4
enum address_mode {
INCR = 0,
FIFO = 1
};
enum fifo_width {
W8BIT = 0,
W16BIT = 1,
W32BIT = 2,
W64BIT = 3,
W128BIT = 4,
W256BIT = 5
};
enum dma_event_q {
EVENTQ_0 = 0,
EVENTQ_1 = 1,
EVENTQ_DEFAULT = -1
};
enum sync_dimension {
ASYNC = 0,
ABSYNC = 1
};
/******************************************************************************
* davinci_request_dma - request for the Davinci DMA channel
*
* dev_id - DMA channel number
*
* EX: DAVINCI_DMA_MCBSP_TX - For requesting a DMA MasterChannel with MCBSP_TX
* event association
*
* DAVINCI_DMA_ANY - For requesting a DMA Masterchannel which does not has
* event association
*
* DAVINCI_DMA_LINK - for requesting a DMA SlaveChannel
*
* dev_name - name of the dma channel in human readable format
* callback - channel callback function (valied only if you are requesting
* for a DMA MasterChannel)
* data - private data for the channel to be requested
* lch - contains the device id allocated
* tcc - specifies the channel number on which the interrupt is
* generated
* Valied for QDMA and PARAM channes
* eventq_no - Event Queue no to which the channel will be associated with
* (valied only if you are requesting for a DMA MasterChannel)
* Values : EVENTQ_0/EVENTQ_1 for event queue 0/1.
* EVENTQ_DEFAULT for Default queue
*
* Return: zero on success,
* -EINVAL - if the requested channel is not supported on the ARM side events
* -EBUSY - if the requested channel is already in use
* EREQDMA - if failed to request the dma channel
*
*****************************************************************************/
int davinci_request_dma(int dev_id,
const char *dev_name,
void (*callback) (int lch, unsigned short ch_status,
void *data), void *data, int *lch,
int *tcc, enum dma_event_q
);
/******************************************************************************
* davinci_set_dma_src_params - DMA source parameters setup
*
* lch - channel for which the source parameters to be configured
* src_port - Source port address
* addressMode - indicates whether the address mode is FIFO or not
* fifoWidth - valied only if addressMode is FIFO, indicates the vidth of
* FIFO
* 0 - 8 bit
* 1 - 16 bit
* 2 - 32 bit
* 3 - 64 bit
* 4 - 128 bit
* 5 - 256 bit
*****************************************************************************/
void davinci_set_dma_src_params(int lch, unsigned long src_port,
enum address_mode mode, enum fifo_width);
/******************************************************************************
* davinci_set_dma_dest_params - DMA destination parameters setup
*
* lch - channel or param device for destination parameters to be
* configured
* dest_port - Destination port address
* addressMode - indicates whether the address mode is FIFO or not
* fifoWidth - valied only if addressMode is FIFO,indicates the vidth of FIFO
* 0 - 8 bit
* 1 - 16 bit
* 2 - 32 bit
* 3 - 64 bit
* 4 - 128 bit
* 5 - 256 bit
*
*****************************************************************************/
void davinci_set_dma_dest_params(int lch, unsigned long dest_port,
enum address_mode mode, enum fifo_width);
/******************************************************************************
* davinci_set_dma_src_index - DMA source index setup
*
* lch - channel or param device for configuration of source index
* srcbidx - source B-register index
* srccidx - source C-register index
*
*****************************************************************************/
void davinci_set_dma_src_index(int lch, short srcbidx, short srccidx);
/******************************************************************************
* davinci_set_dma_dest_index - DMA destination index setup
*
* lch - channel or param device for configuration of destination index
* destbidx - dest B-register index
* destcidx - dest C-register index
*
*****************************************************************************/
void davinci_set_dma_dest_index(int lch, short destbidx, short destcidx);
/******************************************************************************
* davinci_set_dma_transfer_params - DMA transfer parameters setup
*
* lch - channel or param device for configuration of aCount, bCount and
* cCount regs.
* aCnt - aCnt register value to be configured
* bCnt - bCnt register value to be configured
* cCnt - cCnt register value to be configured
*
*****************************************************************************/
void davinci_set_dma_transfer_params(int lch, unsigned short acnt,
unsigned short bcnt, unsigned short ccnt,
unsigned short bcntrld,
enum sync_dimension sync_mode);
/******************************************************************************
*
* davinci_set_dma_params -
* ARGUMENTS:
* lch - logical channel number
*
*****************************************************************************/
void davinci_set_dma_params(int lch, edmacc_paramentry_regs * temp);
/******************************************************************************
*
* davinci_get_dma_params -
* ARGUMENTS:
* lch - logical channel number
*
*****************************************************************************/
void davinci_get_dma_params(int lch, edmacc_paramentry_regs * temp);
/******************************************************************************
* davinci_start_dma - Starts the dma on the channel passed
*
* lch - logical channel number
*
* Note: This API can be used only on DMA MasterChannel
*
* Return: zero on success
* -EINVAL on failure, i.e if requested for the slave channels
*
*****************************************************************************/
int davinci_start_dma(int lch);
/******************************************************************************
* davinci_stop_dma - Stops the dma on the channel passed
*
* lch - logical channel number
*
* Note: This API can be used on MasterChannel and SlaveChannel
*****************************************************************************/
void davinci_stop_dma(int lch);
/******************************************************************************
* davinci_dma_link_lch - Link two Logical channels
*
* lch_head - logical channel number, in which the link field is linked to the
* the param pointed to by lch_queue
* Can be a MasterChannel or SlaveChannel
* lch_queue - logical channel number or the param entry number, which is to be
* linked to the lch_head
* Must be a SlaveChannel
*
* |---------------|
* v |
* Ex: ch1--> ch2-->ch3-->ch4--|
*
* ch1 must be a MasterChannel
*
* ch2, ch3, ch4 must be SlaveChannels
*
* Note: After channel linking,the user should not update any PaRam entry
* of MasterChannel ( In the above example ch1 )
*
*****************************************************************************/
void davinci_dma_link_lch(int lch_head, int lch_queue);
/******************************************************************************
* davinci_dma_unlink_lch - unlink the two logical channels passed through by
* setting the link field of head to 0xffff.
*
* lch_head - logical channel number, from which the link field is to be
* removed
* lch_queue - logical channel number or the param entry number,which is to be
* unlinked from lch_head
*
*****************************************************************************/
void davinci_dma_unlink_lch(int lch_head, int lch_queue);
/******************************************************************************
*
* DMA channel chain - chains the two logical channels passed through by
* ARGUMENTS:
* lch_head - logical channel number, from which the link field is to be removed
* lch_queue - logical channel number or the param entry number, which is to be
* unlinked from lch_head
*
*****************************************************************************/
void davinci_dma_chain_lch(int lch_head, int lch_queue);
/******************************************************************************
*
* DMA channel unchain - unchain the two logical channels passed through by
* ARGUMENTS:
* lch_head - logical channel number, from which the link field is to be removed
* lch_queue - logical channel number or the param entry number, which is to be
* unlinked from lch_head
*
*****************************************************************************/
void davinci_dma_unchain_lch(int lch_head, int lch_queue);
/******************************************************************************
*
* Free DMA channel - Free the dma channel number passed
*
* ARGUMENTS:
* lch - dma channel number to get free
*
*****************************************************************************/
void davinci_free_dma(int lch);
#endif
/*
* include/asm-arm/arch-davinci/entry-macro.S
*
* Low-level IRQ helper macros for TI DaVinci-based platforms
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
.macro disable_fiq
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
/* GIVEN:
* IRQ Entry Table Base Address
* RETURN:
* irqnr: Interrupt number. Zero corresponds
* to bit 0 of the status register
* irqstat, base, and tmp may be considered
* as scratch registers
* Z conditions means no outstanding interrupt
*/
ldr \base, =IO_ADDRESS(DAVINCI_ARM_INTC_BASE)
ldr \tmp, [\base, #0x14]
ldr \irqstat, =DAVINCI_IRAM_VIRT
add \tmp, \irqstat, \tmp
ldr \irqnr, [\tmp]
ldr \irqstat, =0xFFFFFFFF
cmp \irqnr, \irqstat
.endm
.macro irq_prio_table
.endm
/*
* linux/include/asm-arm/arch-davinci/hardware.h
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
/**************************************************************************
* Included Files
**************************************************************************/
#include <linux/config.h>
#include <asm/sizes.h>
#include <asm/memory.h>
#include <asm/arch/io.h>
/*
* Base register addresses
*/
#define DAVINCI_DMA_3PCC_BASE (0x01C00000)
#define DAVINCI_DMA_3PTC0_BASE (0x01C10000)
#define DAVINCI_DMA_3PTC1_BASE (0x01C10400)
#define DAVINCI_UART0_BASE (0x01C20000)
#define DAVINCI_UART1_BASE (0x01C20400)
#define DAVINCI_UART2_BASE (0x01C20800)
#define DAVINCI_I2C_BASE (0x01C21000)
#define DAVINCI_TIMER0_BASE (0x01C21400)
#define DAVINCI_TIMER1_BASE (0x01C21800)
#define DAVINCI_WDOG_BASE (0x01C21C00)
#define DAVINCI_PWM0_BASE (0x01C22000)
#define DAVINCI_PWM1_BASE (0x01C22400)
#define DAVINCI_PWM2_BASE (0x01C22800)
#define DAVINCI_SYSTEM_MODULE_BASE (0x01C40000)
#define DAVINCI_PLL_CNTRL0_BASE (0x01C40800)
#define DAVINCI_PLL_CNTRL1_BASE (0x01C40C00)
#define DAVINCI_PWR_SLEEP_CNTRL_BASE (0x01C41000)
#define DAVINCI_SYSTEM_DFT_BASE (0x01C42000)
#define DAVINCI_ARM_INTC_BASE (0x01C48000)
#define DAVINCI_IEEE1394_BASE (0x01C60000)
#define DAVINCI_USB_OTG_BASE (0x01C64000)
#define DAVINCI_CFC_ATA_BASE (0x01C66000)
#define DAVINCI_SPI_BASE (0x01C66800)
#define DAVINCI_GPIO_BASE (0x01C67000)
#define DAVINCI_UHPI_BASE (0x01C67800)
#define DAVINCI_VPSS_REGS_BASE (0x01C70000)
#define DAVINCI_EMAC_CNTRL_REGS_BASE (0x01C80000)
#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE (0x01C81000)
#define DAVINCI_EMAC_WRAPPER_RAM_BASE (0x01C82000)
#define DAVINCI_MDIO_CNTRL_REGS_BASE (0x01C84000)
#define DAVINCI_IMCOP_BASE (0x01CC0000)
#define DAVINCI_ASYNC_EMIF_CNTRL_BASE (0x01E00000)
#define DAVINCI_VLYNQ_BASE (0x01E01000)
#define DAVINCI_MCBSP_BASE (0x01E02000)
#define DAVINCI_MMC_SD_BASE (0x01E10000)
#define DAVINCI_MS_BASE (0x01E20000)
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x02000000)
#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE (0x04000000)
#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x06000000)
#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x08000000)
#define DAVINCI_VLYNQ_REMOTE_BASE (0x0C000000)
/* Power and Sleep Controller (PSC) Domains */
#define DAVINCI_GPSC_ARMDOMAIN 0
#define DAVINCI_GPSC_DSPDOMAIN 1
#define DAVINCI_LPSC_VPSSMSTR 0 // VPSS Master LPSC
#define DAVINCI_LPSC_VPSSSLV 1 // VPSS Slave LPSC
#define DAVINCI_LPSC_TPCC 2 // TPCC LPSC
#define DAVINCI_LPSC_TPTC0 3 // TPTC0 LPSC
#define DAVINCI_LPSC_TPTC1 4 // TPTC1 LPSC
#define DAVINCI_LPSC_EMAC 5 // EMAC LPSC
#define DAVINCI_LPSC_EMAC_WRAPPER 6 // EMAC WRAPPER LPSC
#define DAVINCI_LPSC_MDIO 7 // MDIO LPSC
#define DAVINCI_LPSC_IEEE1394 8 // IEEE1394 LPSC
#define DAVINCI_LPSC_USB 9 // USB LPSC
#define DAVINCI_LPSC_ATA 10 // ATA LPSC
#define DAVINCI_LPSC_VLYNQ 11 // VLYNQ LPSC
#define DAVINCI_LPSC_UHPI 12 // UHPI LPSC
#define DAVINCI_LPSC_DDR_EMIF 13 // DDR_EMIF LPSC
#define DAVINCI_LPSC_AEMIF 14 // AEMIF LPSC
#define DAVINCI_LPSC_MMC_SD 15 // MMC_SD LPSC
#define DAVINCI_LPSC_MEMSTICK 16 // MEMSTICK LPSC
#define DAVINCI_LPSC_McBSP 17 // McBSP LPSC
#define DAVINCI_LPSC_I2C 18 // I2C LPSC
#define DAVINCI_LPSC_UART0 19 // UART0 LPSC
#define DAVINCI_LPSC_UART1 20 // UART1 LPSC
#define DAVINCI_LPSC_UART2 21 // UART2 LPSC
#define DAVINCI_LPSC_SPI 22 // SPI LPSC
#define DAVINCI_LPSC_PWM0 23 // PWM0 LPSC
#define DAVINCI_LPSC_PWM1 24 // PWM1 LPSC
#define DAVINCI_LPSC_PWM2 25 // PWM2 LPSC
#define DAVINCI_LPSC_GPIO 26 // GPIO LPSC
#define DAVINCI_LPSC_TIMER0 27 // TIMER0 LPSC
#define DAVINCI_LPSC_TIMER1 28 // TIMER1 LPSC
#define DAVINCI_LPSC_TIMER2 29 // TIMER2 LPSC
#define DAVINCI_LPSC_SYSTEM_SUBSYS 30 // SYSTEM SUBSYSTEM LPSC
#define DAVINCI_LPSC_ARM 31 // ARM LPSC
#define DAVINCI_LPSC_SCR2 32 // SCR2 LPSC
#define DAVINCI_LPSC_SCR3 33 // SCR3 LPSC
#define DAVINCI_LPSC_SCR4 34 // SCR4 LPSC
#define DAVINCI_LPSC_CROSSBAR 35 // CROSSBAR LPSC
#define DAVINCI_LPSC_CFG27 36 // CFG27 LPSC
#define DAVINCI_LPSC_CFG3 37 // CFG3 LPSC
#define DAVINCI_LPSC_CFG5 38 // CFG5 LPSC
#define DAVINCI_LPSC_GEM 39 // GEM LPSC
#define DAVINCI_LPSC_IMCOP 40 // IMCOP LPSC
#endif /* __ASM_ARCH_HARDWARE_H */
/*
* include/asm-arm/arch-omap/hrtime.h
*
* HRT hooks for the TI DaVinci
*
* Author: MontaVista, Software, Inc. <source@mvista.com>
*
* 2003-2004 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef __ASM_ARCH_HRTIME_H_
#define __ASM_ARCH_HRTIME_H_
#include <linux/timex.h>
#define SC_ARCH2NSEC 25 /* int(log2(2 * CLOCK_TICK_RATE - 1)) */
#define SC_NSEC2ARCH 32
#define scaled_nsec_per_arch_cycle \
(SC_n(SC_ARCH2NSEC, NSEC_PER_SEC) / CLOCK_TICK_RATE)
#define scaled_arch_cycles_per_nsec \
(SC_n(SC_NSEC2ARCH, CLOCK_TICK_RATE) / NSEC_PER_SEC)
#define arch_cycle_to_nsec(cycles) \
mpy_sc_n(SC_ARCH2NSEC, (cycles), scaled_nsec_per_arch_cycle)
#define nsec_to_arch_cycle(nsec) \
mpy_sc_n(SC_NSEC2ARCH, (nsec), scaled_arch_cycles_per_nsec)
#ifdef CONFIG_HIGH_RES_TIMERS
int schedule_hr_timer_int(unsigned long, int);
int get_arch_cycles(unsigned long);
#define hrtimer_use 1
#define hr_time_resolution 1000 /* (NSEC_PER_SEC / CLOCK_TICK_RATE) */
#define arch_cycles_per_jiffy (long)(CLOCK_TICK_RATE / HZ)
#define schedule_jiffies_int(x) (get_arch_cycles(x) >= arch_cycles_per_jiffy)
#endif /* CONFIG_HIGH_RES_TIMERS */
#endif /* __ASM_ARCH_HRTIME_H_ */
/*
* include/asm-arm/arch-davinci/i2c-client.h
*
* Copyright (C) 2006 Texas Instruments Inc
*
* 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
*/
/* i2c-client.h */
typedef enum {
USB_DRVVBUS = 0,
VDDIMX_EN = 1,
VLYNQ_ON = 2,
CF_RESET = 3,
WLAN_RESET = 4,
ATA_SEL = 5,
CF_SEL = 6
} u35_expander_ops;
int davinci_i2c_expander_op (u16 client_addr, u35_expander_ops pin, u8 val);
int davinci_i2c_write(u8 size, u8 * val, u16 client_addr);
int davinci_i2c_read(u8 size, u8 * val, u16 client_addr);
/*
* linux/include/asm-arm/arch-davinci/io.h
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
#define IO_SPACE_LIMIT 0xffffffff
/*
* ----------------------------------------------------------------------------
* I/O mapping
* ----------------------------------------------------------------------------
*/
#define IO_PHYS 0x01c00000
#define IO_VIRT 0xe1000000
#define IO_SIZE 0x00400000
#define io_p2v(pa) (((pa) & (IO_SIZE-1)) + IO_VIRT)
#define io_v2p(va) (((va) & (IO_SIZE-1)) + IO_PHYS)
#define IO_ADDRESS(x) io_p2v(x)
#define __REG(x) (*((volatile unsigned long *)io_p2v(x)))
/*
* We don't actually have real ISA nor PCI buses, but there is so many
* drivers out there that might just work if we fake them...
*/
#define PCIO_BASE 0
#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
#define __mem_pci(a) (a)
#define __mem_isa(a) (a)
#endif /* __ASM_ARCH_IO_H */
/*
* linux/include/asm-arm/arch-davinci/irq.h
*
* BRIEF MODULE DESCRIPTION
* DAVINCI Virtual irq definitions
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ASM_ARCH_IRQ_H
#define __ASM_ARCH_IRQ_H
/**************************************************************************
* Included Files
**************************************************************************/
/**************************************************************************
* Global Function Prototypes
**************************************************************************/
typedef struct intc_registers_t {
unsigned int fiq0; /* 0x0 */
unsigned int fiq1; /* 0x4 */
unsigned int irq0; /* 0x8 */
unsigned int irq1; /* 0xC */
unsigned int fiqentry; /* 0x10 */
unsigned int irqentry; /* 0x14 */
unsigned int eint0; /* 0x18 */
unsigned int eint1; /* 0x1C */
unsigned int inctl; /* 0x20 */
unsigned int eabase; /* 0x24 */
unsigned int resv1; /* 0x28 */
unsigned int resv2; /* 0x2C */
unsigned int intpri0; /* 0x30 */
unsigned int intpri1; /* 0x34 */
unsigned int intpri2; /* 0x38 */
unsigned int intpri3; /* 0x3C */
unsigned int intpri4; /* 0x30 */
unsigned int intpri5; /* 0x34 */
unsigned int intpri6; /* 0x38 */
unsigned int intpri7; /* 0x3C */
} intc_registers;
/****************************************************
* DaVinci Interrupt numbers
****************************************************/
#endif /* __ASM_ARCH_IRQ_H */
/*
* linux/include/asm-arm/arch-davinci/irqs.h
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H
/**************************************************************************
* Included Files
**************************************************************************/
/**************************************************************************
* Definitions
**************************************************************************/
#define IRQ_VDINT0 0
#define IRQ_VDINT1 1
#define IRQ_VDINT2 2
#define IRQ_HISTINT 3
#define IRQ_H3AINT 4
#define IRQ_PRVUINT 5
#define IRQ_RSZINT 6
#define IRQ_VFOCINT 7
#define IRQ_VENCINT 8
#define IRQ_ASQINT 9
#define IRQ_IMXINT 10
#define IRQ_VLCDINT 11
#define IRQ_USBINT 12
#define IRQ_EMACINT 13
#define IRQ_IEEE1394INT 14
#define IRQ_IEEE1394WK 15
#define IRQ_CCINT0 16
#define IRQ_CCERRINT 17
#define IRQ_TCERRINT0 18
#define IRQ_TCERRINT 19
#define IRQ_PSCIN 20
#define IRQ_RESERVED 21
#define IRQ_IDE 22
#define IRQ_HPIINT 23
#define IRQ_MBXINT 24
#define IRQ_MBRINT 25
#define IRQ_MMCINT 26
#define IRQ_SDIOINT 27
#define IRQ_MSINT 28
#define IRQ_DDRINT 29
#define IRQ_AEMIFINT 30
#define IRQ_VLQINT 31
#define IRQ_TINT0_TINT12 32
#define IRQ_TINT0_TINT34 33
#define IRQ_TINT1_TINT12 34
#define IRQ_TINT1_TINT34 35
#define IRQ_PWMINT0 36
#define IRQ_PWMINT1 37
#define IRQ_PWMINT2 38
#define IRQ_I2C 39
#define IRQ_UARTINT0 40
#define IRQ_UARTINT1 41
#define IRQ_UARTINT2 42
#define IRQ_SPINT0 43
#define IRQ_SPINT1 44
#define IRQ_RESERVED_2 45
#define IRQ_DSP2ARM0 46
#define IRQ_DSP2ARM1 47
#define IRQ_GPIO0 48
#define IRQ_GPIO1 49
#define IRQ_GPIO2 50
#define IRQ_GPIO3 51
#define IRQ_GPIO4 52
#define IRQ_GPIO5 53
#define IRQ_GPIO6 54
#define IRQ_GPIO7 55
#define IRQ_GPIOBNK0 56
#define IRQ_GPIOBNK1 57
#define IRQ_GPIOBNK2 58
#define IRQ_GPIOBNK3 59
#define IRQ_GPIOBNK4 60
#define IRQ_COMMTX 61
#define IRQ_COMMRX 62
#define IRQ_EMUINT 63
#define DAVINCI_MAXIRQNUM 63
#define NR_IRQS (DAVINCI_MAXIRQNUM + 1)
#define DAVINCI_MAXSWINUM DAVINCI_MAXIRQNUM
#define DAVINCI_MAXFIQNUM 0
#define ARCH_TIMER_IRQ IRQ_TINT1_TINT34
#endif /* __ASM_ARCH_IRQS_H */
/*
* linux/include/asm/arch/mcbsp.h
*
* BRIEF MODULE DESCRIPTION
* DAVINCI McBSP driver Info
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ASM_ARCH_DAVINCI_MCBSP_H
#define __ASM_ARCH_DAVINCI_MCBSP_H
#include <asm/arch/hardware.h>
#include <asm/arch/irqs.h>
#define DAVINCI_MCBSP1_BASE DAVINCI_MCBSP_BASE
#define DAVINCI_DMA_MCBSP1_RX 3
#define DAVINCI_DMA_MCBSP1_TX 2
#define DAVINCI_McBSP1RX IRQ_MBRINT
#define DAVINCI_McBSP1TX IRQ_MBXINT
#define DRR1 0x00
#define DRR2 0x02
#define DXR1 0x04
#define DXR2 0x06
#define SPCR1 0x08
#define SPCR2 0x0a
#define RCR1 0x0c
#define RCR2 0x0e
#define XCR1 0x10
#define XCR2 0x12
#define SRGR1 0x14
#define SRGR2 0x16
#define MCR1 0x18
#define MCR2 0x1a
#define RCERA 0x1c
#define RCERB 0x1e
#define XCERA 0x20
#define XCERB 0x22
#define PCR0 0x24
#define PCR1 0x26
#define RCERC 0x28
#define RCERD 0x2a
#define XCERC 0x2c
#define XCERD 0x2e
#define RCERE 0x30
#define RCERF 0x32
#define XCERE 0x34
#define XCERF 0x36
#define RCERG 0x38
#define RCERH 0x3a
#define XCERG 0x3c
#define XCERH 0x3e
#define DAVINCI_MAX_MCBSP_COUNT 1
/********************** McBSP SPCR1 bit definitions ***********************/
#define RRST 0x0001
#define RRDY 0x0002
#define RFULL 0x0004
#define RSYNC_ERR 0x0008
#define RINTM(value) ((value)<<4) /* bits 4:5 */
#define ABIS 0x0040
#define DXENA 0x0080
#define CLKSTP(value) ((value)<<11) /* bits 11:12 */
#define RJUST(value) ((value)<<13) /* bits 13:14 */
#define DLB 0x8000
/********************** McBSP SPCR2 bit definitions ***********************/
#define XRST 0x0001
#define XRDY 0x0002
#define XEMPTY 0x0004
#define XSYNC_ERR 0x0008
#define XINTM(value) ((value)<<4) /* bits 4:5 */
#define GRST 0x0040
#define FRST 0x0080
#define SOFT 0x0100
#define FREE 0x0200
/********************** McBSP PCR bit definitions *************************/
#define CLKRP 0x0001
#define CLKXP 0x0002
#define FSRP 0x0004
#define FSXP 0x0008
#define DR_STAT 0x0010
#define DX_STAT 0x0020
#define CLKS_STAT 0x0040
#define SCLKME 0x0080
#define CLKRM 0x0100
#define CLKXM 0x0200
#define FSRM 0x0400
#define FSXM 0x0800
#define RIOEN 0x1000
#define XIOEN 0x2000
#define IDLE_EN 0x4000
/********************** McBSP RCR1 bit definitions ************************/
#define RWDLEN1(value) ((value)<<5) /* Bits 5:7 */
#define RFRLEN1(value) ((value)<<8) /* Bits 8:14 */
/********************** McBSP XCR1 bit definitions ************************/
#define XWDLEN1(value) ((value)<<5) /* Bits 5:7 */
#define XFRLEN1(value) ((value)<<8) /* Bits 8:14 */
/*********************** McBSP RCR2 bit definitions ***********************/
#define RDATDLY(value) (value) /* Bits 0:1 */
#define RFIG 0x0004
#define RCOMPAND(value) ((value)<<3) /* Bits 3:4 */
#define RWDLEN2(value) ((value)<<5) /* Bits 5:7 */
#define RFRLEN2(value) ((value)<<8) /* Bits 8:14 */
#define RPHASE 0x8000
/*********************** McBSP XCR2 bit definitions ***********************/
#define XDATDLY(value) (value) /* Bits 0:1 */
#define XFIG 0x0004
#define XCOMPAND(value) ((value)<<3) /* Bits 3:4 */
#define XWDLEN2(value) ((value)<<5) /* Bits 5:7 */
#define XFRLEN2(value) ((value)<<8) /* Bits 8:14 */
#define XPHASE 0x8000
/********************* McBSP SRGR1 bit definitions ************************/
#define CLKGDV(value) (value) /* Bits 0:7 */
#define FWID(value) ((value)<<8) /* Bits 8:15 */
/********************* McBSP SRGR2 bit definitions ************************/
#define FPER(value) (value) /* Bits 0:11 */
#define FSGM 0x1000
#define CLKSM 0x2000
#define CLKSP 0x4000
#define GSYNC 0x8000
/********************* McBSP MCR1 bit definitions *************************/
#define RMCM 0x0001
#define RCBLK(value) ((value)<<2) /* Bits 2:4 */
#define RPABLK(value) ((value)<<5) /* Bits 5:6 */
#define RPBBLK(value) ((value)<<7) /* Bits 7:8 */
/********************* McBSP MCR2 bit definitions *************************/
#define XMCM(value) (value) /* Bits 0:1 */
#define XCBLK(value) ((value)<<2) /* Bits 2:4 */
#define XPABLK(value) ((value)<<5) /* Bits 5:6 */
#define XPBBLK(value) ((value)<<7) /* Bits 7:8 */
/* we don't do multichannel for now */
struct davinci_mcbsp_reg_cfg {
u16 spcr2;
u16 spcr1;
u16 rcr2;
u16 rcr1;
u16 xcr2;
u16 xcr1;
u16 srgr2;
u16 srgr1;
u16 mcr2;
u16 mcr1;
u16 pcr2;
u16 pcr0;
u16 rcerc;
u16 rcerd;
u16 xcerc;
u16 xcerd;
u16 rcere;
u16 rcerf;
u16 xcere;
u16 xcerf;
u16 rcerg;
u16 rcerh;
u16 xcerg;
u16 xcerh;
};
typedef enum {
DAVINCI_MCBSP1 = 0,
} davinci_mcbsp_id;
typedef enum {
DAVINCI_MCBSP_WORD_8 = 0,
DAVINCI_MCBSP_WORD_12,
DAVINCI_MCBSP_WORD_16,
DAVINCI_MCBSP_WORD_20,
DAVINCI_MCBSP_WORD_24,
DAVINCI_MCBSP_WORD_32,
} davinci_mcbsp_word_length;
typedef enum {
DAVINCI_MCBSP_CLK_RISING = 0,
DAVINCI_MCBSP_CLK_FALLING,
} davinci_mcbsp_clk_polarity;
typedef enum {
DAVINCI_MCBSP_FS_ACTIVE_HIGH = 0,
DAVINCI_MCBSP_FS_ACTIVE_LOW,
} davinci_mcbsp_fs_polarity;
typedef enum {
DAVINCI_MCBSP_CLK_STP_MODE_NO_DELAY = 0,
DAVINCI_MCBSP_CLK_STP_MODE_DELAY,
} davinci_mcbsp_clk_stp_mode;
/******* SPI specific mode **********/
typedef enum {
DAVINCI_MCBSP_SPI_MASTER = 0,
DAVINCI_MCBSP_SPI_SLAVE,
} davinci_mcbsp_spi_mode;
struct davinci_mcbsp_spi_cfg {
davinci_mcbsp_spi_mode spi_mode;
davinci_mcbsp_clk_polarity rx_clock_polarity;
davinci_mcbsp_clk_polarity tx_clock_polarity;
davinci_mcbsp_fs_polarity fsx_polarity;
u8 clk_div;
davinci_mcbsp_clk_stp_mode clk_stp_mode;
davinci_mcbsp_word_length word_length;
};
void davinci_mcbsp_config(unsigned int id,
const struct davinci_mcbsp_reg_cfg *config);
int davinci_mcbsp_request(unsigned int id);
void davinci_mcbsp_free(unsigned int id);
void davinci_mcbsp_start(unsigned int id);
void davinci_mcbsp_stop(unsigned int id);
void davinci_mcbsp_xmit_word(unsigned int id, u32 word);
u32 davinci_mcbsp_recv_word(unsigned int id);
int davinci_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
unsigned int length);
int davinci_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
unsigned int length);
/* SPI specific API */
void davinci_mcbsp_set_spi_mode(unsigned int id,
const struct davinci_mcbsp_spi_cfg *spi_cfg);
#endif
/*
* linux/include/asm-arm/arch-davinci/memory.h
*
* BRIEF MODULE DESCRIPTION
* DAVINCI Virtual memory definitions
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
/**************************************************************************
* Included Files
**************************************************************************/
#include <linux/config.h>
#include <asm/page.h>
#include <asm/sizes.h>
#include <asm/arch/hardware.h>
/**************************************************************************
* Definitions
**************************************************************************/
#define DAVINCI_DDR_BASE 0x80000000
#define DAVINCI_IRAM_BASE 0x00008000 /* ARM Internal RAM (Data) */
#define DAVINCI_IRAM_VIRT 0xe1400000 /* after 4M of IO space (io.h) */
/* Linux Memory Pool */
/* The start of physical memory available to the kernel. This value
* is used in the arch-specific bootup code like setup_arch &
* bootmem_init. This may or may not be the start of physical memory;
* There may be memory reserved "in front" of the kernel for other
* purposes.
*/
#define PHYS_OFFSET DAVINCI_DDR_BASE
/*
* Increase size of DMA-consistent memory region
*/
#define CONSISTENT_DMA_SIZE (14<<20)
#ifndef __ASSEMBLY__
/*
* Restrict DMA-able region to workaround silicon bug. The bug
* restricts buffers available for DMA to video hardware to be
* below 128M
*/
static inline void
__arch_adjust_zones(int node, unsigned long *size, unsigned long *holes)
{
unsigned int sz = (128<<20) >> PAGE_SHIFT;
if (node != 0)
sz = 0;
size[1] = size[0] - sz;
size[0] = sz;
}
#define arch_adjust_zones(node, zone_size, holes) \
if ((meminfo.bank[0].size >> 20) > 128) __arch_adjust_zones(node, zone_size, holes)
#define ISA_DMA_THRESHOLD (PHYS_OFFSET + (128<<20) - 1)
#endif
/*
* Bus address is physical address
*/
#define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt(x) __phys_to_virt(x)
#endif /* __ASM_ARCH_MEMORY_H */
/*
* linux/include/asm-arm/arch-davinci/param.h
*
* BRIEF MODULE DESCRIPTION
* DAVINCI Virtual memofy definitions
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
* linux/include/asm-arm/arch-davinci/preempt.h
*
* BRIEF MODULE DESCRIPTION
* DAVINCI Virtual preempt definitions
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ASM_ARCH_PREEMPT_H
#define __ASM_ARCH_PREEMPT_H
/*
* DaVinci timers run at clk_ref = 27MHz
*/
#define TICKS_PER_USEC 27
#endif /* __ASM_ARCH_PREEMPT_H */
/*
* linux/include/asm-arm/arch-davinci/system.h
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H
/**************************************************************************
* Included Files
**************************************************************************/
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/arch/timex.h>
/**************************************************************************
* Global Functions
**************************************************************************/
static void arch_idle(void)
{
if (!hlt_counter) {
unsigned long flags;
local_irq_save(flags);
if (!need_resched())
cpu_do_idle();
local_irq_restore(flags);
}
}
static void arch_reset(char mode)
{
davinci_watchdog_reset();
}
#endif /* __ASM_ARCH_SYSTEM_H */
/*
* linux/include/asm-arm/arch-davinci/timex.h
*
* BRIEF MODULE DESCRIPTION
* DAVINCI Virtual memofy definitions
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef __ASM_ARCH_TIMEX_H
#define __ASM_ARCH_TIMEX_H
/* The source frequency for the timers is the 27MHz MXI clock */
#define CLOCK_TICK_RATE 27000000
extern void davinci_watchdog_reset(void);
#endif /* __ASM_ARCH_TIMEX_H__ */
/*
* linux/include/asm-arm/arch-davinci/uncompress.h
*
* Serial port stubs for kernel decompress status messages
*
* Author: Anant Gole
* (C) Copyright (C) 2006, Texas Instruments, Inc
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <asm/arch/hardware.h>
typedef struct uart_registers_t {
unsigned int rbr_thr;
unsigned int ier;
unsigned int iir_fcr;
unsigned int lcr;
unsigned int mcr;
unsigned int lsr;
unsigned int msr;
unsigned int scr;
unsigned int dll;
unsigned int dlh;
unsigned int pid1;
unsigned int pid2;
unsigned int pwremu;
} uart_registers;
/* Initialize Serial port - This code is written to initialize UART0 only */
static void do_nothing(void)
{
unsigned int counter;
for (counter = 0; counter < 0x200; counter++) {
/* Do nothing */
}
}
/* Wait (busy loop) untill TX FIFO is empty and a character
* can be transmitted */
static void serial_waitfortxcharcomplete(void)
{
volatile uart_registers *uartregs;
uartregs = (volatile uart_registers *) DAVINCI_UART0_BASE;
do_nothing();
while (!uartregs->lsr & 0x20) {
/* Do Nothing */
}
}
static void putc(const char c)
{
volatile uart_registers *uartregs;
uartregs = (volatile uart_registers *) DAVINCI_UART0_BASE;
if (c == '\n')
putc('\r');
uartregs->rbr_thr = c;
serial_waitfortxcharcomplete();
}
static inline void flush(void)
{
}
#define arch_decomp_setup()
#define arch_decomp_wdog()
/*
* linux/include/asm-arm/arch-davinci/vmalloc.h
*
* BRIEF MODULE DESCRIPTION
* DAVINCI vmalloc definitions
*
* Copyright (C) 2006 Texas Instruments.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <asm/arch/memory.h>
/*
* Just any arbitrary offset to the start of the vmalloc VM area: the
* current 8MB value just means that there will be a 8MB "hole" after the
* physical memory until the kernel virtual memory starts. That means that
* any out-of-bounds memory accesses will hopefully be caught.
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
* area for the same reason. ;)
*/
#define VMALLOC_OFFSET (8*1024*1024)
#define VMALLOC_START \
(((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
/* Allow vmalloc range until the IO virtual range minus a "hole" */
#define VMALLOC_END (IO_VIRT - VMALLOC_OFFSET)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment