diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX index caabbd3..28227cc 100644 --- a/Documentation/fb/00-INDEX +++ b/Documentation/fb/00-INDEX @@ -43,6 +43,8 @@ sa1100fb.txt - information about the driver for the SA-1100 LCD controller. sisfb.txt - info on the framebuffer device driver for various SiS chips. +splash.txt + - info on the Framebuffer Splash sstfb.txt - info on the frame buffer driver for 3dfx' Voodoo Graphics boards. tgafb.txt diff --git a/Documentation/fb/splash.txt b/Documentation/fb/splash.txt new file mode 100644 index 0000000..6b281c9 --- /dev/null +++ b/Documentation/fb/splash.txt @@ -0,0 +1,207 @@ +What is it? +----------- + +The framebuffer splash is a kernel feature that allows displaying a background +picture on selected consoles. + +What do I need to get it to work? +--------------------------------- + +To get fb splash up-and-running you will have to: + 1) get a copy of splashutils [1] or a similar program + 2) get some splash themes + 3) build the kernel helper program + 4) build your kernel with the FB_SPLASH option enabled. + +To get fbsplash operational right after fbcon initialization is finished, you +will have to include a theme and the kernel helper into your initramfs image. +Please refer to splashutils documentation for instructions on how to do that. + +[1] The splashutils package can be downloaded from: + http://dev.gentoo.org/~spock/projects/splashutils/ + +The userspace helper +-------------------- + +The userspace splash helper (by default: /sbin/splash_helper) is called by the +kernel whenever an important event occurs and the kernel needs some kind of +job to be carried out. Important events include console switches and video +mode switches (the kernel requests background images and configuration +parameters for the current console). The splash helper must be accessible at +all times. If it's not, fbsplash will be switched off automatically. + +It's possible to set path to the splash helper by writing it to +/proc/sys/kernel/fbsplash. + +***************************************************************************** + +The information below is mostly technical stuff. There's probably no need to +read it unless you plan to develop a userspace helper. + +The splash protocol +------------------- + +The splash protocol defines a communication interface between the kernel and +the userspace splash helper. + +The kernel side is responsible for: + + * rendering console text, using an image as a background (instead of a + standard solid color fbcon uses), + * accepting commands from the user via ioctls on the fbsplash device, + * calling the userspace helper to set things up as soon as the fb subsystem + is initialized. + +The userspace helper is responsible for everything else, including parsing +configuration files, decompressing the image files whenever the kernel needs +it, and communicating with the kernel if necessary. + +The splash protocol specifies how communication is done in both ways: +kernel->userspace and userspace->helper. + +Kernel -> Userspace +------------------- + +The kernel communicates with the userspace helper by calling it and specifying +the task to be done in a series of arguments. + +The arguments follow the pattern: + + +All commands defined in splash protocol v2 have the following parameters: + virtual console + framebuffer number + theme + +Splash protocol v1 specified an additional 'fbsplash mode' after the +framebuffer number. Splash protocol v1 is deprecated and should not be used. + +Splash protocol v2 specifies the following commands: + +getpic +------ + The kernel issues this command to request image data. It's up to the + userspace helper to find a background image appropriate for the specified + theme and the current resolution. The userspace helper should respond by + issuing the FBIOSPLASH_SETPIC ioctl. + +init +---- + The kernel issues this command after the fbsplash device is created and + the fbsplash interface is initialized. Upon receiving 'init', the userspace + helper should parse the kernel command line (/proc/cmdline) or otherwise + decide whether fbsplash is to be activated. + + To activate fbsplash on the first console the helper should issue the + FBIOSPLASH_SETCFG, FBIOSPLASH_SETPIC and FBIOSPLASH_SETSTATE commands, + in the above-mentioned order. + + When the userspace helper is called in an early phase of the boot process + (right after the initialization of fbcon), no filesystems will be mounted. + The helper program should mount sysfs and then create the appropriate + framebuffer, fbsplash and tty0 devices (if they don't already exist) to get + current display settings and to be able to communicate with the kernel side. + It should probably also mount the procfs to be able to parse the kernel + command line parameters. + + Note that the console sem is not held when the kernel calls splash_helper + with the 'init' command. The splash helper should perform all ioctls with + origin set to FB_SPLASH_IO_ORIG_USER. + +modechange +---------- + The kernel issues this command on a mode change. The helper's response should + be similar to the response to the 'init' command. Note that this time the + console sem is held and all ioctls must be performed with origin set to + FB_SPLASH_IO_ORIG_KERNEL. + + +Userspace -> Kernel +------------------- + +Userspace programs can communicate with fbsplash via ioctls on the fbsplash +device. These ioctls are to be used by both the userspace helper (called +only by the kernel) and userspace configuration tools (run by the users). + +The splash helper should set the origin field to FB_SPLASH_IO_ORIG_KERNEL +when doing the appropriate ioctls. All userspace configuration tools should +use FB_SPLASH_IO_ORIG_USER. Failure to set the appropriate value in the origin +field when performing ioctls from the kernel helper will most likely result +in a console deadlock. + +FB_SPLASH_IO_ORIG_KERNEL instructs fbsplash not to try to acquire the console +semaphore. Not surprisingly, FB_SPLASH_IO_ORIG_USER instructs it to acquire +the console sem. + +The framebuffer splash provides the following ioctls (all defined in +linux/fb.h): + +FBIOSPLASH_SETPIC +description: loads a background picture for a virtual console +argument: struct fb_splash_iowrapper*; data: struct fb_image* +notes: +If called for consoles other than the current foreground one, the picture data +will be ignored. + +If the current virtual console is running in a 8-bpp mode, the cmap substruct +of fb_image has to be filled appropriately: start should be set to 16 (first +16 colors are reserved for fbcon), len to a value <= 240 and red, green and +blue should point to valid cmap data. The transp field is ingored. The fields +dx, dy, bg_color, fg_color in fb_image are ignored as well. + +FBIOSPLASH_SETCFG +description: sets the fbsplash config for a virtual console +argument: struct fb_splash_iowrapper*; data: struct vc_splash* +notes: The structure has to be filled with valid data. + +FBIOSPLASH_GETCFG +description: gets the fbsplash config for a virtual console +argument: struct fb_splash_iowrapper*; data: struct vc_splash* + +FBIOSPLASH_SETSTATE +description: sets the fbsplash state for a virtual console +argument: struct fb_splash_iowrapper*; data: unsigned int* + values: 0 = disabled, 1 = enabled. + +FBIOSPLASH_GETSTATE +description: gets the fbsplash state for a virtual console +argument: struct fb_splash_iowrapper*; data: unsigned int* + values: as in FBIOSPLASH_SETSTATE + +Info on used structures: + +Definition of struct vc_splash can be found in linux/console_splash.h. It's +heavily commented. Note that the 'theme' field should point to a string +no longer than FB_SPLASH_THEME_LEN. When FBIOSPLASH_GETCFG call is +performed, the theme field should point to a char buffer of length +FB_SPLASH_THEME_LEN. + +Definition of struct fb_splash_iowrapper can be found in linux/fb.h. +The fields in this struct have the following meaning: + +vc: +Virtual console number. + +origin: +Specifies if the ioctl is performed as a response to a kernel request. The +splash helper should set this field to FB_SPLASH_IO_ORIG_KERNEL, userspace +programs should set it to FB_SPLASH_IO_ORIG_USER. This field is necessary to +avoid console semaphore deadlocks. + +data: +Pointer to a data structure appropriate for the performed ioctl. Type of +the data struct is specified in the ioctls description. + +***************************************************************************** + +Credit +------ + +Original 'bootsplash' project & implementation by: + Volker Poplawski , Stefan Reinauer , + Steffen Winterfeldt , Michael Schroeder , + Ken Wimer . + +Fbsplash, splash protocol design, current implementation & docs by: + Michal Januszewski + diff --git a/Makefile b/Makefile index b5f52f3..4ea8373 100644 --- a/Makefile +++ b/Makefile @@ -189,9 +189,10 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ # Alternatively CROSS_COMPILE can be set in the environment. # Default value for CROSS_COMPILE is not to prefix executables # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile + export KBUILD_BUILDHOST := $(SUBARCH) -ARCH ?= $(SUBARCH) -CROSS_COMPILE ?= +ARCH ?= mips +CROSS_COMPILE ?= # Architecture as present in compile.h UTS_MACHINE := $(ARCH) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1e06d23..5059abe 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -6,7 +6,7 @@ config MIPS select HAVE_ARCH_KGDB # Horrible source of confusion. Die, die, die ... select EMBEDDED - select RTC_LIB + select RTC_LIB if !MACH_LM2F mainmenu "Linux/MIPS Kernel Configuration" @@ -181,6 +181,9 @@ config LEMOTE_FULONG Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and an FPGA northbridge +config MACH_LM2F + bool "Lemote LOONGSON2F based machines" + config MIPS_MALTA bool "MIPS Malta board" select ARCH_MAY_HAVE_PC_FDC @@ -607,6 +610,7 @@ source "arch/mips/sgi-ip27/Kconfig" source "arch/mips/sibyte/Kconfig" source "arch/mips/txx9/Kconfig" source "arch/mips/vr41xx/Kconfig" +source "arch/mips/lemote/lm2f/Kconfig" endmenu @@ -954,7 +958,7 @@ config CPU_LOONGSON2 select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM help - The Loongson 2E processor implements the MIPS III instruction set + The Loongson 2E/2F processor implements the MIPS III instruction set with many extensions. config CPU_MIPS32_R1 @@ -2015,6 +2019,9 @@ endmenu menu "Power management options" +config ARCH_HIBERNATION_POSSIBLE + def_bool y + config ARCH_SUSPEND_POSSIBLE def_bool y depends on !SMP @@ -2023,6 +2030,23 @@ source "kernel/power/Kconfig" endmenu +menu "CPU Frequency scaling" + +source "drivers/cpufreq/Kconfig" + +config LS2F_CPU_FREQ + tristate "Loongson-2F CPU Frequency driver" + depends on CPU_LOONGSON2 && CPU_FREQ + select CPU_FREQ_TABLE + help + This adds the cpufreq driver for Loongson-2F. + + For details, take a look at . + + If unsure, say N. + +endmenu + source "net/Kconfig" source "drivers/Kconfig" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9aab51c..95036fd 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -305,6 +305,25 @@ load-$(CONFIG_LEMOTE_FULONG) +=0xffffffff80100000 cflags-$(CONFIG_LEMOTE_FULONG) += -Iinclude/asm-mips/mach-lemote # +# common lemote loongson2f stuffs +# +core-$(CONFIG_MACH_LM2F) +=arch/mips/lemote/lm2f/common/ + +# +# lemote loongson2f fulong mini-PC board +# +core-$(CONFIG_LEMOTE_FULONG2F) +=arch/mips/lemote/lm2f/lmbox/ +load-$(CONFIG_LEMOTE_FULONG2F) +=0xffffffff80200000 +cflags-$(CONFIG_LEMOTE_FULONG2F) += -Iinclude/asm-mips/mach-lemote + +# +# lemote loongson2f notebook +# +core-$(CONFIG_LEMOTE_2FNOTEBOOK) +=arch/mips/lemote/lm2f/lmbook/ +load-$(CONFIG_LEMOTE_2FNOTEBOOK) +=0xffffffff80200000 +cflags-$(CONFIG_LEMOTE_2FNOTEBOOK) += -Iinclude/asm-mips/mach-lemote + +# # MIPS Malta board # core-$(CONFIG_MIPS_MALTA) += arch/mips/mti-malta/ @@ -649,6 +668,9 @@ core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/ +#Support hibernate +drivers-$(CONFIG_PM) += arch/mips/power/ + ifdef CONFIG_LASAT rom.bin rom.sw: vmlinux $(Q)$(MAKE) $(build)=arch/mips/lasat/image $@ @@ -695,6 +717,13 @@ ifdef CONFIG_MIPS32_O32 $(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=32" endif +zboot := arch/mips/zboot +bzImage: KBUILD_IMAGE := arch/mips/zboot/bzImage + +BOOT_TARGETS = bzImage + +$(BOOT_TARGETS): vmlinux + $(Q)$(MAKE) $(build)=$(zboot) $(KBUILD_IMAGE) ZBOOT_FLAGS=$(CFLAGS) archclean: @$(MAKE) $(clean)=arch/mips/boot @$(MAKE) $(clean)=arch/mips/lasat diff --git a/arch/mips/configs/ls2f_fuloong_defconfig b/arch/mips/configs/ls2f_fuloong_defconfig new file mode 100644 index 0000000..da5d8e5 --- /dev/null +++ b/arch/mips/configs/ls2f_fuloong_defconfig @@ -0,0 +1,2274 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.27.1 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +CONFIG_MACH_LM2F=y +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set +# CONFIG_WR_PPMC is not set +CONFIG_LEMOTE_FULONG2F=y +# CONFIG_LEMOTE_2FNOTEBOOK is not set +CONFIG_CS5536_RTC_BUG=y +CONFIG_CS5536=y +# CONFIG_LEMOTE_NAS is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +# CONFIG_HOTPLUG_CPU is not set +CONFIG_I8259=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_BOOT_ELF32=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_HAVE_STD_PC_SERIAL_PORT=y + +# +# CPU selection +# +CONFIG_CPU_LOONGSON2=y +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_LOONGSON2=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +# CONFIG_PAGE_SIZE_4KB is not set +# CONFIG_PAGE_SIZE_8KB is not set +CONFIG_PAGE_SIZE_16KB=y +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +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=y +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_KEXEC=y +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=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_PCSPKR_PLATFORM=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +# CONFIG_MARKERS is not set +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set +# CONFIG_HAVE_IOREMAP_PROT is not set +# CONFIG_HAVE_KPROBES is not set +# CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_ARCH_TRACEHOOK is not set +# CONFIG_HAVE_DMA_ATTRS is not set +# CONFIG_USE_GENERIC_SMP_HELPERS is not set +# CONFIG_HAVE_CLK is not set +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y +# CONFIG_PROBE_INITRD_HEADER is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +CONFIG_ISA=y +CONFIG_MMU=y +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Power management options +# +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +# CONFIG_TCP_CONG_YEAH is not set +# CONFIG_TCP_CONG_ILLINOIS is not set +CONFIG_DEFAULT_BIC=y +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="bic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +# CONFIG_NF_CONNTRACK is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ESP=m +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +# CONFIG_IP_NF_SECURITY is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AH=m +# CONFIG_IP6_NF_MATCH_MH is not set +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m +# CONFIG_IP6_NF_SECURITY is not set + +# +# DECnet: Netfilter Configuration +# +CONFIG_DECNET_NF_GRABULATOR=m + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +# CONFIG_BRIDGE_EBT_IP6 is not set +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +# CONFIG_BRIDGE_EBT_NFLOG is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_IP_DCCP_ACKVEC=y + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_TIPC=m +CONFIG_TIPC_ADVANCED=y +CONFIG_TIPC_ZONES=3 +CONFIG_TIPC_CLUSTERS=1 +CONFIG_TIPC_NODES=255 +CONFIG_TIPC_SLAVE_NODES=0 +CONFIG_TIPC_PORTS=8191 +CONFIG_TIPC_LOG=0 +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=y +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +CONFIG_DECNET=m +# CONFIG_DECNET_ROUTER is not set +CONFIG_LLC=m +CONFIG_LLC2=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +# CONFIG_COPS is not set +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_WAN_ROUTER=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_CLS_FLOW is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +# CONFIG_NET_ACT_NAT is not set +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_YAM=m +# CONFIG_CAN is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +# CONFIG_KINGSUN_DONGLE is not set +# CONFIG_KSDAZZLE_DONGLE is not set +# CONFIG_KS959_DONGLE is not set + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +# CONFIG_BT_HCIBTUSB is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +# CONFIG_BT_HCIUART_LL is not set +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +CONFIG_FIB_RULES=y + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_MAC80211 is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_INFTL=m +CONFIG_RFD_FTL=m +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PCI=m +# CONFIG_MTD_INTEL_VR_NOR is not set +CONFIG_MTD_PLATRAM=m + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_SLRAM=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTD_BLOCK2MTD=m + +# +# Disk-On-Chip Device Drivers +# +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCECC=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +# CONFIG_MTD_ONENAND_OTP is not set +# CONFIG_MTD_ONENAND_2X_PROGRAM is not set +# CONFIG_MTD_ONENAND_SIM is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +CONFIG_LOONGSON2_PLATFROM_SUPPORT=y +CONFIG_BIOS_DRIVER=m +# CONFIG_IO_MSR_DEBUG_DRIVER is not set +CONFIG_HAVE_IDE=y +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_TIMINGS=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# 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 +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_BLK_DEV_IDEDMA_SFF=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_PCIBUS_ORDER=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set + +# +# Other IDE chipsets support +# + +# +# Note: most of these also require special kernel boot parameters +# +# CONFIG_BLK_DEV_4DRIVES is not set +# CONFIG_BLK_DEV_ALI14XX is not set +# CONFIG_BLK_DEV_DTC2278 is not set +# CONFIG_BLK_DEV_HT6560B is not set +# CONFIG_BLK_DEV_QD65XX is not set +# CONFIG_BLK_DEV_UMC8672 is not set +CONFIG_BLK_DEV_IDEDMA=y + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# 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=m +CONFIG_CHR_DEV_SCH=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_SRP_ATTRS=m +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_ATA is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_DV1394=m +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +CONFIG_IFB=m +CONFIG_DUMMY=m +CONFIG_BONDING=m +# CONFIG_MACVLAN is not set +CONFIG_EQUALIZER=m +CONFIG_TUN=m +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_DM9000 is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_TC35815 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=y +CONFIG_R8169_VLAN=y +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS 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_WAN is not set +# CONFIG_ATM_DRIVERS is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_NET_FC is not set +CONFIG_NETCONSOLE=y +# CONFIG_NETCONSOLE_DYNAMIC is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# 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=m +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYBOARD_NEWTON=m +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +# CONFIG_GAMEPORT_NS558 is not set +# CONFIG_GAMEPORT_L4 is not set +# CONFIG_GAMEPORT_EMU10K1 is not set +# CONFIG_GAMEPORT_FM801 is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +CONFIG_ROCKETPORT=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +CONFIG_MOXA_SMARTIO=m +# CONFIG_ISI is not set +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_N_HDLC=m +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +CONFIG_SX=m +# CONFIG_RIO is not set +CONFIG_STALDRV=y +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=16 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_HW_RANDOM=y +CONFIG_RTC=y +CONFIG_DTLK=m +CONFIG_R3964=m +CONFIG_APPLICOM=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +# CONFIG_I2C_ISCH is not set +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +# CONFIG_I2C_NFORCE2_S4985 is not set +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_OCORES=m +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_PARPORT_LIGHT=m +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Graphics adapter I2C/DDC channel drivers +# +CONFIG_I2C_VOODOO3=m + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_PCA_ISA=m +# CONFIG_I2C_PCA_PLATFORM is not set +CONFIG_I2C_STUB=m + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_AT24 is not set +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_MAX6875=m +# CONFIG_SENSORS_TSL2550 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 +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_ALIM7101_WDT is not set + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX2341X=m +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS 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_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_IVTV is not set +# CONFIG_VIDEO_CAFE_CCIC is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +# CONFIG_USB_GSPCA is not set +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_EM28XX=m +# CONFIG_VIDEO_EM28XX_ALSA is not set +# CONFIG_VIDEO_USBVISION is not set +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +# CONFIG_USB_W9968CF is not set +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +CONFIG_DRM=m +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=m +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +CONFIG_FB_SIS=y +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SILICONMOTION is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_CORGI is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=m +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_RTCTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_DRIVERS is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +CONFIG_SND_CS5535AUDIO=m +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HIFIER is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_MIPS is not set +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_SOC is not set +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +# CONFIG_USB_WDM 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=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IUU is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +CONFIG_USB_IDMOUSE=m +# CONFIG_USB_FTDI_ELAN is not set +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_ATM is not set +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_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_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +CONFIG_CODA_FS=m +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_CMDLINE="" + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_NULL=m +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +# CONFIG_CRYPTO_CAMELLIA is not set +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set +CONFIG_CRYPTO_KHAZAD=m +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/mips/configs/ls2f_notebook_defconfig b/arch/mips/configs/ls2f_notebook_defconfig new file mode 100644 index 0000000..e7a47d5 --- /dev/null +++ b/arch/mips/configs/ls2f_notebook_defconfig @@ -0,0 +1,1836 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.27.1 +# Fri Nov 13 10:27:01 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +CONFIG_MACH_LM2F=y +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set +# CONFIG_WR_PPMC is not set +# CONFIG_LEMOTE_FULONG2F is not set +CONFIG_LEMOTE_2FNOTEBOOK=y +CONFIG_CS5536_RTC_BUG=y +CONFIG_CS5536=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +# CONFIG_HOTPLUG_CPU is not set +CONFIG_I8259=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_BOOT_ELF32=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_HAVE_STD_PC_SERIAL_PORT=y + +# +# CPU selection +# +CONFIG_CPU_LOONGSON2=y +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_LOONGSON2=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +# CONFIG_PAGE_SIZE_4KB is not set +# CONFIG_PAGE_SIZE_8KB is not set +CONFIG_PAGE_SIZE_16KB=y +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +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=y +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_KEXEC=y +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y +CONFIG_IKCONFIG=y +# CONFIG_IKCONFIG_PROC is not set +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=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_PCSPKR_PLATFORM=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +# CONFIG_MARKERS is not set +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set +# CONFIG_HAVE_IOREMAP_PROT is not set +# CONFIG_HAVE_KPROBES is not set +# CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_ARCH_TRACEHOOK is not set +# CONFIG_HAVE_DMA_ATTRS is not set +# CONFIG_USE_GENERIC_SMP_HELPERS is not set +# CONFIG_HAVE_CLK is not set +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y +# CONFIG_PROBE_INITRD_HEADER is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +CONFIG_ISA=y +CONFIG_MMU=y +# CONFIG_PCCARD is not set +CONFIG_HOTPLUG_PCI=m +# CONFIG_HOTPLUG_PCI_FAKE is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Power management options +# +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="/dev/hda3" + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_LS2F_CPU_FREQ=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE 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=m +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +# CONFIG_NF_CONNTRACK is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ESP=m +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +# CONFIG_IP_NF_SECURITY is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# Bridge: Netfilter Configuration +# +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# 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_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_AF_RXRPC=y +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +CONFIG_FIB_RULES=y + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=m +# 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_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=m +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# 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 +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +CONFIG_LOONGSON2_PLATFROM_SUPPORT=y +CONFIG_EC_COMMON_OPERATION=y +CONFIG_EC_ROM_UPDATE_DRIVER=m +CONFIG_EC_SCI_DRIVER=m +CONFIG_LAPTOP_YEELOONG=m +CONFIG_BIOS_DRIVER=m +# CONFIG_IO_MSR_DEBUG_DRIVER is not set +CONFIG_HAVE_IDE=y +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_TIMINGS=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# 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 +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_BLK_DEV_IDEDMA_SFF=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_PCIBUS_ORDER=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set + +# +# Other IDE chipsets support +# + +# +# Note: most of these also require special kernel boot parameters +# +# CONFIG_BLK_DEV_4DRIVES is not set +# CONFIG_BLK_DEV_ALI14XX is not set +# CONFIG_BLK_DEV_DTC2278 is not set +# CONFIG_BLK_DEV_HT6560B is not set +# CONFIG_BLK_DEV_QD65XX is not set +# CONFIG_BLK_DEV_UMC8672 is not set +CONFIG_BLK_DEV_IDEDMA=y + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m + +# +# 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 +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_SRP_ATTRS=m +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_OHCI1394=m + +# +# PCILynx controller requires I2C +# +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_DV1394=m +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_I2O=m +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +# CONFIG_I2O_CONFIG is not set +# CONFIG_I2O_BUS is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +CONFIG_VETH=m +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_DM9000 is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_TC35815 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS 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_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_NET_FC is not set +CONFIG_NETCONSOLE=m +# CONFIG_NETCONSOLE_DYNAMIC is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# 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=m +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYBOARD_NEWTON=m +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_INPORT=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_VSXXXAA=m +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +CONFIG_ROCKETPORT=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +CONFIG_MOXA_SMARTIO=m +# CONFIG_ISI is not set +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_N_HDLC=m +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +CONFIG_SX=m +# CONFIG_RIO is not set +CONFIG_STALDRV=y +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=16 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_HW_RANDOM=y +CONFIG_RTC=y +CONFIG_DTLK=m +CONFIG_R3964=m +CONFIG_APPLICOM=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +CONFIG_HWMON=m +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_IBMAEM is not set +# CONFIG_SENSORS_IBMPEX is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_THERMAL=m +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +# CONFIG_SSB_B43_PCI_BRIDGE is not set +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_DRIVER_MIPS is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_STRADIS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_GSPCA is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER 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_ZC0301 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +CONFIG_DRM=m +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_R128 is not set +# CONFIG_DRM_RADEON is not set +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +CONFIG_FB_SILICONMOTION=y +CONFIG_FB_SM7XX=y +CONFIG_FB_SM7XX_ACCEL=y +# CONFIG_FB_SM7XX_DUALHEAD is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_CORGI is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=m +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_RTCTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_MPU401_UART=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +# CONFIG_SND_AC97_POWER_SAVE is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +CONFIG_SND_CS5535AUDIO=m +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HIFIER is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_VIA82XX=m +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_MIPS is not set +# CONFIG_SND_USB is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m +# CONFIG_USB_WDM 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=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +CONFIG_USB_TEST=m +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="utf8" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +# CONFIG_ECRYPT_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +CONFIG_VXFS_FS=m +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +CONFIG_ROMFS_FS=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_NCP_FS=m +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +# CONFIG_NLS_CODEPAGE_932 is not set +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_CMDLINE="" + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_NULL=m +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_BLOWFISH=m +# CONFIG_CRYPTO_CAMELLIA is not set +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set +CONFIG_CRYPTO_KHAZAD=m +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/mips/configs/ls2f_notebook_fbsplash.config b/arch/mips/configs/ls2f_notebook_fbsplash.config new file mode 100644 index 0000000..43d45cf --- /dev/null +++ b/arch/mips/configs/ls2f_notebook_fbsplash.config @@ -0,0 +1,1804 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.27.7 +# Mon Feb 16 20:13:11 2009 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +CONFIG_MACH_LM2F=y +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set +# CONFIG_WR_PPMC is not set +# CONFIG_LEMOTE_FULONG2F is not set +CONFIG_LEMOTE_2FNOTEBOOK=y +CONFIG_CS5536_RTC_BUG=y +CONFIG_CS5536=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_EARLY_PRINTK=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +# CONFIG_HOTPLUG_CPU is not set +CONFIG_I8259=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_BOOT_ELF32=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_HAVE_STD_PC_SERIAL_PORT=y + +# +# CPU selection +# +CONFIG_CPU_LOONGSON2=y +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_LOONGSON2=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +# CONFIG_PAGE_SIZE_4KB is not set +# CONFIG_PAGE_SIZE_8KB is not set +CONFIG_PAGE_SIZE_16KB=y +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +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=y +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_KEXEC=y +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y +CONFIG_IKCONFIG=y +# CONFIG_IKCONFIG_PROC is not set +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=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_PCSPKR_PLATFORM=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +# CONFIG_MARKERS is not set +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set +# CONFIG_HAVE_IOREMAP_PROT is not set +# CONFIG_HAVE_KPROBES is not set +# CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_ARCH_TRACEHOOK is not set +# CONFIG_HAVE_DMA_ATTRS is not set +# CONFIG_USE_GENERIC_SMP_HELPERS is not set +# CONFIG_HAVE_CLK is not set +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y +# CONFIG_PROBE_INITRD_HEADER is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +CONFIG_ISA=y +CONFIG_MMU=y +# CONFIG_PCCARD is not set +CONFIG_HOTPLUG_PCI=m +# CONFIG_HOTPLUG_PCI_FAKE is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y + +# +# Power management options +# +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="/dev/hda3" + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_LS2F_CPU_FREQ=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE 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=m +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +# CONFIG_NF_CONNTRACK is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ESP=m +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +# CONFIG_IP_NF_SECURITY is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# Bridge: Netfilter Configuration +# +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# 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_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_AF_RXRPC=y +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +CONFIG_FIB_RULES=y + +# +# Wireless +# +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=m +# 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_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=m +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# 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 +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +# CONFIG_PNP is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_TIMINGS=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# 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 +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_BLK_DEV_IDEDMA_SFF=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_PCIBUS_ORDER=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set + +# +# Other IDE chipsets support +# + +# +# Note: most of these also require special kernel boot parameters +# +# CONFIG_BLK_DEV_4DRIVES is not set +# CONFIG_BLK_DEV_ALI14XX is not set +# CONFIG_BLK_DEV_DTC2278 is not set +# CONFIG_BLK_DEV_HT6560B is not set +# CONFIG_BLK_DEV_QD65XX is not set +# CONFIG_BLK_DEV_UMC8672 is not set +CONFIG_BLK_DEV_IDEDMA=y + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m + +# +# 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 +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_SRP_ATTRS=m +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_OHCI1394=m + +# +# PCILynx controller requires I2C +# +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_DV1394=m +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_I2O=m +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +# CONFIG_I2O_CONFIG is not set +# CONFIG_I2O_BUS is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +CONFIG_VETH=m +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_DM9000 is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_TC35815 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS 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_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_PPPOL2TP is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_NET_FC is not set +CONFIG_NETCONSOLE=m +# CONFIG_NETCONSOLE_DYNAMIC is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# 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=m +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYBOARD_NEWTON=m +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_INPORT=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_VSXXXAA=m +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +CONFIG_ROCKETPORT=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +CONFIG_MOXA_SMARTIO=m +# CONFIG_ISI is not set +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_N_HDLC=m +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +CONFIG_SX=m +# CONFIG_RIO is not set +CONFIG_STALDRV=y +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=16 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_HW_RANDOM=y +CONFIG_RTC=y +CONFIG_DTLK=m +CONFIG_R3964=m +CONFIG_APPLICOM=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +# CONFIG_SSB_B43_PCI_BRIDGE is not set +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +# CONFIG_SSB_DRIVER_MIPS is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_STRADIS is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_GSPCA is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER 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_ZC0301 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +CONFIG_DRM=m +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_R128 is not set +# CONFIG_DRM_RADEON is not set +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +CONFIG_FB_SILICONMOTION=y +CONFIG_FB_SM7XX=y +CONFIG_FB_SM7XX_ACCEL=y +# CONFIG_FB_SM7XX_DUALHEAD is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_CORGI is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_FB_SPLASH=y +CONFIG_SOUND=m +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_RTCTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_MPU401_UART=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +# CONFIG_SND_AC97_POWER_SAVE is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +CONFIG_SND_CS5535AUDIO=m +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HIFIER is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_VIA82XX=m +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_MIPS is not set +# CONFIG_SND_USB is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m +# CONFIG_USB_WDM 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=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +CONFIG_USB_TEST=m +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="utf8" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +# CONFIG_ECRYPT_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +CONFIG_VXFS_FS=m +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +CONFIG_ROMFS_FS=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_NCP_FS=m +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +# CONFIG_NLS_CODEPAGE_932 is not set +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_CMDLINE="" + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_NULL=m +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_BLOWFISH=m +# CONFIG_CRYPTO_CAMELLIA is not set +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set +CONFIG_CRYPTO_KHAZAD=m +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/mips/kernel/8250-platform.c b/arch/mips/kernel/8250-platform.c index cbf3fe2..6bf8ab3 100644 --- a/arch/mips/kernel/8250-platform.c +++ b/arch/mips/kernel/8250-platform.c @@ -9,6 +9,12 @@ #include #include +#ifdef CONFIG_64BIT +#define UART_BASE (void*)0xffffffffbff003f8 +#else +#define UART_BASE (void*)0xbff003f8 +#endif + #define PORT(base, int) \ { \ .iobase = base, \ @@ -20,10 +26,24 @@ } static struct plat_serial8250_port uart8250_data[] = { +#ifdef CONFIG_MACH_LM2F +#if defined(CONFIG_LEMOTE_NAS) || defined(CONFIG_LEMOTE_2FNOTEBOOK) + { .membase = UART_BASE, + .irq = 19, + .uartclk = 3686400, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + .regshift = 0, + }, +#else + PORT(0x2F8, 3), +#endif +#else PORT(0x3F8, 4), PORT(0x2F8, 3), PORT(0x3E8, 4), PORT(0x2E8, 3), +#endif { }, }; diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 25775cb..5724087 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ptrace.o reset.o setup.o signal.o syscall.o \ - time.o topology.o traps.o unaligned.o + time.o topology.o traps.o unaligned.o rtc.o obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o @@ -71,6 +71,7 @@ obj-$(CONFIG_64BIT) += scall64-64.o obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o +obj-$(CONFIG_LS2F_CPU_FREQ) += ls2f_freq.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_PROC_FS) += proc.o diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 7294222..b06921a 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -295,3 +296,13 @@ void output_irq_cpustat_t_defines(void) DEFINE(IC_IRQ_CPUSTAT_T, sizeof(irq_cpustat_t)); BLANK(); } + +void output_pbe_defines(void) +{ + COMMENT(" Linux struct pbe offsets. "); + OFFSET(PBE_ADDRESS , pbe, address); + OFFSET(PBE_ORIG_ADDRESS , pbe, orig_address); + OFFSET(PBE_NEXT , pbe, next); + DEFINE(PBE_SIZE , sizeof(struct pbe)); + BLANK(); +} diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c index 86e026f..74fb745 100644 --- a/arch/mips/kernel/csrc-r4k.c +++ b/arch/mips/kernel/csrc-r4k.c @@ -27,7 +27,7 @@ int __init init_mips_clocksource(void) if (!cpu_has_counter || !mips_hpt_frequency) return -ENXIO; - /* Calclate a somewhat reasonable rating value */ + /* Calculate a somewhat reasonable rating value */ clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; clocksource_set_clock(&clocksource_mips, mips_hpt_frequency); diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 413bd1d..7f9e771 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -53,7 +53,7 @@ static struct irq_chip i8259A_chip = { /* * This contains the irq mask for both 8259A irq controllers, */ -static unsigned int cached_irq_mask = 0xffff; +unsigned int cached_irq_mask = 0xffff; #define cached_master_mask (cached_irq_mask) #define cached_slave_mask (cached_irq_mask >> 8) @@ -175,11 +175,15 @@ handle_real_irq: if (irq & 8) { inb(PIC_SLAVE_IMR); /* DUMMY - (do we need this?) */ outb(cached_slave_mask, PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); outb(0x60+(irq&7), PIC_SLAVE_CMD);/* 'Specific EOI' to slave */ + inb(PIC_SLAVE_CMD); outb(0x60+PIC_CASCADE_IR, PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */ + inb(PIC_MASTER_CMD); } else { inb(PIC_MASTER_IMR); /* DUMMY - (do we need this?) */ outb(cached_master_mask, PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); outb(0x60+irq, PIC_MASTER_CMD); /* 'Specific EOI to master */ } smtc_im_ack_irq(irq); @@ -203,8 +207,8 @@ spurious_8259A_irq: * At this point we can be sure the IRQ is spurious, * lets ACK and report it. [once per IRQ] */ - if (!(spurious_irq_mask & irqmask)) { - printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", irq); + if (!(spurious_irq_mask & irqmask) || 1) { + printk("spurious 8259A interrupt: IRQ%d.\n", irq); spurious_irq_mask |= irqmask; } atomic_inc(&irq_err_count); diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 2fefb14..e07b1a1 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -555,3 +555,10 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs) return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr); } + +asmlinkage long sys32_lookup_dcookie(u32 dcookie_a0, u32 dcookie_a1, char __user *buf, + size_t len) +{ + return sys_lookup_dcookie(merge_64(dcookie_a0, dcookie_a1), + buf, len); +} diff --git a/arch/mips/kernel/ls2f_freq.c b/arch/mips/kernel/ls2f_freq.c new file mode 100644 index 0000000..602eb46 --- /dev/null +++ b/arch/mips/kernel/ls2f_freq.c @@ -0,0 +1,216 @@ +/* + * arch/mips/kernel/cpufreq.c + * + * cpufreq driver for the loongson-2f processors. + * + * Copyright (C) 2006 - 2008 Yanhua + * + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include /* set_cpus_allowed() */ +#include +#include +#include + +#include + +static uint nowait = 0; + +static struct clk *cpuclk; +extern unsigned long cpu_clock_freq; +extern struct cpufreq_frequency_table ls2f_clockmod_table[]; + +extern void (*cpu_wait)(void); +extern void ls2f_cpu_wait(void); +static void (*saved_cpu_wait)(void); + +static int +ls2f_cpu_freq_notifier(struct notifier_block *nb, unsigned long val, + void *data); + +static struct notifier_block ls2f_cpufreq_notifier_block = { + .notifier_call = ls2f_cpu_freq_notifier +}; + +static int +ls2f_cpu_freq_notifier(struct notifier_block *nb, unsigned long val, void *data) +{ + if (val == CPUFREQ_POSTCHANGE) { + __udelay_val = loops_per_jiffy; + } + return 0; +} + +static unsigned int ls2f_cpufreq_get(unsigned int cpu) +{ + return clk_get_rate(cpuclk); +} + +/* + * Here we notify other drivers of the proposed change and the final change. + */ +static int ls2f_cpufreq_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int cpu = policy->cpu; + unsigned int newstate = 0; + cpumask_t cpus_allowed; + struct cpufreq_freqs freqs; + long freq; + + if (!cpu_online(cpu)) + return -ENODEV; + + cpus_allowed = current->cpus_allowed; + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + +#ifdef CONFIG_SMP + BUG_ON(smp_processor_id() != cpu); +#endif + + if (cpufreq_frequency_table_target(policy, &ls2f_clockmod_table[0], target_freq, relation, &newstate)) + return -EINVAL; + + freq = cpu_clock_freq / 1000 * ls2f_clockmod_table[newstate].index / 8; + if (freq < policy->min || freq > policy->max ) + return -EINVAL; + + pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000); + + freqs.cpu = cpu; + freqs.old = ls2f_cpufreq_get(cpu); + freqs.new = freq; + freqs.flags = 0; + + if (freqs.new == freqs.old) + return 0; + + /* notifiers */ + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + set_cpus_allowed(current, cpus_allowed); + + /* setting the cpu frequency */ + clk_set_rate(cpuclk, freq); + + /* notifiers */ + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + pr_debug("cpufreq: set frequency %lu kHz\n", freq); + + return 0; +} + +static int ls2f_cpufreq_cpu_init(struct cpufreq_policy *policy) +{ + int i; + int result; + + if (!cpu_online(policy->cpu)) + return -ENODEV; + + cpuclk = clk_get(NULL, "cpu_clk"); + if (IS_ERR(cpuclk)) { + printk(KERN_ERR "cpufreq: couldn't get CPU clk\n"); + return PTR_ERR(cpuclk); + } + + cpuclk->rate = cpu_clock_freq / 1000; + if(!cpuclk->rate) + return -EINVAL; + + /* clock table init */ + for (i=2; (ls2f_clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { + ls2f_clockmod_table[i].frequency = (cpuclk->rate * i)/8; + } + + policy->cur = ls2f_cpufreq_get(policy->cpu); + + cpufreq_frequency_table_get_attr(&ls2f_clockmod_table[0], policy->cpu); + + result = cpufreq_frequency_table_cpuinfo(policy, &ls2f_clockmod_table[0]); + if (result) + return (result); + + return 0; +} + +static int ls2f_cpufreq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, &ls2f_clockmod_table[0]); +} + +static int ls2f_cpufreq_exit(struct cpufreq_policy *policy) +{ + clk_put(cpuclk); + return 0; +} + +static struct freq_attr* ls2f_table_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + +static struct cpufreq_driver ls2f_cpufreq_driver = { + .owner = THIS_MODULE, + .name = "ls2f", + .init = ls2f_cpufreq_cpu_init, + .verify = ls2f_cpufreq_verify, + .target = ls2f_cpufreq_target, + .get = ls2f_cpufreq_get, + .exit = ls2f_cpufreq_exit, + .attr = ls2f_table_attr, +}; + +static int __init ls2f_cpufreq_module_init(void) +{ + struct cpuinfo_mips *c = &cpu_data[0]; + int result; + + if (c->processor_id != 0x6303) + return -ENODEV; + + printk(KERN_INFO "cpufreq: Loongson-2F CPU frequency driver.\n"); + result = cpufreq_register_driver(&ls2f_cpufreq_driver); + + if(!result && !nowait) { + saved_cpu_wait = cpu_wait; + cpu_wait = ls2f_cpu_wait; + } + + cpufreq_register_notifier(&ls2f_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + return result; +} + +static void __exit ls2f_cpufreq_module_exit(void) +{ + if(!nowait && saved_cpu_wait) + cpu_wait = saved_cpu_wait; + cpufreq_unregister_driver(&ls2f_cpufreq_driver); + cpufreq_unregister_notifier(&ls2f_cpufreq_notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); +} + +//late_initcall(ls2f_cpufreq_module_init); +module_init(ls2f_cpufreq_module_init); +module_exit(ls2f_cpufreq_module_exit); + +module_param(nowait, uint, 0644); +MODULE_PARM_DESC(nowait, "Disable Loongson-2F specific wait"); + +MODULE_AUTHOR("Yanhua "); +MODULE_DESCRIPTION("cpufreq driver for Loongson2F"); +MODULE_LICENSE("GPL"); diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 36f0653..98b38f6 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -38,7 +38,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "processor\t\t: %ld\n", n); sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : ""); - seq_printf(m, fmt, __cpu_name[smp_processor_id()], + seq_printf(m, fmt, __cpu_name[n], (version >> 4) & 0x0f, version & 0x0f, (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", diff --git a/arch/mips/kernel/rtc.c b/arch/mips/kernel/rtc.c new file mode 100644 index 0000000..e22f062 --- /dev/null +++ b/arch/mips/kernel/rtc.c @@ -0,0 +1,212 @@ +/* + * RTC related functions + */ +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_X86_32 +/* + * This is a special lock that is owned by the CPU and holds the index + * register we are working with. It is required for NMI access to the + * CMOS/RTC registers. See include/asm-i386/mc146818rtc.h for details. + */ +volatile unsigned long cmos_lock = 0; +EXPORT_SYMBOL(cmos_lock); +#endif + +/* For two digit years assume time is always after that */ +#define CMOS_YEARS_OFFS 2000 + +#if 0 +DEFINE_SPINLOCK(rtc_lock); +EXPORT_SYMBOL(rtc_lock); +#else +extern spinlock_t rtc_lock; +#endif + +/* + * In order to set the CMOS clock precisely, set_rtc_mmss has to be + * called 500 ms after the second nowtime has started, because when + * nowtime is written into the registers of the CMOS clock, it will + * jump to the next second precisely 500 ms later. Check the Motorola + * MC146818A or Dallas DS12887 data sheet for details. + * + * BUG: This routine does not handle hour overflow properly; it just + * sets the minutes. Usually you'll only notice that after reboot! + */ +int mach_set_rtc_mmss(unsigned long nowtime) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned char save_control, save_freq_select; + + /* tell the clock it's being set */ + save_control = CMOS_READ(RTC_CONTROL); + CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); + + /* stop and reset prescaler */ + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + + cmos_minutes = CMOS_READ(RTC_MINUTES); + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + BCD_TO_BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + /* correct for half hour time zone */ + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + } + CMOS_WRITE(real_seconds,RTC_SECONDS); + CMOS_WRITE(real_minutes,RTC_MINUTES); + } else { + printk(KERN_WARNING + "set_rtc_mmss: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + /* The following flags have to be released exactly in this order, + * otherwise the DS12887 (popular MC146818A clone with integrated + * battery and quartz) will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned in + * the Dallas Semiconductor data sheets, but who believes data + * sheets anyway ... -- Markus Kuhn + */ + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + + return retval; +} + +unsigned long mach_get_cmos_time(void) +{ + unsigned int status, year, mon, day, hour, min, sec, century = 0; + + /* + * If UIP is clear, then we have >= 244 microseconds before + * RTC registers will be updated. Spec sheet says that this + * is the reliable way to read RTC - registers. If UIP is set + * then the register access might be invalid. + */ + while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) + cpu_relax(); + + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); + +#ifdef CONFIG_ACPI + if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && + acpi_gbl_FADT.century) + century = CMOS_READ(acpi_gbl_FADT.century); +#endif + + status = CMOS_READ(RTC_CONTROL); + WARN_ON_ONCE(RTC_ALWAYS_BCD && (status & RTC_DM_BINARY)); + + if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + + if (century) { + BCD_TO_BIN(century); + year += century * 100; + printk(KERN_INFO "Extended CMOS year: %d\n", century * 100); + } else + year += CMOS_YEARS_OFFS; + + return mktime(year, mon, day, hour, min, sec); +} + +/* Routines for accessing the CMOS RAM/RTC. */ +unsigned char rtc_cmos_read(unsigned char addr) +{ + unsigned char val; + + lock_cmos_prefix(addr); + outb(addr, RTC_PORT(0)); + val = inb(RTC_PORT(1)); + lock_cmos_suffix(addr); + return val; +} +EXPORT_SYMBOL(rtc_cmos_read); + +void rtc_cmos_write(unsigned char val, unsigned char addr) +{ + lock_cmos_prefix(addr); + outb(addr, RTC_PORT(0)); + outb(val, RTC_PORT(1)); + lock_cmos_suffix(addr); +} +EXPORT_SYMBOL(rtc_cmos_write); + +int set_rtc_mmss(unsigned long nowtime) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&rtc_lock, flags); + retval = set_wallclock(nowtime); + spin_unlock_irqrestore(&rtc_lock, flags); + + return retval; +} + +static struct resource rtc_resources[] = { + [0] = { + .start = RTC_PORT(0), + .end = RTC_PORT(1), + .flags = IORESOURCE_IO, + }, + [1] = { + .start = RTC_IRQ, + .end = RTC_IRQ, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device rtc_device = { + .name = "rtc_cmos", + .id = -1, + .resource = rtc_resources, + .num_resources = ARRAY_SIZE(rtc_resources), +}; + +static __init int add_rtc_cmos(void) +{ +#ifdef CONFIG_PNP + if (!pnp_platform_devices) + platform_device_register(&rtc_device); +#else + platform_device_register(&rtc_device); +#endif /* CONFIG_PNP */ + return 0; +} +device_initcall(add_rtc_cmos); diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 5e75a31..759f680 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -180,7 +180,7 @@ bad_stack: * The system call does not exist in this kernel */ illegal_syscall: - li v0, -ENOSYS # error + li v0, ENOSYS # error sw v0, PT_R2(sp) li t0, 1 # set error flag sw t0, PT_R7(sp) @@ -293,7 +293,7 @@ bad_alignment: jr t2 /* Unreached */ -einval: li v0, -EINVAL +einval: li v0, -ENOSYS jr ra END(sys_syscall) diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 3d58204..a9e1716 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -117,7 +117,7 @@ syscall_trace_entry: illegal_syscall: /* This also isn't a 64-bit syscall, throw an error. */ - li v0, -ENOSYS # error + li v0, ENOSYS # error sd v0, PT_R2(sp) li t0, 1 # set error flag sd t0, PT_R7(sp) diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index d7cd1aa..e3271b9 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -452,7 +452,7 @@ sys_call_table: PTR sys_io_submit PTR sys_io_cancel /* 4245 */ PTR sys_exit_group - PTR sys_lookup_dcookie + PTR sys32_lookup_dcookie PTR sys_epoll_create PTR sys_epoll_ctl PTR sys_epoll_wait /* 4250 */ diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 16f8edf..4430a1f 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -601,8 +601,8 @@ static int __init debugfs_mips(void) struct dentry *d; d = debugfs_create_dir("mips", NULL); - if (IS_ERR(d)) - return PTR_ERR(d); + if (!d) + return -ENOMEM; mips_debugfs_dir = d; return 0; } diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 4410f17..6d3d197 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -161,8 +161,10 @@ static void stop_this_cpu(void *dummy) * Remove this CPU: */ cpu_clear(smp_processor_id(), cpu_online_map); - local_irq_enable(); /* May need to service _machine_restart IPI */ - for (;;); /* Wait if available. */ + for (;;) { + if (cpu_wait) + (*cpu_wait)(); /* Wait if available. */ + } } void smp_send_stop(void) diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 1f467d5..4ab3c9b 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -154,6 +154,9 @@ void __init time_init(void) { plat_time_init(); +#if defined(CONFIG_LS2F_CPU_FREQ) || defined(CONFIG_LEMOTE_FULONG2F) + return ; +#endif if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug()) init_mips_clocksource(); } diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index c327b21..2070966 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -560,12 +560,12 @@ static int __init debugfs_unaligned(void) return -ENODEV; d = debugfs_create_u32("unaligned_instructions", S_IRUGO, mips_debugfs_dir, &unaligned_instructions); - if (IS_ERR(d)) - return PTR_ERR(d); + if (!d) + return -ENOMEM; d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR, mips_debugfs_dir, &unaligned_action); - if (IS_ERR(d)) - return PTR_ERR(d); + if (!d) + return -ENOMEM; return 0; } __initcall(debugfs_unaligned); diff --git a/arch/mips/lemote/lm2e/mipsdha.c b/arch/mips/lemote/lm2e/mipsdha.c new file mode 100644 index 0000000..fd90454 --- /dev/null +++ b/arch/mips/lemote/lm2e/mipsdha.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +static ssize_t mipsdha_proc_read(struct file *file, char *buf, size_t len, loff_t *ppos); + +static ssize_t mipsdha_proc_write(struct file *file, const char *buf, size_t len, loff_t *ppos); + + +static struct proc_dir_entry *mipsdha_proc_entry; + +#define INFO_SIZE 4096 +static char info_buf[INFO_SIZE]; + +static struct file_operations mipsdha_fops = +{ + owner: THIS_MODULE, + read: mipsdha_proc_read, + write: mipsdha_proc_write, +}; + +static enum {CMD_ERR, CMD_GIB, CMD_GPI} cmd; + +typedef struct pciinfo_s +{ + int bus,card,func; + unsigned short command; + unsigned short vendor,device; + unsigned base0,base1,base2,baserom; +} pciinfo_t; + + +extern struct proc_dir_entry proc_root; + +static int __init mipsdha_proc_init(void) +{ + mipsdha_proc_entry = create_proc_entry("mipsdha", S_IWUSR | S_IRUGO, &proc_root); + if (mipsdha_proc_entry == NULL) { + printk("MIPSDHA: register /proc/mipsdha failed!\n"); + return 0; + } + + mipsdha_proc_entry->owner = THIS_MODULE; + mipsdha_proc_entry->proc_fops = &mipsdha_fops; + + cmd=CMD_ERR; + return 0; +} + +static ssize_t mipsdha_proc_write (struct file *file, const char *buf, size_t len, loff_t *ppos) +{ + char cmd_gib[]="GET IO BASE"; + char cmd_gpi[]="GET PCI INFO"; + + if (len >= INFO_SIZE) return -ENOMEM; + + if (copy_from_user(info_buf, buf, len)) return -EFAULT; + info_buf[len] = '\0'; + + if (strncmp(info_buf, cmd_gib, sizeof(cmd_gib)-1)==0) { + cmd = CMD_GIB; + return len; + } else if (strncmp(info_buf, cmd_gpi, sizeof(cmd_gpi)-1)==0) { + cmd = CMD_GPI; + return len; + } else { + return -EINVAL; + } +} + +static ssize_t mipsdha_proc_read (struct file *file, char *buf, size_t len, loff_t *ppos) +{ + int info_cnt; + pciinfo_t *pciinfo; + struct pci_dev *dev = NULL; + + switch (cmd) { + default: + printk("MIPSDHA: BUG found in function %s!(cmd=%d)\n", + __FUNCTION__, cmd); + return -EINVAL; + + + case CMD_ERR: + return -EINVAL; + + + case CMD_GIB: + *(unsigned long *)info_buf = + virt_to_phys((void *) mips_io_port_base); + info_cnt=sizeof(unsigned long); + break; + + + case CMD_GPI: + pciinfo = (pciinfo_t *) info_buf; + info_cnt = 0; + for_each_pci_dev(dev) { + + if (info_cnt+sizeof(pciinfo_t)>INFO_SIZE) return -ENOMEM; + + pciinfo->bus = dev->bus->number; + pciinfo->card = PCI_SLOT(dev->devfn); + pciinfo->func = PCI_FUNC(dev->devfn); + + if (pci_read_config_word(dev, PCI_COMMAND, &pciinfo->command) + != PCIBIOS_SUCCESSFUL) { + printk("MIPSDHA: BUG found in function %s!\n", + __FUNCTION__); + pciinfo->command=0; + } + + pciinfo->vendor = dev->vendor; + pciinfo->device = dev->device; + + pciinfo->base0 = (dev->resource[0]).start; + pciinfo->base1 = (dev->resource[1]).start; + pciinfo->base2 = (dev->resource[2]).start; + pciinfo->baserom = (dev->resource[PCI_ROM_RESOURCE]).start; + + pciinfo++; + info_cnt += sizeof(pciinfo_t); + } + break; + } + + if (len < info_cnt) return -ENOMEM; + if (copy_to_user(buf, info_buf, info_cnt)) return -EFAULT; + + return info_cnt; +} + +__initcall(mipsdha_proc_init); diff --git a/arch/mips/lemote/lm2f/Kconfig b/arch/mips/lemote/lm2f/Kconfig new file mode 100644 index 0000000..25c2b3d --- /dev/null +++ b/arch/mips/lemote/lm2f/Kconfig @@ -0,0 +1,72 @@ +choice + prompt "Machine type" + depends on MACH_LM2F + default LEMOTE_FULONG2F + +config LEMOTE_FULONG2F + bool "Lemote Fulong mini-PC" + select ARCH_SPARSEMEM_ENABLE + select CEVT_R4K + select CSRC_R4K + select SYS_HAS_CPU_LOONGSON2 + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select CPU_HAS_WB + select CS5536 + help + Lemote Fulong mini-PC board based on the Chinese Loongson-2F CPU + +config LEMOTE_2FNOTEBOOK + bool "Lemote mini Notebook" + select ARCH_SPARSEMEM_ENABLE + select CEVT_R4K + select CSRC_R4K + select SYS_HAS_CPU_LOONGSON2 + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HAVE_STD_PC_SERIAL_PORT + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select CPU_HAS_WB + select CS5536 + help + Lemote Notebook based on the Chinese Loongson-2F CPU + +endchoice + +config CS5536_RTC_BUG + bool + +config CS5536 + bool + select CS5536_RTC_BUG + +config LEMOTE_NAS + bool "Lemote NAS machine" + depends on LEMOTE_FULONG2F + help + Lemote's Loongson-2F based network attached system + diff --git a/arch/mips/lemote/lm2f/common/Makefile b/arch/mips/lemote/lm2f/common/Makefile new file mode 100644 index 0000000..deac453 --- /dev/null +++ b/arch/mips/lemote/lm2f/common/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2007, 2008 Lemote Tec +# Author: www.lemote.com Inc +# +# Makefile for the loongson2f CPUS, generic files +# + +obj-y += mem.o mipsdha.o pci.o clock.o +obj-$(CONFIG_CS5536) += cs5536_vsm.o mfgpt.o diff --git a/arch/mips/lemote/lm2f/common/clock.c b/arch/mips/lemote/lm2f/common/clock.c new file mode 100644 index 0000000..8c9602f --- /dev/null +++ b/arch/mips/lemote/lm2f/common/clock.c @@ -0,0 +1,160 @@ +#include +#include +#include + +#ifdef CONFIG_64BIT +#define PTR_PAD(p) ((0xffffffff00000000)|((unsigned long)(p))) +#else +#define PTR_PAD(p) (p) +#endif + +static LIST_HEAD(clock_list); +static DEFINE_SPINLOCK(clock_lock); +static DEFINE_MUTEX(clock_list_sem); + +/* Minimum CLK support */ +enum { + DC_ZERO, DC_25PT=2, DC_37PT, DC_50PT, DC_62PT, DC_75PT, + DC_87PT, DC_DISABLE, DC_RESV +}; + +struct cpufreq_frequency_table ls2f_clockmod_table[] = { + {DC_RESV, CPUFREQ_ENTRY_INVALID}, + {DC_ZERO, CPUFREQ_ENTRY_INVALID}, + {DC_25PT, 0}, + {DC_37PT, 0}, + {DC_50PT, 0}, + {DC_62PT, 0}, + {DC_75PT, 0}, + {DC_87PT, 0}, + {DC_DISABLE, 0}, + {DC_RESV, CPUFREQ_TABLE_END}, +}; + + +static struct clk cpu_clk = { + .name = "cpu_clk", + .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, + .rate = 800000000, +}; + +struct clk *clk_get(struct device *dev, const char *id) +{ + return &cpu_clk; +} +EXPORT_SYMBOL(clk_get); + +static void propagate_rate(struct clk *clk) +{ + struct clk *clkp; + + list_for_each_entry(clkp, &clock_list, node) { + if (likely(clkp->parent != clk)) + continue; + if (likely(clkp->ops && clkp->ops->recalc)) + clkp->ops->recalc(clkp); + if (unlikely(clkp->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clkp); + } +} + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return clk_set_rate_ex(clk, rate, 0); +} +EXPORT_SYMBOL_GPL(clk_set_rate); + +int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) +{ + //int ret = -EOPNOTSUPP; + int ret = 0; //-EOPNOTSUPP; + int regval; + int i; + + if (likely(clk->ops && clk->ops->set_rate)) { + unsigned long flags; + + spin_lock_irqsave(&clock_lock, flags); + ret = clk->ops->set_rate(clk, rate, algo_id); + spin_unlock_irqrestore(&clock_lock, flags); + } + + if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clk); + + for (i =0; ls2f_clockmod_table[i].frequency != CPUFREQ_TABLE_END; i++) { + if (ls2f_clockmod_table[i].frequency == CPUFREQ_ENTRY_INVALID) + continue; + if (rate == ls2f_clockmod_table[i].frequency) + break; + } + if (rate != ls2f_clockmod_table[i].frequency) + return -ENOTSUPP; + + clk->rate = rate; + + regval = *(volatile unsigned int*) PTR_PAD(0xbfe00180); + regval = (regval & ~0x7) | (ls2f_clockmod_table[i].index -1); + *(volatile unsigned int *) PTR_PAD(0xbfe00180) = regval; + + return ret; +} +EXPORT_SYMBOL_GPL(clk_set_rate_ex); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (likely(clk->ops && clk->ops->round_rate)) { + unsigned long flags, rounded; + + spin_lock_irqsave(&clock_lock, flags); + rounded = clk->ops->round_rate(clk, rate); + spin_unlock_irqrestore(&clock_lock, flags); + + return rounded; + } + + return rate; //clk_get_rate(clk); +} +EXPORT_SYMBOL_GPL(clk_round_rate); + +/* + * This is the simple version of Loongson-2F wait + * Maybe we need do this in interrupt disabled content + */ +DEFINE_SPINLOCK(ls2f_wait_lock); +void ls2f_cpu_wait(void) +{ + u32 cpu_freq; + unsigned long flags; + + spin_lock_irqsave(&ls2f_wait_lock, flags); + cpu_freq = *(volatile u32*)PTR_PAD(0xbfe00180); + *(volatile u32*)PTR_PAD(0xbfe00180) &= ~0x7; //Put CPU into wait mode + *(volatile u32*)PTR_PAD(0xbfe00180) = cpu_freq; //Restore CPU state + spin_unlock_irqrestore(&ls2f_wait_lock, flags); +} + +EXPORT_SYMBOL_GPL(ls2f_cpu_wait); +EXPORT_SYMBOL_GPL(ls2f_clockmod_table); diff --git a/arch/mips/lemote/lm2f/common/cs5536.h b/arch/mips/lemote/lm2f/common/cs5536.h new file mode 100644 index 0000000..c18522a --- /dev/null +++ b/arch/mips/lemote/lm2f/common/cs5536.h @@ -0,0 +1,578 @@ +/* + * cs5536.h + * + * The include file of cs5536 sourthbridge define which is used in the pmon only. + * you can modify it or change it, please set the modify time and steps. + * + * Author : jlliu + * Data : 07-6-27 + */ + +#ifndef _CS5536_H +#define _CS5536_H + +/*************************************************************************/ + +/* + * basic define + */ +#define PCI_IO_BASE 0x1fd00000 //( < 0x1fe00000) +#define PCI_IO_BASE_VA 0xbfd00000 +#define PCI_MEM_BASE 0x10000000 //( < 0x1c000000 ) +#define PCI_MEM_BASE_VA 0xb0000000 + +/* + * MSR module base + */ +#define CS5536_SB_MSR_BASE (0x00000000) +#define CS5536_GLIU_MSR_BASE (0x10000000) +#define CS5536_ILLEGAL_MSR_BASE (0x20000000) +#define CS5536_USB_MSR_BASE (0x40000000) +#define CS5536_IDE_MSR_BASE (0x60000000) +#define CS5536_DIVIL_MSR_BASE (0x80000000) +#define CS5536_ACC_MSR_BASE (0xa0000000) +#define CS5536_UNUSED_MSR_BASE (0xc0000000) +#define CS5536_GLCP_MSR_BASE (0xe0000000) + +#define SB_MSR_REG(offset) (CS5536_SB_MSR_BASE | offset) +#define GLIU_MSR_REG(offset) (CS5536_GLIU_MSR_BASE | offset) +#define ILLEGAL_MSR_REG(offset) (CS5536_ILLEGAL_MSR_BASE| offset) +#define USB_MSR_REG(offset) (CS5536_USB_MSR_BASE | offset) +#define IDE_MSR_REG(offset) (CS5536_IDE_MSR_BASE | offset) +#define DIVIL_MSR_REG(offset) (CS5536_DIVIL_MSR_BASE | offset) +#define ACC_MSR_REG(offset) (CS5536_ACC_MSR_BASE | offset) +#define UNUSED_MSR_REG(offset) (CS5536_UNUSED_MSR_BASE | offset) +#define GLCP_MSR_REG(offset) (CS5536_GLCP_MSR_BASE | offset) + +/* + * BAR SPACE OF VIRTUAL PCI : range for pci probe use, length is the actual size. + */ +// IO space for all DIVIL modules +#define CS5536_IRQ_RANGE 0xffffffe0 // USERD FOR PCI PROBE +#define CS5536_IRQ_LENGTH 0x20 // THE REGS ACTUAL LENGTH +#define CS5536_SMB_RANGE 0xfffffff8 +#define CS5536_SMB_LENGTH 0x08 +#define CS5536_GPIO_RANGE 0xffffff00 +#define CS5536_GPIO_LENGTH 0x100 +#define CS5536_MFGPT_RANGE 0xffffffc0 +#define CS5536_MFGPT_LENGTH 0x40 +#define CS5536_ACPI_RANGE 0xffffffe0 +#define CS5536_ACPI_LENGTH 0x20 +#define CS5536_PMS_RANGE 0xffffff80 +#define CS5536_PMS_LENGTH 0x80 +// MEM space for 4KB nand flash; IO space for 16B nor flash. +#ifdef CS5536_USE_NOR_FLASH +#define CS5536_FLSH0_RANGE 0xfffffff0 +#define CS5536_FLSH0_LENGTH 0x10 +#define CS5536_FLSH1_RANGE 0xfffffff0 +#define CS5536_FLSH1_LENGTH 0x10 +#define CS5536_FLSH2_RANGE 0xfffffff0 +#define CS5536_FLSH2_LENGTH 0x10 +#define CS5536_FLSH3_RANGE 0xfffffff0 +#define CS5536_FLSH3_LENGTH 0x10 +#else +#define CS5536_FLSH0_RANGE 0xfffff000 +#define CS5536_FLSH0_LENGTH 0x1000 +#define CS5536_FLSH1_RANGE 0xfffff000 +#define CS5536_FLSH1_LENGTH 0x1000 +#define CS5536_FLSH2_RANGE 0xfffff000 +#define CS5536_FLSH2_LENGTH 0x1000 +#define CS5536_FLSH3_RANGE 0xfffff000 +#define CS5536_FLSH3_LENGTH 0x1000 +#endif +// IO space for IDE +#define CS5536_IDE_RANGE 0xfffffff0 +#define CS5536_IDE_LENGTH 0x10 +// IO space for ACC +#define CS5536_ACC_RANGE 0xffffff80 +#define CS5536_ACC_LENGTH 0x80 +// MEM space for ALL USB modules +//#define CS5536_OHCI_RANGE 0xfffffff0 +#define CS5536_OHCI_RANGE 0xfffff000 +#define CS5536_OHCI_LENGTH 0x1000 +//#define CS5536_EHCI_RANGE 0xfffffff0 +#define CS5536_EHCI_RANGE 0xfffff000 +#define CS5536_EHCI_LENGTH 0x1000 +#define CS5536_UDC_RANGE 0xffffe000 +#define CS5536_UDC_LENGTH 0x2000 +#define CS5536_OTG_RANGE 0xfffff000 +#define CS5536_OTG_LENGTH 0x1000 + +/* + * PCI MSR ACCESS + */ +#define PCI_MSR_CTRL 0xF0 +#define PCI_MSR_ADDR 0xF4 +#define PCI_MSR_DATA_LO 0xF8 +#define PCI_MSR_DATA_HI 0xFC + +/******************************* MSR *********************************************/ + +/* + * GLIU STANDARD MSR + */ +#define GLIU_CAP 0x00 +#define GLIU_CONFIG 0x01 +#define GLIU_SMI 0x02 +#define GLIU_ERROR 0x03 +#define GLIU_PM 0x04 +#define GLIU_DIAG 0x05 + +/* + * GLIU SPEC. MSR + */ +#define GLIU_P2D_BM0 0x20 +#define GLIU_P2D_BM1 0x21 +#define GLIU_P2D_BM2 0x22 +#define GLIU_P2D_BMK0 0x23 +#define GLIU_P2D_BMK1 0x24 +#define GLIU_P2D_BM3 0x25 +#define GLIU_P2D_BM4 0x26 +#define GLIU_COH 0x80 +#define GLIU_PAE 0x81 +#define GLIU_ARB 0x82 +#define GLIU_ASMI 0x83 +#define GLIU_AERR 0x84 +#define GLIU_DEBUG 0x85 +#define GLIU_PHY_CAP 0x86 +#define GLIU_NOUT_RESP 0x87 +#define GLIU_NOUT_WDATA 0x88 +#define GLIU_WHOAMI 0x8B +#define GLIU_SLV_DIS 0x8C +#define GLIU_IOD_BM0 0xE0 +#define GLIU_IOD_BM1 0xE1 +#define GLIU_IOD_BM2 0xE2 +#define GLIU_IOD_BM3 0xE3 +#define GLIU_IOD_BM4 0xE4 +#define GLIU_IOD_BM5 0xE5 +#define GLIU_IOD_BM6 0xE6 +#define GLIU_IOD_BM7 0xE7 +#define GLIU_IOD_BM8 0xE8 +#define GLIU_IOD_BM9 0xE9 +#define GLIU_IOD_SC0 0xEA +#define GLIU_IOD_SC1 0xEB +#define GLIU_IOD_SC2 0xEC +#define GLIU_IOD_SC3 0xED +#define GLIU_IOD_SC4 0xEE +#define GLIU_IOD_SC5 0xEF +#define GLIU_IOD_SC6 0xF0 +#define GLIU_IOD_SC7 0xF1 + +/* + * SB STANDARD + */ +#define SB_CAP 0x00 +#define SB_CONFIG 0x01 +#define SB_SMI 0x02 +#define SB_ERROR 0x03 +#define SB_MAR_ERR_EN 0x00000001 +#define SB_TAR_ERR_EN 0x00000002 +#define SB_RSVD_BIT1 0x00000004 +#define SB_EXCEP_ERR_EN 0x00000008 +#define SB_SYSE_ERR_EN 0x00000010 +#define SB_PARE_ERR_EN 0x00000020 +#define SB_TAS_ERR_EN 0x00000040 +#define SB_MAR_ERR_FLAG 0x00010000 +#define SB_TAR_ERR_FLAG 0x00020000 +#define SB_RSVD_BIT2 0x00040000 +#define SB_EXCEP_ERR_FLAG 0x00080000 +#define SB_SYSE_ERR_FLAG 0x00100000 +#define SB_PARE_ERR_FLAG 0x00200000 +#define SB_TAS_ERR_FLAG 0x00400000 +#define SB_PM 0x04 +#define SB_DIAG 0x05 + +/* + * SB SPEC. + */ +#define SB_CTRL 0x10 +#define SB_R0 0x20 +#define SB_R1 0x21 +#define SB_R2 0x22 +#define SB_R3 0x23 +#define SB_R4 0x24 +#define SB_R5 0x25 +#define SB_R6 0x26 +#define SB_R7 0x27 +#define SB_R8 0x28 +#define SB_R9 0x29 +#define SB_R10 0x2A +#define SB_R11 0x2B +#define SB_R12 0x2C +#define SB_R13 0x2D +#define SB_R14 0x2E +#define SB_R15 0x2F + +/* + * GLCP STANDARD + */ +#define GLCP_CAP 0x00 +#define GLCP_CONFIG 0x01 +#define GLCP_SMI 0x02 +#define GLCP_ERROR 0x03 +#define GLCP_PM 0x04 +#define GLCP_DIAG 0x05 + +/* + * GLCP SPEC. + */ +#define GLCP_CLK_DIS_DELAY 0x08 +#define GLCP_PM_CLK_DISABLE 0x09 +#define GLCP_GLB_PM 0x0B +#define GLCP_DBG_OUT 0x0C +#define GLCP_RSVD1 0x0D +#define GLCP_SOFT_COM 0x0E +#define SOFT_BAR_SMB_FLAG 0x00000001 +#define SOFT_BAR_GPIO_FLAG 0x00000002 +#define SOFT_BAR_MFGPT_FLAG 0x00000004 +#define SOFT_BAR_IRQ_FLAG 0x00000008 +#define SOFT_BAR_PMS_FLAG 0x00000010 +#define SOFT_BAR_ACPI_FLAG 0x00000020 +#define SOFT_BAR_FLSH0_FLAG 0x00000040 +#define SOFT_BAR_FLSH1_FLAG 0x00000080 +#define SOFT_BAR_FLSH2_FLAG 0x00000100 +#define SOFT_BAR_FLSH3_FLAG 0x00000200 +#define SOFT_BAR_IDE_FLAG 0x00000400 +#define SOFT_BAR_ACC_FLAG 0x00000800 +#define SOFT_BAR_OHCI_FLAG 0x00001000 +#define SOFT_BAR_EHCI_FLAG 0x00002000 +#define SOFT_BAR_UDC_FLAG 0x00004000 +#define SOFT_BAR_OTG_FLAG 0x00008000 +#define GLCP_RSVD2 0x0F +#define GLCP_CLK_OFF 0x10 +#define GLCP_CLK_ACTIVE 0x11 +#define GLCP_CLK_DISABLE 0x12 +#define GLCP_CLK4ACK 0x13 +#define GLCP_SYS_RST 0x14 +#define GLCP_RSVD3 0x15 +#define GLCP_DBG_CLK_CTRL 0x16 +#define GLCP_CHIP_REV_ID 0x17 + +/* + * DIVIL STANDARD + */ +#define DIVIL_CAP 0x00 +#define DIVIL_CONFIG 0x01 +#define DIVIL_SMI 0x02 +#define DIVIL_ERROR 0x03 +#define DIVIL_PM 0x04 +#define DIVIL_DIAG 0x05 + +/* + * DIVIL SPEC. + */ +#define DIVIL_LBAR_IRQ 0x08 +#define DIVIL_LBAR_KEL 0x09 +#define DIVIL_LBAR_SMB 0x0B +#define DIVIL_LBAR_GPIO 0x0C +#define DIVIL_LBAR_MFGPT 0x0D +#define DIVIL_LBAR_ACPI 0x0E +#define DIVIL_LBAR_PMS 0x0F +#define DIVIL_LBAR_FLSH0 0x10 +#define DIVIL_LBAR_FLSH1 0x11 +#define DIVIL_LBAR_FLSH2 0x12 +#define DIVIL_LBAR_FLSH3 0x13 +#define DIVIL_LEG_IO 0x14 +#define DIVIL_BALL_OPTS 0x15 +#define DIVIL_SOFT_IRQ 0x16 +#define DIVIL_SOFT_RESET 0x17 +// NOR FLASH +#define NORF_CTRL 0x18 +#define NORF_T01 0x19 +#define NORF_T23 0x1A +// NAND FLASH +#define NANDF_DATA 0x1B +#define NANDF_CTRL 0x1C +#define NANDF_RSVD 0x1D +// KEL Keyboard Emulation Logic +#define KEL_CTRL 0x1F +// PIC +#define PIC_YSEL_LOW 0x20 +#define PIC_YSEL_LOW_USB_SHIFT 8 +#define PIC_YSEL_LOW_ACC_SHIFT 16 +#define PIC_YSEL_LOW_FLASH_SHIFT 24 +#define PIC_YSEL_HIGH 0x21 +#define PIC_ZSEL_LOW 0x22 +#define PIC_ZSEL_HIGH 0x23 +#define PIC_IRQM_PRIM 0x24 +#define PIC_IRQM_LPC 0x25 +#define PIC_XIRR_STS_LOW 0x26 +#define PIC_XIRR_STS_HIGH 0x27 +#define PCI_SHDW 0x34 +// MFGPT +#define MFGPT_IRQ 0x28 +#define MFGPT_NR 0x29 +#define MFGPT_RSVD 0x2A +#define MFGPT_SETUP 0x2B +// FLOPPY +#define FLPY_3F2_SHDW 0x30 +#define FLPY_3F7_SHDW 0x31 +#define FLPY_372_SHDW 0x32 +#define FLPY_377_SHDW 0x33 +// PIT +#define PIT_SHDW 0x36 +#define PIT_CNTRL 0x37 +// UART +#define UART1_MOD 0x38 +#define UART1_DONG 0x39 +#define UART1_CONF 0x3A +#define UART1_RSVD 0x3B +#define UART2_MOD 0x3C +#define UART2_DONG 0x3D +#define UART2_CONF 0x3E +#define UART2_RSVD 0x3F +// DMA +#define DIVIL_AC_DMA 0x1E +#define DMA_MAP 0x40 +#define DMA_SHDW_CH0 0x41 +#define DMA_SHDW_CH1 0x42 +#define DMA_SHDW_CH2 0x43 +#define DMA_SHDW_CH3 0x44 +#define DMA_SHDW_CH4 0x45 +#define DMA_SHDW_CH5 0x46 +#define DMA_SHDW_CH6 0x47 +#define DMA_SHDW_CH7 0x48 +#define DMA_MSK_SHDW 0x49 +// LPC +#define LPC_EADDR 0x4C +#define LPC_ESTAT 0x4D +#define LPC_SIRQ 0x4E +#define LPC_RSVD 0x4F +// PMC +#define PMC_LTMR 0x50 +#define PMC_RSVD 0x51 +// RTC +#define RTC_RAM_LOCK 0x54 +#define RTC_DOMA_OFFSET 0x55 +#define RTC_MONA_OFFSET 0x56 +#define RTC_CEN_OFFSET 0x57 + +/* + * IDE STANDARD + */ +#define IDE_CAP 0x00 +#define IDE_CONFIG 0x01 +#define IDE_SMI 0x02 +#define IDE_ERROR 0x03 +#define IDE_PM 0x04 +#define IDE_DIAG 0x05 + +/* + * IDE SPEC. + */ +#define IDE_IO_BAR 0x08 +#define IDE_CFG 0x10 +#define IDE_DTC 0x12 +#define IDE_CAST 0x13 +#define IDE_ETC 0x14 +#define IDE_INTERNAL_PM 0x15 + +/* + * ACC STANDARD + */ +#define ACC_CAP 0x00 +#define ACC_CONFIG 0x01 +#define ACC_SMI 0x02 +#define ACC_ERROR 0x03 +#define ACC_PM 0x04 +#define ACC_DIAG 0x05 + +/* + * USB STANDARD + */ +#define USB_CAP 0x00 +#define USB_CONFIG 0x01 +#define USB_SMI 0x02 +#define USB_ERROR 0x03 +#define USB_PM 0x04 +#define USB_DIAG 0x05 + +/* + * USB SPEC. + */ +#define USB_OHCI 0x08 +#define USB_EHCI 0x09 +#define USB_UDC 0x0A +#define USB_OTG 0x0B + +/********************************** NATIVE ****************************************/ +// IDE NATIVE registers +#define IDE_BM_CMD 0x00 +#define IDE_BM_STS 0x02 +#define IDE_BM_PRD 0x04 + +// OHCI native registers +#define OHCI_REVISION 0x00 +#define OHCI_CONTROL 0x04 +#define OHCI_COMMAND_STATUS 0x08 +#define OHCI_INT_STATUS 0x0C +#define OHCI_INT_ENABLE 0x10 +#define OHCI_INT_DISABLE 0x14 +#define OHCI_HCCA 0x18 +#define OHCI_PERI_CUR_ED 0x1C +#define OHCI_CTRL_HEAD_ED 0x20 +#define OHCI_CTRL_CUR_ED 0x24 +#define OHCI_BULK_HEAD_ED 0x28 +#define OHCI_BULK_CUR_ED 0x2C +#define OHCI_DONE_HEAD 0x30 +#define OHCI_FM_INTERVAL 0x34 +#define OHCI_FM_REMAINING 0x38 +#define OHCI_FM_NUMBER 0x3C +#define OHCI_PERI_START 0x40 +#define OHCI_LS_THRESHOLD 0x44 +#define OHCI_RH_DESCRIPTORA 0x48 +#define OHCI_RH_DESCRIPTORB 0x4C +#define OHCI_RH_STATUS 0x50 +#define OHCI_RH_PORT_STATUS1 0x54 +#define OHCI_RH_PORT_STATUS2 0x58 +#define OHCI_RH_PORT_STATUS3 0x5C +#define OHCI_RH_PORT_STATUS4 0x60 + +// KEL : MEM SPACE; REG :32BITS WIDTH +#define KEL_HCE_CTRL 0x100 +#define KEL_HCE_IN 0x104 +#define KEL_HCE_OUT 0x108 +#define KEL_HCE_STS 0x10C +#define KEL_PORTA 0x92 //8bits +// PIC : I/O SPACE; REG : 8BITS +#define PIC_ICW1_MASTER 0x20 +#define PIC_ICW1_SLAVE 0xA0 +#define PIC_ICW2_MASTER 0x21 +#define PIC_ICW2_SLAVE 0xA1 +#define PIC_ICW3_MASTER 0x21 +#define PIC_ICW3_SLAVE 0xA1 +#define PIC_ICW4_MASTER 0x21 +#define PIC_ICW4_SLAVE 0xA1 +#define PIC_OCW1_MASTER 0x21 +#define PIC_OCW1_SLAVE 0xA1 +#define PIC_OCW2_MASTER 0x20 +#define PIC_OCW2_SLAVE 0xA0 +#define PIC_OCW3_MASTER 0x20 +#define PIC_OCW3_SLAVE 0xA0 +#define PIC_IRR_MASTER 0x20 +#define PIC_IRR_SLAVE 0xA0 +#define PIC_ISR_MASTER 0x20 +#define PIC_ISR_SLAVE 0xA0 +#define PIC_INT_SEL1 0x4D0 +#define PIC_INT_SEL2 0x4D1 +// GPIO : I/O SPACE; REG : 32BITS +#define GPIOL_OUT_VAL 0x00 +#define GPIOL_OUT_EN 0x04 +#define GPIOL_OUT_OD_EN 0x08 +#define GPIOL_OUT_INVRT_EN 0x0c +#define GPIOL_OUT_AUX1_SEL 0x10 +#define GPIOL_OUT_AUX2_SEL 0x14 +#define GPIOL_PU_EN 0x18 +#define GPIOL_PD_EN 0x1c +#define GPIOL_IN_EN 0x20 +#define GPIOL_IN_INVRT_EN 0x24 +#define GPIOL_IN_FLTR_EN 0x28 +#define GPIOL_IN_EVNTCNT_EN 0x2c +#define GPIOL_IN_READBACK 0x30 +#define GPIOL_IN_AUX1_SEL 0x34 +#define GPIOL_EVNT_EN 0x38 +#define GPIOL_LOCK_EN 0x3c +#define GPIOL_IN_POSEDGE_EN 0x40 +#define GPIOL_IN_NEGEDGE_EN 0x44 +#define GPIOL_IN_POSEDGE_STS 0x48 +#define GPIOL_IN_NEGEDGE_STS 0x4c +#define GPIOH_OUT_VAL 0x80 +#define GPIOH_OUT_EN 0x84 +#define GPIOH_OUT_OD_EN 0x88 +#define GPIOH_OUT_INVRT_EN 0x8c +#define GPIOH_OUT_AUX1_SEL 0x90 +#define GPIOH_OUT_AUX2_SEL 0x94 +#define GPIOH_PU_EN 0x98 +#define GPIOH_PD_EN 0x9c +#define GPIOH_IN_EN 0xA0 +#define GPIOH_IN_INVRT_EN 0xA4 +#define GPIOH_IN_FLTR_EN 0xA8 +#define GPIOH_IN_EVNTCNT_EN 0xAc +#define GPIOH_IN_READBACK 0xB0 +#define GPIOH_IN_AUX1_SEL 0xB4 +#define GPIOH_EVNT_EN 0xB8 +#define GPIOH_LOCK_EN 0xBc +#define GPIOH_IN_POSEDGE_EN 0xC0 +#define GPIOH_IN_NEGEDGE_EN 0xC4 +#define GPIOH_IN_POSEDGE_STS 0xC8 +#define GPIOH_IN_NEGEDGE_STS 0xCC +// SMB : I/O SPACE, REG : 8BITS WIDTH +#define SMB_SDA 0x00 +#define SMB_STS 0x01 +#define SMB_STS_SLVSTP (1 << 7) +#define SMB_STS_SDAST (1 << 6) +#define SMB_STS_BER (1 << 5) +#define SMB_STS_NEGACK (1 << 4) +#define SMB_STS_STASTR (1 << 3) +#define SMB_STS_NMATCH (1 << 2) +#define SMB_STS_MASTER (1 << 1) +#define SMB_STS_XMIT (1 << 0) +#define SMB_CTRL_STS 0x02 +#define SMB_CSTS_TGSTL (1 << 5) +#define SMB_CSTS_TSDA (1 << 4) +#define SMB_CSTS_GCMTCH (1 << 3) +#define SMB_CSTS_MATCH (1 << 2) +#define SMB_CSTS_BB (1 << 1) +#define SMB_CSTS_BUSY (1 << 0) +#define SMB_CTRL1 0x03 +#define SMB_CTRL1_STASTRE (1 << 7) +#define SMB_CTRL1_NMINTE (1 << 6) +#define SMB_CTRL1_GCMEN (1 << 5) +#define SMB_CTRL1_ACK (1 << 4) +#define SMB_CTRL1_RSVD (1 << 3) +#define SMB_CTRL1_INTEN (1 << 2) +#define SMB_CTRL1_STOP (1 << 1) +#define SMB_CTRL1_START (1 << 0) +#define SMB_ADDR 0x04 +#define SMB_ADDR_SAEN (1 << 7) +#define SMB_CONTROLLER_ADDR (0xef << 0) +#define SMB_CTRL2 0x05 +#define SMB_FREQ (0x20 << 1) //(0x7f << 1) +#define SMB_ENABLE (0x01 << 0) +#define SMB_CTRL3 0x06 + +/*********************************** LEGACY I/O *******************************/ + +/* + * LEGACY I/O SPACE BASE + */ +#define CS5536_LEGACY_BASE_ADDR (PCI_IO_BASE_VA | 0x0000) + +/* + * IDE LEGACY REG : legacy IO address is 0x170~0x177 and 0x376 (0x1f0~0x1f7 and 0x3f6) + * all registers are 16bits except the IDE_LEGACY_DATA reg + * some registers are read only and the + */ +#define PRI_IDE_LEGACY_REG(offset) (CS5536_LEGACY_BASE_ADDR | 0x1f0 | offset) +#define SEC_IDE_LEGACY_REG(offset) (CS5536_LEGACY_BASE_ADDR | 0x170 | offset) + +#define IDE_LEGACY_DATA 0x00 // RW +#define IDE_LEGACY_ERROR 0x01 // RO +#define IDE_LEGACY_FEATURE 0x01 // WO +#define IDE_LEGACY_SECTOR_COUNT 0x02 // RW +#define IDE_LEGACY_SECTOR_NUM 0x03 // RW +#define IDE_LEGACY_CYL_LO 0x04 // RW +#define IDE_LEGACY_CYL_HI 0x05 // RW +#define IDE_LEGACY_HEAD 0x06 // RW +#define IDE_LEGACY_HEAD_DRV (1 << 4) +#define IDE_LEGACY_HEAD_LBA (1 << 6) +#define IDE_LEGACY_HEAD_IBM (1 << 7 | 1 << 5) +#define IDE_LEGACY_STATUS 0x07 // RO +#define IDE_LEGACY_STATUS_ERR (1 << 0) +#define IDE_LEGACY_STATUS_IDX (1 << 1) +#define IDE_LEGACY_STATUS_CORR (1 << 2) +#define IDE_LEGACY_STATUS_DRQ (1 << 3) +#define IDE_LEGACY_STATUS_DSC (1 << 4) +#define IDE_LEGACY_STATUS_DWF (1 << 5) +#define IDE_LEGACY_STATUS_DRDY (1 << 6) +#define IDE_LEGACY_STATUS_BUSY (1 << 7) +#define IDE_LEGACY_COMMAND 0x07 // WO +#define IDE_LEGACY_ASTATUS 0x206 // RO +#define IDE_LEGACY_CTRL 0x206 // WO +#define IDE_LEGACY_CTRL_IDS 0x02 +#define IDE_LEGACY_CTRL_RST 0x04 +#define IDE_LEGACY_CTRL_4BIT 0x08 + +/**********************************************************************************/ + +#endif /* _CS5536_H */ diff --git a/arch/mips/lemote/lm2f/common/cs5536_pci.h b/arch/mips/lemote/lm2f/common/cs5536_pci.h new file mode 100644 index 0000000..eed94fb --- /dev/null +++ b/arch/mips/lemote/lm2f/common/cs5536_pci.h @@ -0,0 +1,181 @@ +/* + * cs5536_vsm.h + * the definition file of cs5536 Virtual Support Module(VSM). + * pci configuration space can be accessed through the VSM, so + * there is no need the MSR read/write now, except the spec. MSR + * registers which are not implemented yet. + * + * Author : jlliu + * Date : 07-07-04 + * + */ + +#ifndef _CS5536_PCI_H +#define _CS5536_PCI_H + +/**********************************************************************/ + +//#define TEST_CS5536_USE_FLASH +//#ifdef TEST_CS5536_USE_FLASH +//#define TEST_CS5536_USE_NOR_FLASH +//#endif +#define TEST_CS5536_USE_EHCI +#define TEST_CS5536_USE_UDC +#define TEST_CS5536_USE_OTG + +/**********************************************************************/ + +#define PCI_SPECIAL_SHUTDOWN 1 +#define CS5536_FLASH_INTR 6 +#define CS5536_ACC_INTR 9 +#define CS5536_IDE_INTR 14 +#define CS5536_USB_INTR 11 +#define CS5536_UART1_INTR 4 +#define CS5536_UART2_INTR 3 + +/************************* PCI BUS DEVICE FUNCTION ********************/ + +/* + * PCI bus device function + */ +#define PCI_BUS_CS5536 0 +#define PCI_IDSEL_CS5536 14 +#define PCI_CFG_BASE 0x02000000 + +#define CS5536_ISA_FUNC 0 +#define CS5536_FLASH_FUNC 1 +#define CS5536_IDE_FUNC 2 +#define CS5536_ACC_FUNC 3 +#define CS5536_OHCI_FUNC 4 +#define CS5536_EHCI_FUNC 5 +#define CS5536_UDC_FUNC 6 +#define CS5536_OTG_FUNC 7 +#define CS5536_FUNC_START 0 +#define CS5536_FUNC_END 7 +#define CS5536_FUNC_COUNT (CS5536_FUNC_END - CS5536_FUNC_START + 1) + +/***************************** STANDARD PCI-2.2 EXPANSION ***********************/ + +/* + * PCI configuration space + * we have to virtualize the PCI configure space head, so we should + * define the necessary IDs and some others. + */ +/* VENDOR ID */ +#define CS5536_VENDOR_ID 0x1022 + +/* DEVICE ID */ +#define CS5536_ISA_DEVICE_ID 0x2090 +#define CS5536_FLASH_DEVICE_ID 0x2091 +#define CS5536_IDE_DEVICE_ID 0x209a +#define CS5536_ACC_DEVICE_ID 0x2093 +#define CS5536_OHCI_DEVICE_ID 0x2094 +#define CS5536_EHCI_DEVICE_ID 0x2095 +#define CS5536_UDC_DEVICE_ID 0x2096 +#define CS5536_OTG_DEVICE_ID 0x2097 + +/* CLASS CODE : CLASS SUB-CLASS INTERFACE */ +#define CS5536_ISA_CLASS_CODE 0x060100 +#define CS5536_FLASH_CLASS_CODE 0x050100 +#define CS5536_IDE_CLASS_CODE 0x010180 +#define CS5536_ACC_CLASS_CODE 0x040100 +#define CS5536_OHCI_CLASS_CODE 0x0C0310 +#define CS5536_EHCI_CLASS_CODE 0x0C0320 +#define CS5536_UDC_CLASS_CODE 0x0C03FE +#define CS5536_OTG_CLASS_CODE 0x0C0380 + +/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */ +#define PCI_NONE_BIST 0x00 //RO not implemented yet. +#define PCI_BRIDGE_HEADER_TYPE 0x80 //RO +#define PCI_NORMAL_HEADER_TYPE 0x00 +#define PCI_NORMAL_LATENCY_TIMER 0x00 +#define PCI_NORMAL_CACHE_LINE_SIZE 0x08 //RW + +/* BAR */ +#define PCI_BAR0_REG 0x10 +#define PCI_BAR1_REG 0x14 +#define PCI_BAR2_REG 0x18 +#define PCI_BAR3_REG 0x1c +#define PCI_BAR4_REG 0x20 +#define PCI_BAR5_REG 0x24 +#define PCI_BAR_COUNT 6 +#define PCI_BAR_RANGE_MASK 0xFFFFFFFF + +/* CARDBUS CIS POINTER */ +#define PCI_CARDBUS_CIS_POINTER 0x00000000 + +/* SUBSYSTEM VENDOR ID */ +#define CS5536_SUB_VENDOR_ID CS5536_VENDOR_ID + +/* SUBSYSTEM ID */ +#define CS5536_ISA_SUB_ID CS5536_ISA_DEVICE_ID +#define CS5536_FLASH_SUB_ID CS5536_FLASH_DEVICE_ID +#define CS5536_IDE_SUB_ID CS5536_IDE_DEVICE_ID +#define CS5536_ACC_SUB_ID CS5536_ACC_DEVICE_ID +#define CS5536_OHCI_SUB_ID CS5536_OHCI_DEVICE_ID +#define CS5536_EHCI_SUB_ID CS5536_EHCI_DEVICE_ID +#define CS5536_UDC_SUB_ID CS5536_UDC_DEVICE_ID +#define CS5536_OTG_SUB_ID CS5536_OTG_DEVICE_ID + +/* EXPANSION ROM BAR */ +#define PCI_EXPANSION_ROM_BAR 0x00000000 + +/* CAPABILITIES POINTER */ +#define PCI_CAPLIST_POINTER 0x00000000 +#define PCI_CAPLIST_USB_POINTER 0x40 +/* INTERRUPT */ +#define PCI_MAX_LATENCY 0x40 +#define PCI_MIN_GRANT 0x00 +#define PCI_DEFAULT_PIN 0x01 + +/**************************** EXPANSION PCI REG **************************************/ + +/* + * ISA EXPANSION + */ +#define PCI_UART1_INT_REG 0x50 +#define PCI_UART2_INT_REG 0x54 +#define PCI_ISA_FIXUP_REG 0x58 + +/* + * FLASH EXPANSION + */ +#define PCI_FLASH_INT_REG 0x50 +#define PCI_NOR_FLASH_CTRL_REG 0x40 +#define PCI_NOR_FLASH_T01_REG 0x44 +#define PCI_NOR_FLASH_T23_REG 0x48 +#define PCI_NAND_FLASH_TDATA_REG 0x60 +#define PCI_NAND_FLASH_TCTRL_REG 0x64 +#define PCI_NAND_FLASH_RSVD_REG 0x68 +#define PCI_FLASH_SELECT_REG 0x70 + +/* + * IDE EXPANSION + */ +#define PCI_IDE_CFG_REG 0x40 +#define CS5536_IDE_FLASH_SIGNATURE 0xDEADBEEF +#define PCI_IDE_DTC_REG 0x48 +#define PCI_IDE_CAST_REG 0x4C +#define PCI_IDE_ETC_REG 0x50 +#define PCI_IDE_PM_REG 0x54 +#define PCI_IDE_INT_REG 0x60 + +/* + * ACC EXPANSION + */ +#define PCI_ACC_INT_REG 0x50 + +/* + * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI + */ +#define PCI_OHCI_PM_REG 0x40 +#define PCI_OHCI_INT_REG 0x50 + +/* + * EHCI EXPANSION + */ +#define PCI_EHCI_LEGSMIEN_REG 0x50 +#define PCI_EHCI_LEGSMISTS_REG 0x54 +#define PCI_EHCI_FLADJ_REG 0x60 + +#endif /* _CS5536_PCI_H_ */ diff --git a/arch/mips/lemote/lm2f/common/cs5536_vsm.c b/arch/mips/lemote/lm2f/common/cs5536_vsm.c new file mode 100644 index 0000000..01b06b1 --- /dev/null +++ b/arch/mips/lemote/lm2f/common/cs5536_vsm.c @@ -0,0 +1,2294 @@ +/* + * pci_machdep_cs5536.c + * the Virtual Support Module(VSM) for virtulize the PCI configure + * space. so user can access the PCI configure space directly as + * a normal multi-function PCI device which following the PCI-2.2 spec. + * + * Author : jlliu + * Date : 07-07-05 + * + */ +#include + +#include "cs5536.h" +#include "cs5536_pci.h" +#include "pcireg.h" + +extern void _wrmsr(u32 reg, u32 hi, u32 lo); +extern void _rdmsr(u32 reg, u32 *hi, u32 *lo); + +/******************************INTERNAL USED FUNCTIONS***********************************/ + +/* + * divil_lbar_enable_disable : enable/disable the divil module bar space. + * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg + * and the RCONFx(0~5) reg to use the modules. + */ +static void divil_lbar_enable_disable(int enable) +{ + u32 hi, lo; + + /* + * The DIVIL IRQ is not used yet. and make the RCONF0 reserved. + */ + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); + if(enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); + if(enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &lo); + if(enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), &hi, &lo); + if(enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), &hi, &lo); + if(enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), hi, lo); + + /* + * RCONF0 is reserved to the DIVIL IRQ mdoule + */ +#if 0 + _rdmsr(SB_MSR_REG(SB_R1), &hi, &lo); + if(enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R1), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R2), &hi, &lo); + if(enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R2), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R3), &hi, &lo); + if(enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R3), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R4), &hi, &lo); + if(enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R4), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R5), &hi, &lo); + if(enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R5), hi, lo); +#endif + return; +} + +#ifdef TEST_CS5536_USE_FLASH +/* + * flash_lbar_enable_disable : enable or disable the region of flashs(NOR or NAND) + * the same as the DIVIL other modules above, two groups of regs should be modified + * here to control the region. DIVIL flash LBAR and the RCONFx(6~9 reserved). + */ +static void flash_lbar_enable_disable(int enable) +{ + u32 hi, lo; + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + if(enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo); + if(enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo); + if(enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo); + + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo); + if(enable) + hi |= 0x01; + else + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R6), &hi, &lo); + if(enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R6), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R7), &hi, &lo); + if(enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R7), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R8), &hi, &lo); + if(enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R8), hi, lo); + + _rdmsr(SB_MSR_REG(SB_R9), &hi, &lo); + if(enable) + lo |= 0x01; + else + lo &= ~0x01; + _wrmsr(SB_MSR_REG(SB_R9), hi, lo); + + return; +} +#endif + + +/**********************************MODULES*********************************************/ + +/* + * isa_write : isa write transfering. + * WE assume that the ISA is not the BUS MASTER.!!! + */ +/* FAST BACK TO BACK '1' for BUS MASTER '0' for BUS SALVE */ +/* COMMAND : + * bit0 : IO SPACE ENABLE + * bit1 : MEMORY SPACE ENABLE(ignore) + * bit2 : BUS MASTER ENABLE(ignore) + * bit3 : SPECIAL CYCLE(ignore)? default is ignored. + * bit4 : MEMORY WRITE and INVALIDATE(ignore) + * bit5 : VGA PALETTE(ignore) + * bit6 : PARITY ERROR(ignore)? : default is ignored. + * bit7 : WAIT CYCLE CONTROL(ignore) + * bit8 : SYSTEM ERROR(ignore) + * bit9 : FAST BACK TO BACK(ignore) + * bit10-bit15 : RESERVED + * STATUS : + * bit0-bit3 : RESERVED + * bit4 : CAPABILITY LIST(ignore) + * bit5 : 66MHZ CAPABLE + * bit6 : RESERVED + * bit7 : FAST BACK TO BACK(ignore) + * bit8 : DATA PARITY ERROR DETECED(ignore) + * bit9-bit10 : DEVSEL TIMING(ALL MEDIUM) + * bit11: SIGNALED TARGET ABORT + * bit12: RECEIVED TARGET ABORT + * bit13: RECEIVED MASTER ABORT + * bit14: SIGNALED SYSTEM ERROR + * bit15: DETECTED PARITY ERROR + */ +static void pci_isa_write_reg(int reg, u32 value) +{ + u32 hi, lo; + u32 temp; + + switch(reg){ + case PCI_COMMAND_STATUS_REG : + // command + if( value & PCI_COMMAND_IO_ENABLE ){ + divil_lbar_enable_disable(1); + }else{ + divil_lbar_enable_disable(0); + } +#if 0 + /* PER response enable or disable. */ + if( value & PCI_COMMAND_PARITY_ENABLE ){ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + lo |= SB_PARE_ERR_EN; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + }else{ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + lo &= ~SB_PARE_ERR_EN; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } +#endif + // status + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + temp = lo & 0x0000ffff; + if( (value & PCI_STATUS_TARGET_TARGET_ABORT) && + (lo & SB_TAS_ERR_EN) ){ + temp |= SB_TAS_ERR_FLAG; + } + if( (value & PCI_STATUS_MASTER_TARGET_ABORT) && + (lo & SB_TAR_ERR_EN) ){ + temp |= SB_TAR_ERR_FLAG; + } + if( (value & PCI_STATUS_MASTER_ABORT) && + (lo & SB_MAR_ERR_EN) ){ + temp |= SB_MAR_ERR_FLAG; + } + if( (value & PCI_STATUS_PARITY_DETECT) && + (lo & SB_PARE_ERR_EN) ){ + temp |= SB_PARE_ERR_FLAG; + } + lo = temp; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + break; + case PCI_BHLC_REG : + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR0_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_SMB_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + // SMB NATIVE IO space has 8bytes + hi = 0x0000f001; + lo = value & 0x0000fff8; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), hi, lo); + + // RCONFx is 4bytes in units for IO space. + hi = ((value & 0x000ffffc) << 12) | ((CS5536_SMB_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R0), hi, lo); + } + break; + case PCI_BAR1_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_GPIO_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + // GPIO NATIVE reg is 256bytes + hi = 0x0000f001; + lo = value & 0x0000ff00; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), hi, lo); + + // RCONFx is 4bytes in units for IO space + hi = ((value & 0x000ffffc) << 12) | ((CS5536_GPIO_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R1), hi, lo); + } + break; + case PCI_BAR2_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_MFGPT_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + // MFGPT NATIVE reg is 64bytes + hi = 0x0000f001; + lo = value & 0x0000ffc0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), hi, lo); + + // RCONFx is 4bytes in units for IO space + hi = ((value & 0x000ffffc) << 12) | ((CS5536_MFGPT_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R2), hi, lo); + } + break; + case PCI_BAR3_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_IRQ_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + // IRQ NATIVE reg is 32bytes + hi = 0x0000f001; + lo = value & 0x0000ffc0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_IRQ), hi, lo); + + // RCONFx is 4bytes in units for IO space + hi = ((value & 0x000ffffc) << 12) | ((CS5536_IRQ_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R3), hi, lo); + } + break; + case PCI_BAR4_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_PMS_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + // PMS NATIVE reg is 128bytes + hi = 0x0000f001; + lo = value & 0x0000ff80; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), hi, lo); + + // RCONFx is 4bytes in units for IO space. + hi = ((value & 0x000ffffc) << 12) | ((CS5536_PMS_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R4), hi, lo); + } + break; + case PCI_BAR5_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_ACPI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + // ACPI NATIVE reg is 32bytes + hi = 0x0000f001; + lo = value & 0x0000ffe0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), hi, lo); + + // RCONFx is 4bytes in units for IO space. + hi = ((value & 0x000ffffc) << 12) | ((CS5536_ACPI_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R5), hi, lo); + } + break; + case PCI_UART1_INT_REG : + if(value){ + /* enable uart1 interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + lo &= ~(0xf << 24); + lo |= (CS5536_UART1_INTR << 24); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + }else{ + /* disable uart1 interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + lo &= ~(0xf << 24); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + } + break; + case PCI_UART2_INT_REG : + if(value){ + /* enable uart2 interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + lo &= ~(0xf << 28); + lo |= (CS5536_UART2_INTR << 28); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + }else{ + /* disable uart2 interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + lo &= ~(0xf << 28); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + } + break; + case PCI_ISA_FIXUP_REG : + if(value){ + /* enable the TARGET ABORT/MASTER ABORT etc. */ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + lo |= 0x00000063; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + + default : + /* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */ + break; + } + + return; +} + +/* + * isa_read : isa read transfering. + * we assume that the ISA is not the BUS MASTER. + */ + + /* COMMAND : + * bit0 : IO SPACE ENABLE + * bit1 : MEMORY SPACE ENABLE(ignore) + * bit2 : BUS MASTER ENABLE(ignore) + * bit3 : SPECIAL CYCLE(ignore)? default is ignored. + * bit4 : MEMORY WRITE and INVALIDATE(ignore) + * bit5 : VGA PALETTE(ignore) + * bit6 : PARITY ERROR(ignore)? : default is ignored. + * bit7 : WAIT CYCLE CONTROL(ignore) + * bit8 : SYSTEM ERROR(ignore) + * bit9 : FAST BACK TO BACK(ignore) + * bit10-bit15 : RESERVED + * STATUS : + * bit0-bit3 : RESERVED + * bit4 : CAPABILITY LIST(ignore) + * bit5 : 66MHZ CAPABLE + * bit6 : RESERVED + * bit7 : FAST BACK TO BACK(ignore) + * bit8 : DATA PARITY ERROR DETECED(ignore)? + * bit9-bit10 : DEVSEL TIMING(ALL MEDIUM) + * bit11: SIGNALED TARGET ABORT + * bit12: RECEIVED TARGET ABORT + * bit13: RECEIVED MASTER ABORT + * bit14: SIGNALED SYSTEM ERROR + * bit15: DETECTED PARITY ERROR(?) + */ + +static u32 pci_isa_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch(reg){ + case PCI_ID_REG : + conf_data = (CS5536_ISA_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG : + conf_data = 0; + // COMMAND + // we just check the first LBAR for the IO enable bit, + // maybe we should changed later. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); + if(hi & 0x01){ + conf_data |= PCI_COMMAND_IO_ENABLE; + } + //conf_data |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE; +#if 0 + conf_data |= PCI_COMMAND_SPECIAL_ENABLE; +#endif +#if 0 + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_EN){ + conf_data |= PCI_COMMAND_PARITY_ENABLE; + }else{ + conf_data &= ~PCI_COMMAND_PARITY_ENABLE; + } +#endif + // STATUS + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; +#if 1 + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; +#endif + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_TAS_ERR_FLAG) + conf_data |= PCI_STATUS_TARGET_TARGET_ABORT; + if(lo & SB_TAR_ERR_FLAG) + conf_data |= PCI_STATUS_MASTER_TARGET_ABORT; + if(lo & SB_MAR_ERR_FLAG) + conf_data |= PCI_STATUS_MASTER_ABORT; + if(lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_DETECT; + break; + case PCI_CLASS_REG : + _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ISA_CLASS_CODE << 8); + break; + case PCI_BHLC_REG : + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = (PCI_NONE_BIST << 24) | (PCI_BRIDGE_HEADER_TYPE << 16) | + (hi << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + /* + * we only use the LBAR of DIVIL, no RCONF used. + * all of them are IO space. + */ + case PCI_BAR0_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_SMB_FLAG){ + conf_data = CS5536_SMB_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_SMB_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); + conf_data = lo & 0x0000fff8; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR1_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_GPIO_FLAG){ + conf_data = CS5536_GPIO_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_GPIO_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); + conf_data = lo & 0x0000ff00; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR2_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_MFGPT_FLAG){ + conf_data = CS5536_MFGPT_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_MFGPT_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &lo); + conf_data = lo & 0x0000ffc0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; +#if 1 + case PCI_BAR3_REG : + conf_data = 0; + break; +#else + case PCI_BAR3_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_IRQ_FLAG){ + conf_data = CS5536_IRQ_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_IRQ_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_IRQ), &hi, &lo); + conf_data = lo & 0x0000ffc0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; +#endif + case PCI_BAR4_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_PMS_FLAG){ + conf_data = CS5536_PMS_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_PMS_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_PMS), &hi, &lo); + conf_data = lo & 0x0000ff80; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR5_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_ACPI_FLAG){ + conf_data = CS5536_ACPI_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_ACPI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_ACPI), &hi, &lo); + conf_data = lo & 0x0000ffe0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_CARDBUS_CIS_REG : + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG : + conf_data = (CS5536_ISA_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM : + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG : + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_REG : + conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (0x00 << 8) | 0x00; + break; + default : + conf_data = 0; + break; + } + + return conf_data; +} + +#ifdef TEST_CS5536_USE_FLASH + +#ifndef TEST_CS5536_USE_NOR_FLASH /* for nand flash */ +static void pci_flash_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch(reg){ + case PCI_COMMAND_STATUS_REG : + // command + if( value & PCI_COMMAND_MEM_ENABLE ){ + flash_lbar_enable_disable(1); + }else{ + flash_lbar_enable_disable(0); + } + // STATUS + if(value & PCI_STATUS_PARITY_ERROR){ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG){ + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG : + if(value == PCI_BAR_RANGE_MASK){ + // make the flag for reading the bar length. + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH0_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if( (value & 0x01) == 0x00 ){ + // mem space nand flash native reg base addr + hi = 0xfffff007; + lo = value & 0xfffff000; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo); + + // RCONFx is 4KB in units for mem space. + hi = ((value & 0xfffff000) << 12) | ( (CS5536_FLSH0_LENGTH & 0xfffff000) - (1 << 12) ) | 0x00; + lo = ((value & 0xfffff000) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R6), hi, lo); + } + break; + case PCI_BAR1_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH1_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if( (value & 0x01) == 0x00 ){ + // mem space nand flash native reg base addr + hi = 0xfffff007; + lo = value & 0xfffff000; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo); + + // RCONFx is 4KB in units for mem space. + hi = ((value & 0xfffff000) << 12) | ( (CS5536_FLSH1_LENGTH & 0xfffff000) - (1 << 12) ) | 0x00; + lo = ((value & 0xfffff000) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R7), hi, lo); + } + break; + case PCI_BAR2_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH2_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if( (value & 0x01) == 0x00 ){ + // mem space nand flash native reg base addr + hi = 0xfffff007; + lo = value & 0xfffff000; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo); + + // RCONFx is 4KB in units for mem space. + hi = ((value & 0xfffff000) << 12) | ( (CS5536_FLSH2_LENGTH & 0xfffff000) - (1 << 12) ) | 0x00; + lo = ((value & 0xfffff000) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R8), hi, lo); + } + break; + case PCI_BAR3_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH3_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if( (value & 0x01) == 0x00 ){ + // mem space nand flash native reg base addr + hi = 0xfffff007; + lo = value & 0xfffff000; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo); + + // RCONFx is 4KB in units for mem space. + hi = ((value & 0xfffff000) << 12) | ( (CS5536_FLSH3_LENGTH & 0xfffff000)- (1 << 12) ) | 0x00; + lo = ((value & 0xfffff000) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R9), hi, lo); + } + break; + case PCI_FLASH_INT_REG : + if(value){ + /* enable all the flash interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT); + lo |= (CS5536_FLASH_INTR << PIC_YSEL_LOW_FLASH_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + }else{ + /* disable all the flash interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } + break; + case PCI_NAND_FLASH_TDATA_REG : + hi = 0; + lo = value; + _wrmsr(DIVIL_MSR_REG(NANDF_DATA), hi, lo); + break; + case PCI_NAND_FLASH_TCTRL_REG : + hi = 0; + lo = value & 0x00000fff; + _wrmsr(DIVIL_MSR_REG(NANDF_CTRL), hi, lo); + break; + case PCI_NAND_FLASH_RSVD_REG : + hi = 0; + lo = value; + _wrmsr(DIVIL_MSR_REG(NANDF_RSVD), hi, lo); + break; + case PCI_FLASH_SELECT_REG : + if(value == CS5536_IDE_FLASH_SIGNATURE){ + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } + break; + default : + break; + } + + return; +} + +static u32 pci_flash_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch(reg){ + case PCI_ID_REG : + conf_data = (CS5536_FLASH_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG : + conf_data = 0; + // COMMAND + // we just read one lbar for returning. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + if(hi & 0x01) + conf_data |= PCI_COMMAND_MEM_ENABLE; + //STATUS + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG : + _rdmsr(DIVIL_MSR_REG(DIVIL_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_FLASH_CLASS_CODE << 8); + break; + case PCI_BHLC_REG : + conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) | + (PCI_NORMAL_LATENCY_TIMER << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_FLSH0_FLAG){ + conf_data = CS5536_FLSH0_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH0_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + conf_data = lo; + conf_data &= ~0x0f; + } + break; + case PCI_BAR1_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_FLSH1_FLAG){ + conf_data = CS5536_FLSH1_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH1_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo); + conf_data = lo; + conf_data &= ~0x0f; + } + break; + case PCI_BAR2_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_FLSH2_FLAG){ + conf_data = CS5536_FLSH2_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH2_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo); + conf_data = lo; + conf_data &= ~0x0f; + } + break; + case PCI_BAR3_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_FLSH3_FLAG){ + conf_data = CS5536_FLSH3_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH3_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo); + conf_data = lo; + conf_data &= ~0x0f; + } + break; + case PCI_CARDBUS_CIS_REG : + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG : + conf_data = (CS5536_FLASH_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM : + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG : + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_REG : + conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR); + break; + case PCI_NAND_FLASH_TDATA_REG : + _rdmsr(DIVIL_MSR_REG(NANDF_DATA), &hi, &lo); + conf_data = lo; + break; + case PCI_NAND_FLASH_TCTRL_REG : + _rdmsr(DIVIL_MSR_REG(NANDF_CTRL), &hi, &lo); + conf_data = lo & 0x00000fff; + break; + case PCI_NAND_FLASH_RSVD_REG : + _rdmsr(DIVIL_MSR_REG(NANDF_RSVD), &hi, &lo); + conf_data = lo; + break; + case PCI_FLASH_SELECT_REG : + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + conf_data = lo & 0x01; + break; + + } + return 0; +} + +#else /* nor flash */ + +static void pci_flash_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch(reg){ + case PCI_COMMAND_STATUS_REG : + // command + if( value & PCI_COMMAND_IO_ENABLE ){ + flash_lbar_enable_disable(1); + }else{ + flash_lbar_enable_disable(0); + } + // STATUS + if(value & PCI_STATUS_PARITY_ERROR){ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG){ + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH0_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + // IO space of 16bytes nor flash + hi = 0x0000fff1; + lo = value & 0x0000fff0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), hi, lo); + + // RCONFx used for 16bytes reserved. + hi = ((value & 0x000ffffc) << 12) | ((CS5536_FLSH0_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R6), hi, lo); + } + break; + case PCI_BAR1_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH1_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + // IO space of 16bytes nor flash + hi = 0x0000fff1; + lo = value & 0x0000fff0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), hi, lo); + + // RCONFx used for 16bytes reserved. + hi = ((value & 0x000ffffc) << 12) | ((CS5536_FLSH1_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R7), hi, lo); + } + break; + case PCI_BAR2_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH2_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + hi = 0x0000fff1; + lo = value & 0x0000fff0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), hi, lo); + + hi = ((value & 0x000ffffc) << 12) | ((CS5536_FLSH2_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R8), hi, lo); + } + break; + case PCI_BAR3_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_FLSH3_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + // 16bytes for nor flash + hi = 0x0000fff1; + lo = value & 0x0000fff0; + _wrmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), hi, lo); + + // 16bytes of IO space of RCONFx region. + hi = ((value & 0x000ffffc) << 12) | ((CS5536_FLSH3_LENGTH - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(SB_MSR_REG(SB_R9), hi, lo); + } + break; + + case PCI_INTERRUPT_REG : + conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR); + break; + case PCI_FLASH_INT_REG : + if(value){ + /* enable all the flash interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT); + lo |= (CS5536_FLASH_INTR << PIC_YSEL_LOW_FLASH_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + }else{ + /* disable all the flash interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_FLASH_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } + break; + case PCI_NOR_FLASH_CTRL_REG : + hi = 0; + lo = value & 0x000000ff; + _wrmsr(DIVIL_MSR_REG(NORF_CTRL), hi, lo); + break; + case PCI_NOR_FLASH_T01_REG : + hi = 0; + lo = value; + _wrmsr(DIVIL_MSR_REG(NORF_T01), hi, lo); + break; + case PCI_NOR_FLASH_T23_REG : + hi = 0; + lo = value; + _wrmsr(DIVIL_MSR_REG(NORF_T23), hi, lo); + break; + case PCI_FLASH_SELECT_REG : + if(value == CS5536_IDE_FLASH_SIGNATURE){ + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo &= ~0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } + break; + + default : + break; + } + + return; +} + +static u32 pci_flash_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch(reg){ + case PCI_ID_REG : + conf_data = (CS5536_FLASH_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG : + conf_data = 0; + // COMMAND + // we just check one flash bar for returning. + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + if(hi & 0x01) + conf_data |= PCI_COMMAND_IO_ENABLE; + //STATUS + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG : + _rdmsr(DIVIL_MSR_REG(DIVIL_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_FLASH_CLASS_CODE << 8); + break; + case PCI_BHLC_REG : + conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) | + (PCI_NORMAL_LATENCY_TIMER << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_FLSH0_FLAG){ + conf_data = CS5536_FLSH0_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH0_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH0), &hi, &lo); + conf_data = lo & 0x0000ffff; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR1_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_FLSH1_FLAG){ + conf_data = CS5536_FLSH1_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH1_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH1), &hi, &lo); + conf_data = lo & 0x0000ffff; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR2_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_FLSH2_FLAG){ + conf_data = CS5536_FLSH2_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH2_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH2), &hi, &lo); + conf_data = lo & 0x0000ffff; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR3_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_FLSH3_FLAG){ + conf_data = CS5536_FLSH3_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_FLSH3_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_FLSH3), &hi, &lo); + conf_data = lo & 0x0000ffff; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_CARDBUS_CIS_REG : + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG : + conf_data = (CS5536_FLASH_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM : + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG : + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_REG : + conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_FLASH_INTR); + break; + case PCI_NOR_FLASH_CTRL_REG : + _rdmsr(DIVIL_MSR_REG(NORF_CTRL), &hi, &lo); + conf_data = lo & 0x000000ff; + break; + case PCI_NOR_FLASH_T01_REG : + _rdmsr(DIVIL_MSR_REG(NORF_T01), &hi, &lo); + conf_data = lo; + break; + case PCI_NOR_FLASH_T23_REG : + _rdmsr(DIVIL_MSR_REG(NORF_T23), &hi, &lo); + conf_data = lo; + break; + default : + conf_data = 0; + break; + } + return conf_data; +} +#endif /* TEST_CS5536_USE_NOR_FLASH */ + +#else /* TEST_CS5536_USE_FLASH */ + +static void pci_flash_write_reg(int reg, u32 value) +{ + return; +} + +static u32 pci_flash_read_reg(int reg) +{ + return 0xffffffff; +} + +#endif /* TEST_CS5536_USE_FLASH */ + +/* + * ide_write : ide write transfering + */ +static void pci_ide_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch(reg){ + case PCI_COMMAND_STATUS_REG : + // COMMAND + if(value & PCI_COMMAND_MASTER_ENABLE){ + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + lo |= (0x03 << 4); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + }else{ + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + lo &= ~(0x03 << 4); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + } + // STATUS + if(value & PCI_STATUS_PARITY_ERROR){ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG){ + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BHLC_REG : + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR4_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if(value & 0x01){ + hi = 0x00000000; + //lo = ((value & 0x0fffffff) << 4) | 0x001; + lo = (value & 0xfffffff0) | 0x1; + _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo); + + value &= 0xfffffffc; + hi = 0x60000000 | ((value & 0x000ff000) >> 12); + lo = 0x000ffff0 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo); + } + break; + case PCI_IDE_CFG_REG : + if(value == CS5536_IDE_FLASH_SIGNATURE){ + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo |= 0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + }else{ + hi = 0; + lo = value; + _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo); + } + break; + case PCI_IDE_DTC_REG : + hi = 0; + lo = value; + _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo); + break; + case PCI_IDE_CAST_REG : + hi = 0; + lo = value; + _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo); + break; + case PCI_IDE_ETC_REG : + hi = 0; + lo = value; + _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo); + break; + case PCI_IDE_PM_REG : + hi = 0; + lo = value; + _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo); + break; + default : + break; + } + + return; +} + +/* + * ide_read : ide read tranfering. + */ +static u32 pci_ide_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch(reg){ + case PCI_ID_REG : + conf_data = (CS5536_IDE_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG : + conf_data = 0; + // COMMAND + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + if(lo & 0xfffffff0) + conf_data |= PCI_COMMAND_IO_ENABLE; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if( (lo & 0x30) == 0x30 ) + conf_data |= PCI_COMMAND_MASTER_ENABLE; + /* conf_data |= PCI_COMMAND_BACKTOBACK_ENABLE??? HOW TO GET..*/ + //STATUS + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG : + _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_IDE_CLASS_CODE << 8); + break; + case PCI_BHLC_REG : + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) | + (hi << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG : + conf_data = 0x00000000; + break; + case PCI_BAR1_REG : + conf_data = 0x00000000; + break; + case PCI_BAR2_REG : + conf_data = 0x00000000; + break; + case PCI_BAR3_REG : + conf_data = 0x00000000; + break; + case PCI_BAR4_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_IDE_FLAG){ + conf_data = CS5536_IDE_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + //conf_data = lo >> 4; + conf_data = lo & 0xfffffff0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR5_REG : + conf_data = 0x00000000; + break; + case PCI_CARDBUS_CIS_REG : + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG : + conf_data = (CS5536_IDE_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM : + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG : + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_REG : + conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_IDE_INTR); + break; + case PCI_IDE_CFG_REG : + _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_DTC_REG : + _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_CAST_REG : + _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_ETC_REG : + _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); + conf_data = lo; + case PCI_IDE_PM_REG : + _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); + conf_data = lo; + break; + + default : + conf_data = 0; + break; + } + + return conf_data; +} + +static void pci_acc_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch(reg){ + case PCI_COMMAND_STATUS_REG : + // COMMAND + if(value & PCI_COMMAND_MASTER_ENABLE){ + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + lo |= (0x03 << 8); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + }else{ + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + lo &= ~(0x03 << 8); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + } + // STATUS + if(value & PCI_STATUS_PARITY_ERROR){ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG){ + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if( value & 0x01 ){ + value &= 0xfffffffc; + hi = 0xA0000000 | ((value & 0x000ff000) >> 12); + lo = 0x000fff80 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo); + } + break; + case PCI_ACC_INT_REG : + if(value){ + /* enable all the acc interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT); + lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + }else{ + /* disable all the usb interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } + break; + default : + break; + } + + return; +} + +static u32 pci_acc_read_reg(int reg) +{ + u32 hi, lo; + u32 conf_data; + + switch(reg){ + case PCI_ID_REG : + conf_data = (CS5536_ACC_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG : + + conf_data = 0; + // COMMAND + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + if( ( (lo & 0xfff00000) || (hi & 0x000000ff) ) + && ((hi & 0xf0000000) == 0xa0000000) ) + conf_data |= PCI_COMMAND_IO_ENABLE; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if( (lo & 0x300) == 0x300 ) + conf_data |= PCI_COMMAND_MASTER_ENABLE; + /* conf_data |= PCI_COMMAND_BACKTOBACK_ENABLE??? HOW TO GET..*/ + //STATUS + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG : + _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ACC_CLASS_CODE << 8); + break; + case PCI_BHLC_REG : + conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) | + (PCI_NORMAL_LATENCY_TIMER << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_ACC_FLAG){ + conf_data = CS5536_ACC_RANGE | PCI_MAPREG_TYPE_IO; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + conf_data = (hi & 0x000000ff) << 12; + conf_data |= (lo & 0xfff00000) >> 20; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_BAR1_REG : + conf_data = 0x000000; + break; + case PCI_BAR2_REG : + conf_data = 0x000000; + break; + case PCI_BAR3_REG : + conf_data = 0x000000; + break; + case PCI_BAR4_REG : + conf_data = 0x000000; + break; + case PCI_BAR5_REG : + conf_data = 0x000000; + break; + case PCI_CARDBUS_CIS_REG : + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG : + conf_data = (CS5536_ACC_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM : + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG : + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_REG : + conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_ACC_INTR); + break; + default : + conf_data = 0; + break; + } + + return conf_data; +} + + +/* + * ohci_write : ohci write tranfering. + */ +static void pci_ohci_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch(reg){ + case PCI_COMMAND_STATUS_REG : + // COMMAND + if(value & PCI_COMMAND_MASTER_ENABLE){ + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + hi |= (1 << 2); + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + hi &= ~(1 << 2); + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + } + if(value & PCI_COMMAND_MEM_ENABLE){ + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + hi |= (1 << 1); + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + hi &= ~(1 << 1); + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + } + // STATUS + if(value & PCI_STATUS_PARITY_ERROR){ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG){ + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if( (value & 0x01) == 0x00 ){ + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + //lo = (value & 0xffffff00) << 8; + lo = value; + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo); + } + break; + case PCI_INTERRUPT_REG : + value &= 0x000000ff; + break; + case PCI_OHCI_PM_REG : + break; + case PCI_OHCI_INT_REG : + if(value){ + /* enable all the usb interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << 8); + lo |= (CS5536_USB_INTR << 8); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + }else{ + /* disable all the usb interrupt in PIC */ + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << 8); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + } + break; + default : + break; + } + + return; +} + +/* + * ohci_read : ohci read transfering. + */ +static u32 pci_ohci_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch(reg){ + case PCI_ID_REG : + conf_data = (CS5536_OHCI_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG : + conf_data = 0; + // COMMAND + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + if(hi & 0x04) + conf_data |= PCI_COMMAND_MASTER_ENABLE; + if(hi & 0x02) + conf_data |= PCI_COMMAND_MEM_ENABLE; + // STATUS + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG : + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_OHCI_CLASS_CODE << 8); + break; + case PCI_BHLC_REG : + conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) | + (0x00 << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_OHCI_FLAG){ + conf_data = CS5536_OHCI_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + //conf_data = lo >> 8; + conf_data = lo & 0xffffff00; + conf_data &= ~0x0000000f; // 32bit mem + } + break; + case PCI_BAR1_REG : + conf_data = 0x000000; + break; + case PCI_BAR2_REG : + conf_data = 0x000000; + break; + case PCI_BAR3_REG : + conf_data = 0x000000; + break; + case PCI_BAR4_REG : + conf_data = 0x000000; + break; + case PCI_BAR5_REG : + conf_data = 0x000000; + break; + case PCI_CARDBUS_CIS_REG : + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG : + conf_data = (CS5536_OHCI_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM : + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG : + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_REG : + conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR); + break; + case PCI_OHCI_PM_REG : + conf_data = 0; + break; + case PCI_OHCI_INT_REG : + _rdmsr(DIVIL_MSR_REG(0x20), &hi, &lo); + if((lo & 0x00000f00) == 11) + conf_data = 1; + else + conf_data = 0; + break; + default : + conf_data = 0; + break; + } + + return conf_data; +} + +#ifdef TEST_CS5536_USE_EHCI +static void pci_ehci_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch(reg){ + case PCI_COMMAND_STATUS_REG : + // COMMAND + if(value & PCI_COMMAND_MASTER_ENABLE){ + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi |= (1 << 2); + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= ~(1 << 2); + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + } + if(value & PCI_COMMAND_MEM_ENABLE){ + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi |= (1 << 1); + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= ~(1 << 1); + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + } + // STATUS + if(value & PCI_STATUS_PARITY_ERROR){ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG){ + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if( (value & 0x01) == 0x00 ){ + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + lo = value; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo); + } + break; + case PCI_EHCI_LEGSMIEN_REG : + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= 0x003f0000; + hi |= (value & 0x3f) << 16; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + case PCI_EHCI_FLADJ_REG : + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= ~0x00003f00; + hi |= value & 0x00003f00; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + default : + break; + } + + return; +} + +static u32 pci_ehci_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch(reg){ + case PCI_ID_REG : + conf_data = (CS5536_EHCI_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG : + conf_data = 0; + // COMMAND + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + if(hi & 0x04) + conf_data |= PCI_COMMAND_MASTER_ENABLE; + if(hi & 0x02) + conf_data |= PCI_COMMAND_MEM_ENABLE; + // STATUS + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG : + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_EHCI_CLASS_CODE << 8); + break; + case PCI_BHLC_REG : + conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) | + (PCI_NORMAL_LATENCY_TIMER << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_EHCI_FLAG){ + conf_data = CS5536_EHCI_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = lo & 0xfffff000; + } + break; + case PCI_BAR1_REG : + conf_data = 0x000000; + break; + case PCI_BAR2_REG : + conf_data = 0x000000; + break; + case PCI_BAR3_REG : + conf_data = 0x000000; + break; + case PCI_BAR4_REG : + conf_data = 0x000000; + break; + case PCI_BAR5_REG : + conf_data = 0x000000; + break; + case PCI_CARDBUS_CIS_REG : + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG : + conf_data = (CS5536_EHCI_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM : + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG : + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_REG : + conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR); + break; + case PCI_EHCI_LEGSMIEN_REG : + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x003f0000) >> 16; + break; + case PCI_EHCI_LEGSMISTS_REG : + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x3f000000) >> 24; + break; + case PCI_EHCI_FLADJ_REG : + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = hi & 0x00003f00; + break; + default : + conf_data = 0; + break; + } + + return conf_data; +} +#else +static void pci_ehci_write_reg(int reg, u32 value) +{ + return; +} + +static u32 pci_ehci_read_reg(int reg) +{ + return 0xffffffff; +} + + +#endif + +#ifdef TEST_CS5536_USE_UDC +static void pci_udc_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch(reg){ + case PCI_COMMAND_STATUS_REG : + // COMMAND + if(value & PCI_COMMAND_MASTER_ENABLE){ + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + hi |= (1 << 2); + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + hi &= ~(1 << 2); + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + } + if(value & PCI_COMMAND_MEM_ENABLE){ + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + hi |= (1 << 1); + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + hi &= ~(1 << 1); + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + } + // STATUS + if(value & PCI_STATUS_PARITY_ERROR){ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG){ + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_UDC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if( (value & 0x01) == 0x00 ){ + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + lo = value; + _wrmsr(USB_MSR_REG(USB_UDC), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM0), hi, lo); + } + break; + default : + break; + } + + return; +} + +static u32 pci_udc_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch(reg){ + case PCI_ID_REG : + conf_data = (CS5536_UDC_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG : + conf_data = 0; + // COMMAND + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + if(hi & 0x04) + conf_data |= PCI_COMMAND_MASTER_ENABLE; + if(hi & 0x02) + conf_data |= PCI_COMMAND_MEM_ENABLE; + // STATUS + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG : + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_UDC_CLASS_CODE << 8); + break; + case PCI_BHLC_REG : + conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) | + (0x00 << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_UDC_FLAG){ + conf_data = CS5536_UDC_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_UDC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_UDC), &hi, &lo); + conf_data = lo & 0xfffff000; + conf_data &= ~0x0000000f; // 32bit mem + } + break; + case PCI_BAR1_REG : + conf_data = 0x000000; + break; + case PCI_BAR2_REG : + conf_data = 0x000000; + break; + case PCI_BAR3_REG : + conf_data = 0x000000; + break; + case PCI_BAR4_REG : + conf_data = 0x000000; + break; + case PCI_BAR5_REG : + conf_data = 0x000000; + break; + case PCI_CARDBUS_CIS_REG : + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG : + conf_data = (CS5536_UDC_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM : + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG : + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_REG : + conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR); + break; + default : + conf_data = 0; + break; + } + + return conf_data; +} + +#else /* TEST_CS5536_USE_UDC */ + +static void pci_udc_write_reg(int reg, u32 value) +{ + return; +} + +static u32 pci_udc_read_reg(int reg) +{ + return 0xffffffff; +} + +#endif /* TEST_CS5536_USE_UDC */ + + +#ifdef TEST_CS5536_USE_OTG +static void pci_otg_write_reg(int reg, u32 value) +{ + u32 hi, lo; + + switch(reg){ + case PCI_COMMAND_STATUS_REG : + // COMMAND + if(value & PCI_COMMAND_MEM_ENABLE){ + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + hi |= (1 << 1); + _wrmsr(USB_MSR_REG(USB_OTG), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + hi &= ~(1 << 1); + _wrmsr(USB_MSR_REG(USB_OTG), hi, lo); + } + // STATUS + if(value & PCI_STATUS_PARITY_ERROR){ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG){ + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG : + if(value == PCI_BAR_RANGE_MASK){ + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_OTG_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else if( (value & 0x01) == 0x00 ){ + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + lo = value & 0xffffff00; + _wrmsr(USB_MSR_REG(USB_OTG), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM1), hi, lo); + } + break; + default : + break; + } + + return; +} + +static u32 pci_otg_read_reg(int reg) +{ + u32 conf_data; + u32 hi, lo; + + switch(reg){ + case PCI_ID_REG : + conf_data = (CS5536_OTG_DEVICE_ID << 16 | CS5536_VENDOR_ID); + break; + case PCI_COMMAND_STATUS_REG : + conf_data = 0; + // COMMAND + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + if(hi & 0x02) + conf_data |= PCI_COMMAND_MEM_ENABLE; + // STATUS + conf_data |= PCI_STATUS_66MHZ_SUPPORT; + conf_data |= PCI_STATUS_BACKTOBACK_SUPPORT; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if(lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY_ERROR; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REG : + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_OTG_CLASS_CODE << 8); + break; + case PCI_BHLC_REG : + conf_data = (PCI_NONE_BIST << 24) | (PCI_NORMAL_HEADER_TYPE << 16) | + (0x00 << 8) | PCI_NORMAL_CACHE_LINE_SIZE; + break; + case PCI_BAR0_REG : + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if(lo & SOFT_BAR_OTG_FLAG){ + conf_data = CS5536_OTG_RANGE | PCI_MAPREG_TYPE_MEM; + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo &= ~SOFT_BAR_OTG_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + }else{ + _rdmsr(USB_MSR_REG(USB_OTG), &hi, &lo); + conf_data = lo & 0xffffff00; + conf_data &= ~0x0000000f; + } + break; + case PCI_BAR1_REG : + conf_data = 0x000000; + break; + case PCI_BAR2_REG : + conf_data = 0x000000; + break; + case PCI_BAR3_REG : + conf_data = 0x000000; + break; + case PCI_BAR4_REG : + conf_data = 0x000000; + break; + case PCI_BAR5_REG : + conf_data = 0x000000; + break; + case PCI_CARDBUS_CIS_REG : + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYS_ID_REG : + conf_data = (CS5536_OTG_SUB_ID << 16) | CS5536_SUB_VENDOR_ID; + break; + case PCI_MAPREG_ROM : + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPLISTPTR_REG : + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_REG : + conf_data = (PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | + (PCI_DEFAULT_PIN << 8) | (CS5536_USB_INTR); + break; + default : + conf_data = 0; + break; + } + + return conf_data; +} + +#else /* TEST_CS5536_USE_OTG */ + +static void pci_otg_write_reg(int reg, u32 value) +{ + return; +} + +static u32 pci_otg_read_reg(int reg) +{ + return 0xffffffff; +} + +#endif /* TEST_CS5536_USE_OTG */ + +/*******************************************************************************/ + +/* + * writen : write to PCI config space and transfer it to MSR write. + */ +void cs5536_pci_conf_write4(int function, int reg, u32 value) +{ + /* some basic checking. */ + if( (function < CS5536_FUNC_START) || (function > CS5536_FUNC_END) ){ + return; + } + if( (reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0) ){ + return; + } + + switch(function){ + case CS5536_ISA_FUNC : + pci_isa_write_reg(reg, value); + break; + + case CS5536_FLASH_FUNC : + pci_flash_write_reg(reg, value); + break; + + case CS5536_IDE_FUNC : + pci_ide_write_reg(reg, value); + break; + + case CS5536_ACC_FUNC : + pci_acc_write_reg(reg, value); + break; + + case CS5536_OHCI_FUNC : + pci_ohci_write_reg(reg, value); + break; + + case CS5536_EHCI_FUNC : + pci_ehci_write_reg(reg, value); + break; + + case CS5536_UDC_FUNC : + pci_udc_write_reg(reg, value); + break; + + case CS5536_OTG_FUNC : + pci_otg_write_reg(reg, value); + break; + + default : + break; + } + + return; +} + +/* + * readn : read PCI config space and transfer it to MSR access. + */ +u32 cs5536_pci_conf_read4(int function, int reg) +{ + u32 data = 0; + + /* some basic checking. */ + if( (function < CS5536_FUNC_START) || (function > CS5536_FUNC_END) ){ + return 0; + } + if( (reg < 0) || ((reg & 0x03) != 0) ){ + return 0; + } + if( reg > 0x100 ) + return 0xffffffff; + + switch(function){ + case CS5536_ISA_FUNC : + data = pci_isa_read_reg(reg); + break; + + case CS5536_FLASH_FUNC : + data = pci_flash_read_reg(reg); + break; + + case CS5536_IDE_FUNC : + data = pci_ide_read_reg(reg); + break; + + case CS5536_ACC_FUNC : + data = pci_acc_read_reg(reg); + break; + + case CS5536_OHCI_FUNC : + data = pci_ohci_read_reg(reg); + break; + + case CS5536_EHCI_FUNC : + data = pci_ehci_read_reg(reg); + break; + + case CS5536_UDC_FUNC : + data = pci_udc_read_reg(reg); + break; + + case CS5536_OTG_FUNC : + data = pci_otg_read_reg(reg); + break; + + default : + break; + + } + + return data; +} + +/**************************************************************************/ + diff --git a/arch/mips/lemote/lm2f/common/mem.c b/arch/mips/lemote/lm2f/common/mem.c new file mode 100644 index 0000000..5916ed6 --- /dev/null +++ b/arch/mips/lemote/lm2f/common/mem.c @@ -0,0 +1,23 @@ +/* + * 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. + */ +#include +#include +#include + +/* override of arch/mips/mm/cache.c: __uncached_access */ +int __uncached_access(struct file *file, unsigned long addr) +{ + if (file->f_flags & O_SYNC) + return 1; + + /* + * On the Lemote Loongson 2f system, the peripheral registers + * reside between 0x1000:0000 and 0x8000:0000. + */ + return addr >= __pa(high_memory) || + ((addr >= 0x10000000) && (addr < 0x80000000)); +} diff --git a/arch/mips/lemote/lm2f/common/mfgpt.c b/arch/mips/lemote/lm2f/common/mfgpt.c new file mode 100644 index 0000000..e62a7fd --- /dev/null +++ b/arch/mips/lemote/lm2f/common/mfgpt.c @@ -0,0 +1,222 @@ +/* + * CS5536 General timer functions + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +DEFINE_SPINLOCK(mfgpt_lock); + +#if 1 +#define MFGFT_TICK_RATE 14318000 +#else +#define MFGFT_TICK_RATE (14318180 / 8) +#endif +#define COMPARE ((MFGFT_TICK_RATE + HZ/2) / HZ) + +extern void _wrmsr(u32 reg, u32 hi, u32 lo); +extern void _rdmsr(u32 reg, u32 *hi, u32 *lo); + +static u32 base ; + +/* + * Initialize the MFGPT timer. + * + * This is also called after resume to bring the MFGPT into operation again. + */ +/* setup register bit fields: + 15: counter enable + 14: compare2 output status, write 1 to clear when in event mode + 13: compare1 output status + 12: setup(ro) + 11: stop enable, stop on sleep + 10: external enable + 9:8 compare2 mode; 00: disable, 01: compare on equal; 10: compare on GE, 11 event: GE + irq + 7:6 compare1 mode + 5: reverse enable, bit reverse of the counter + 4: clock select. 0: 32KHz, 1: 14.318MHz + 3:0 counter prescaler scale factor. select the input clock divide-by value. 2^n + bit 11:0 is write once. +*/ + + +static void init_mfgpt_timer(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + spin_lock(&mfgpt_lock); + + switch(mode) { + case CLOCK_EVT_MODE_PERIODIC: + /* set comparator2 */ + outw(COMPARE, base + 2); + /* set counter to 0 */ + outw(0, base + 4); + /* setup; enable, comparator2 to event mode,14.318MHz clock */ + //outw(0xe313, base + 6); + outw(0xe310, base + 6); + break; + + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + if (evt->mode == CLOCK_EVT_MODE_PERIODIC || + evt->mode == CLOCK_EVT_MODE_ONESHOT) { + /* disable counter */ + outw(inw(base+6) & 0x7fff, base + 6); + } + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* One shot setup */ + break; + + case CLOCK_EVT_MODE_RESUME: + /* Nothing to do here */ + break; + } + spin_unlock(&mfgpt_lock); +} + +/* + * Program the next event in oneshot mode + * + * Delta is given in MFGPT ticks + */ +static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt) +{ + spin_lock(&mfgpt_lock); + + /* set comparator2 */ + outw(delta & 0xffff, base + 2); + /* set counter to 0 */ + outw(0, base + 4); + /* setup; enable, comparator2 */ + outw(0xe310, base + 6); + + spin_unlock(&mfgpt_lock); + + return 0; +} + +static struct clock_event_device mfgpt_clockevent = { + .name = "mfgpt", + .features = CLOCK_EVT_FEAT_PERIODIC, + .set_mode = init_mfgpt_timer, + .set_next_event = mfgpt_next_event, + .rating = 2000, + .irq = 5, +}; + +static irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + u32 basehi,baselo; + + _rdmsr(0x8000000d,&basehi,&baselo); + + base = baselo; + /* ack */ +// outw(0x0, baselo + 4); + outw(0xc000, baselo + 6); + + mfgpt_clockevent.event_handler(&mfgpt_clockevent); + + return IRQ_HANDLED; +} + +static struct irqaction irq5 = { + .handler = timer_interrupt, + .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .mask = CPU_MASK_NONE, + .name = "timer" +}; + +/* + * Initialize the conversion factor and the min/max deltas of the clock event + * structure and register the clock event source with the framework. + */ +void __init setup_mfgpt_timer(void) +{ + u32 basehi; + struct clock_event_device *cd = &mfgpt_clockevent; + unsigned int cpu = smp_processor_id(); + + cd->cpumask = cpumask_of_cpu(cpu); + clockevent_set_clock(cd, MFGFT_TICK_RATE); + cd->max_delta_ns = clockevent_delta2ns(0xFFFF, cd); + cd->min_delta_ns = clockevent_delta2ns(0xF, cd); + + /* connect multifunction timer0 comparator 2 to irq mapper*/ + _wrmsr(0x80000028, 0, 0x100); + + /* map unrestricted interrupt source Z4 to IG5 */ + _wrmsr(0x80000022, 0, 0x50000); + + _rdmsr(0x8000000d, &basehi, &base); + + irq5.mask = cpumask_of_cpu(cpu); + + clockevents_register_device(cd); + + setup_irq(5, &irq5); + +} + +/* + * Since the MFGPT overflows every tick, its not very useful + * to just read by itself. So use jiffies to emulate a free + * running counter: + */ +static cycle_t mfgpt_read(void) +{ + static cycle_t count, old_count; + static unsigned long old_jifs; + unsigned long jifs; + unsigned long flags; + + spin_lock_irqsave(&mfgpt_lock, flags); + + jifs = jiffies; + + count = inw(base + 4); + + /* overflow ?*/ + if (count < old_count && jifs == old_jifs) { + count = old_count; + } + old_count = count; + old_jifs = jifs; + + spin_unlock_irqrestore(&mfgpt_lock, flags); + + return (cycle_t)(jifs * COMPARE) + count; +} + +static struct clocksource clocksource_mfgpt = { + .name = "mfgpt", + .rating = 1200, + .read = mfgpt_read, + .mask = CLOCKSOURCE_MASK(32), + .mult = 0, + .shift = 22, +}; + +int __init init_mfgpt_clocksource(void) +{ + + if (num_possible_cpus() > 1) /* MFGPT does not scale! */ + return 0; + + setup_mfgpt_timer(); + + clocksource_mfgpt.mult = clocksource_hz2mult(MFGFT_TICK_RATE, 22); + return clocksource_register(&clocksource_mfgpt); +} +/* Too late for kernel calc delay */ +//arch_initcall(init_mfgpt_clocksource); diff --git a/arch/mips/lemote/lm2f/common/mipsdha.c b/arch/mips/lemote/lm2f/common/mipsdha.c new file mode 100644 index 0000000..fd90454 --- /dev/null +++ b/arch/mips/lemote/lm2f/common/mipsdha.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +static ssize_t mipsdha_proc_read(struct file *file, char *buf, size_t len, loff_t *ppos); + +static ssize_t mipsdha_proc_write(struct file *file, const char *buf, size_t len, loff_t *ppos); + + +static struct proc_dir_entry *mipsdha_proc_entry; + +#define INFO_SIZE 4096 +static char info_buf[INFO_SIZE]; + +static struct file_operations mipsdha_fops = +{ + owner: THIS_MODULE, + read: mipsdha_proc_read, + write: mipsdha_proc_write, +}; + +static enum {CMD_ERR, CMD_GIB, CMD_GPI} cmd; + +typedef struct pciinfo_s +{ + int bus,card,func; + unsigned short command; + unsigned short vendor,device; + unsigned base0,base1,base2,baserom; +} pciinfo_t; + + +extern struct proc_dir_entry proc_root; + +static int __init mipsdha_proc_init(void) +{ + mipsdha_proc_entry = create_proc_entry("mipsdha", S_IWUSR | S_IRUGO, &proc_root); + if (mipsdha_proc_entry == NULL) { + printk("MIPSDHA: register /proc/mipsdha failed!\n"); + return 0; + } + + mipsdha_proc_entry->owner = THIS_MODULE; + mipsdha_proc_entry->proc_fops = &mipsdha_fops; + + cmd=CMD_ERR; + return 0; +} + +static ssize_t mipsdha_proc_write (struct file *file, const char *buf, size_t len, loff_t *ppos) +{ + char cmd_gib[]="GET IO BASE"; + char cmd_gpi[]="GET PCI INFO"; + + if (len >= INFO_SIZE) return -ENOMEM; + + if (copy_from_user(info_buf, buf, len)) return -EFAULT; + info_buf[len] = '\0'; + + if (strncmp(info_buf, cmd_gib, sizeof(cmd_gib)-1)==0) { + cmd = CMD_GIB; + return len; + } else if (strncmp(info_buf, cmd_gpi, sizeof(cmd_gpi)-1)==0) { + cmd = CMD_GPI; + return len; + } else { + return -EINVAL; + } +} + +static ssize_t mipsdha_proc_read (struct file *file, char *buf, size_t len, loff_t *ppos) +{ + int info_cnt; + pciinfo_t *pciinfo; + struct pci_dev *dev = NULL; + + switch (cmd) { + default: + printk("MIPSDHA: BUG found in function %s!(cmd=%d)\n", + __FUNCTION__, cmd); + return -EINVAL; + + + case CMD_ERR: + return -EINVAL; + + + case CMD_GIB: + *(unsigned long *)info_buf = + virt_to_phys((void *) mips_io_port_base); + info_cnt=sizeof(unsigned long); + break; + + + case CMD_GPI: + pciinfo = (pciinfo_t *) info_buf; + info_cnt = 0; + for_each_pci_dev(dev) { + + if (info_cnt+sizeof(pciinfo_t)>INFO_SIZE) return -ENOMEM; + + pciinfo->bus = dev->bus->number; + pciinfo->card = PCI_SLOT(dev->devfn); + pciinfo->func = PCI_FUNC(dev->devfn); + + if (pci_read_config_word(dev, PCI_COMMAND, &pciinfo->command) + != PCIBIOS_SUCCESSFUL) { + printk("MIPSDHA: BUG found in function %s!\n", + __FUNCTION__); + pciinfo->command=0; + } + + pciinfo->vendor = dev->vendor; + pciinfo->device = dev->device; + + pciinfo->base0 = (dev->resource[0]).start; + pciinfo->base1 = (dev->resource[1]).start; + pciinfo->base2 = (dev->resource[2]).start; + pciinfo->baserom = (dev->resource[PCI_ROM_RESOURCE]).start; + + pciinfo++; + info_cnt += sizeof(pciinfo_t); + } + break; + } + + if (len < info_cnt) return -ENOMEM; + if (copy_to_user(buf, info_buf, info_cnt)) return -EFAULT; + + return info_cnt; +} + +__initcall(mipsdha_proc_init); diff --git a/arch/mips/lemote/lm2f/common/pci.c b/arch/mips/lemote/lm2f/common/pci.c new file mode 100644 index 0000000..91f6abb --- /dev/null +++ b/arch/mips/lemote/lm2f/common/pci.c @@ -0,0 +1,89 @@ +/* + * pci.c + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include +#include + +extern struct pci_ops loongson2f_pci_pci_ops; +/* if you want to expand the pci memory space, you should config 64bits kernel too. */ + +static struct resource loongson2f_pci_mem_resource = { + .name = "LOONGSON2F PCI MEM", + .start = 0x14000000UL, + .end = 0x1fffffffUL, + .flags = IORESOURCE_MEM, +}; + +static struct resource loongson2f_pci_io_resource = { + .name = "LOONGSON2F PCI IO MEM", + .start = 0x00004000UL, + .end = 0x0000ffffUL, + .flags = IORESOURCE_IO, +}; + + +static struct pci_controller loongson2f_pci_controller = { + .pci_ops = &loongson2f_pci_pci_ops, + .io_resource = &loongson2f_pci_io_resource, + .mem_resource = &loongson2f_pci_mem_resource, + .mem_offset = 0x00000000UL, + .io_offset = 0x00000000UL, +}; + +static int __init pcibios_init(void) +{ + extern int pci_probe_only; + pci_probe_only = 0; + +#ifdef CONFIG_TRACE_BOOT + printk(KERN_INFO"arch_initcall:pcibios_init\n"); + printk(KERN_INFO"register_pci_controller : %x\n",&loongson2f_pci_controller); +#endif + +#ifdef CONFIG_64BIT + loongson2f_pci_mem_resource.start = 0x50000000UL; + loongson2f_pci_mem_resource.end = 0x7fffffffUL; + __asm__(".set mips3\n" + "dli $2,0x900000003ff00000\n" + "li $3,0x40000000\n" + "sd $3,0x18($2)\n" + "or $3,1\n" + "sd $3,0x58($2)\n" + "dli $3,0xffffffffc0000000\n" + "sd $3,0x38($2)\n" + ".set mips0\n" + :::"$2","$3","memory" + ); +#endif + loongson2f_pci_controller.io_map_base = mips_io_port_base; + register_pci_controller(&loongson2f_pci_controller); + return 0; +} + +arch_initcall(pcibios_init); diff --git a/arch/mips/lemote/lm2f/common/pcireg.h b/arch/mips/lemote/lm2f/common/pcireg.h new file mode 100644 index 0000000..aa823d3 --- /dev/null +++ b/arch/mips/lemote/lm2f/common/pcireg.h @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2001, 2006 www.ict.ac.cn. + * Copyright (c) 2006, 2008 www.lemote.com.cn. + * + * 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 named License, + * or 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. + */ + +#ifndef _DEV_PCI_PCIREG_H_ +#define _DEV_PCI_PCIREG_H_ + + +/* + * Standardized PCI configuration information + * + * XXX This is not complete. + */ + +/* + * Device identification register; contains a vendor ID and a device ID. + */ +#define PCI_ID_REG 0x00 + +typedef u_int16_t pci_vendor_id_t; +typedef u_int16_t pci_product_id_t; + +#define PCI_VENDOR_SHIFT 0 +#define PCI_VENDOR_MASK 0xffff +#define PCI_VENDOR(id) \ + (((id) >> PCI_VENDOR_SHIFT) & PCI_VENDOR_MASK) + +#define PCI_PRODUCT_SHIFT 16 +#define PCI_PRODUCT_MASK 0xffff +#define PCI_PRODUCT(id) \ + (((id) >> PCI_PRODUCT_SHIFT) & PCI_PRODUCT_MASK) + +/* + * Command and status register. + */ +#define PCI_COMMAND_STATUS_REG 0x04 + +#define PCI_COMMAND_IO_ENABLE 0x00000001 +#define PCI_COMMAND_MEM_ENABLE 0x00000002 +#define PCI_COMMAND_MASTER_ENABLE 0x00000004 +#define PCI_COMMAND_SPECIAL_ENABLE 0x00000008 +#define PCI_COMMAND_INVALIDATE_ENABLE 0x00000010 +#define PCI_COMMAND_PALETTE_ENABLE 0x00000020 +#define PCI_COMMAND_PARITY_ENABLE 0x00000040 +#define PCI_COMMAND_STEPPING_ENABLE 0x00000080 +#define PCI_COMMAND_SERR_ENABLE 0x00000100 +#define PCI_COMMAND_BACKTOBACK_ENABLE 0x00000200 + +#define PCI_STATUS_CAPLIST_SUPPORT 0x00100000 +#define PCI_STATUS_66MHZ_SUPPORT 0x00200000 +#define PCI_STATUS_UDF_SUPPORT 0x00400000 +#define PCI_STATUS_BACKTOBACK_SUPPORT 0x00800000 +#define PCI_STATUS_PARITY_ERROR 0x01000000 +#define PCI_STATUS_DEVSEL_FAST 0x00000000 +#define PCI_STATUS_DEVSEL_MEDIUM 0x02000000 +#define PCI_STATUS_DEVSEL_SLOW 0x04000000 +#define PCI_STATUS_DEVSEL_MASK 0x06000000 +#define PCI_STATUS_TARGET_TARGET_ABORT 0x08000000 +#define PCI_STATUS_MASTER_TARGET_ABORT 0x10000000 +#define PCI_STATUS_MASTER_ABORT 0x20000000 +#define PCI_STATUS_SPECIAL_ERROR 0x40000000 +#define PCI_STATUS_PARITY_DETECT 0x80000000 + +/* + * PCI Class and Revision Register; defines type and revision of device. + */ +#define PCI_CLASS_REG 0x08 + +typedef u_int8_t pci_class_t; +typedef u_int8_t pci_subclass_t; +typedef u_int8_t pci_interface_t; +typedef u_int8_t pci_revision_t; + +#define PCI_CLASS_SHIFT 24 +#define PCI_CLASS_MASK 0xff +#define PCI_CLASS(cr) \ + (((cr) >> PCI_CLASS_SHIFT) & PCI_CLASS_MASK) + +#define PCI_SUBCLASS_SHIFT 16 +#define PCI_SUBCLASS_MASK 0xff +#define PCI_SUBCLASS(cr) \ + (((cr) >> PCI_SUBCLASS_SHIFT) & PCI_SUBCLASS_MASK) + +#define PCI_ISCLASS(what, class, subclass) \ + (((what) & 0xffff0000) == (class << 24 | subclass << 16)) + +#define PCI_INTERFACE_SHIFT 8 +#define PCI_INTERFACE_MASK 0xff +#define PCI_INTERFACE(cr) \ + (((cr) >> PCI_INTERFACE_SHIFT) & PCI_INTERFACE_MASK) + +#define PCI_REVISION_SHIFT 0 +#define PCI_REVISION_MASK 0xff +#define PCI_REVISION(cr) \ + (((cr) >> PCI_REVISION_SHIFT) & PCI_REVISION_MASK) + +/* base classes */ +#define PCI_CLASS_PREHISTORIC 0x00 +#define PCI_CLASS_MASS_STORAGE 0x01 +#define PCI_CLASS_NETWORK 0x02 +#define PCI_CLASS_DISPLAY 0x03 +#define PCI_CLASS_MULTIMEDIA 0x04 +#define PCI_CLASS_MEMORY 0x05 +#define PCI_CLASS_BRIDGE 0x06 +#define PCI_CLASS_COMMUNICATIONS 0x07 +#define PCI_CLASS_SYSTEM 0x08 +#define PCI_CLASS_INPUT 0x09 +#define PCI_CLASS_DOCK 0x0a +#define PCI_CLASS_PROCESSOR 0x0b +#define PCI_CLASS_SERIALBUS 0x0c +#define PCI_CLASS_WIRELESS 0x0d +#define PCI_CLASS_I2O 0x0e +#define PCI_CLASS_SATCOM 0x0f +#define PCI_CLASS_CRYPTO 0x10 +#define PCI_CLASS_DASP 0x11 +#define PCI_CLASS_UNDEFINED 0xff + +/* 0x00 prehistoric subclasses */ +#define PCI_SUBCLASS_PREHISTORIC_MISC 0x00 +#define PCI_SUBCLASS_PREHISTORIC_VGA 0x01 + +/* 0x01 mass storage subclasses */ +#define PCI_SUBCLASS_MASS_STORAGE_SCSI 0x00 +#define PCI_SUBCLASS_MASS_STORAGE_IDE 0x01 +#define PCI_SUBCLASS_MASS_STORAGE_FLOPPY 0x02 +#define PCI_SUBCLASS_MASS_STORAGE_IPI 0x03 +#define PCI_SUBCLASS_MASS_STORAGE_RAID 0x04 +#define PCI_SUBCLASS_MASS_STORAGE_ATA 0x05 +#define PCI_SUBCLASS_MASS_STORAGE_MISC 0x80 + +/* 0x02 network subclasses */ +#define PCI_SUBCLASS_NETWORK_ETHERNET 0x00 +#define PCI_SUBCLASS_NETWORK_TOKENRING 0x01 +#define PCI_SUBCLASS_NETWORK_FDDI 0x02 +#define PCI_SUBCLASS_NETWORK_ATM 0x03 +#define PCI_SUBCLASS_NETWORK_ISDN 0x04 +#define PCI_SUBCLASS_NETWORK_WORLDFIP 0x05 +#define PCI_SUBCLASS_NETWORK_PCIMGMULTICOMP 0x06 +#define PCI_SUBCLASS_NETWORK_MISC 0x80 + +/* 0x03 display subclasses */ +#define PCI_SUBCLASS_DISPLAY_VGA 0x00 +#define PCI_SUBCLASS_DISPLAY_XGA 0x01 +#define PCI_SUBCLASS_DISPLAY_3D 0x02 +#define PCI_SUBCLASS_DISPLAY_MISC 0x80 + +/* 0x04 multimedia subclasses */ +#define PCI_SUBCLASS_MULTIMEDIA_VIDEO 0x00 +#define PCI_SUBCLASS_MULTIMEDIA_AUDIO 0x01 +#define PCI_SUBCLASS_MULTIMEDIA_TELEPHONY 0x02 +#define PCI_SUBCLASS_MULTIMEDIA_MISC 0x80 + +/* 0x05 memory subclasses */ +#define PCI_SUBCLASS_MEMORY_RAM 0x00 +#define PCI_SUBCLASS_MEMORY_FLASH 0x01 +#define PCI_SUBCLASS_MEMORY_MISC 0x80 + +/* 0x06 bridge subclasses */ +#define PCI_SUBCLASS_BRIDGE_HOST 0x00 +#define PCI_SUBCLASS_BRIDGE_ISA 0x01 +#define PCI_SUBCLASS_BRIDGE_EISA 0x02 +#define PCI_SUBCLASS_BRIDGE_MC 0x03 +#define PCI_SUBCLASS_BRIDGE_PCI 0x04 +#define PCI_SUBCLASS_BRIDGE_PCMCIA 0x05 +#define PCI_SUBCLASS_BRIDGE_NUBUS 0x06 +#define PCI_SUBCLASS_BRIDGE_CARDBUS 0x07 +#define PCI_SUBCLASS_BRIDGE_RACEWAY 0x08 +#define PCI_SUBCLASS_BRIDGE_STPCI 0x09 +#define PCI_SUBCLASS_BRIDGE_INFINIBAND 0x0a +#define PCI_SUBCLASS_BRIDGE_MISC 0x80 + +/* 0x07 communications subclasses */ +#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00 +#define PCI_SUBCLASS_COMMUNICATIONS_PARALLEL 0x01 +#define PCI_SUBCLASS_COMMUNICATIONS_MPSERIAL 0x02 +#define PCI_SUBCLASS_COMMUNICATIONS_MODEM 0x03 +#define PCI_SUBCLASS_COMMUNICATIONS_MISC 0x80 + +/* 0x08 system subclasses */ +#define PCI_SUBCLASS_SYSTEM_PIC 0x00 +#define PCI_SUBCLASS_SYSTEM_DMA 0x01 +#define PCI_SUBCLASS_SYSTEM_TIMER 0x02 +#define PCI_SUBCLASS_SYSTEM_RTC 0x03 +#define PCI_SUBCLASS_SYSTEM_PCIHOTPLUG 0x04 +#define PCI_SUBCLASS_SYSTEM_MISC 0x80 + +/* 0x09 input subclasses */ +#define PCI_SUBCLASS_INPUT_KEYBOARD 0x00 +#define PCI_SUBCLASS_INPUT_DIGITIZER 0x01 +#define PCI_SUBCLASS_INPUT_MOUSE 0x02 +#define PCI_SUBCLASS_INPUT_SCANNER 0x03 +#define PCI_SUBCLASS_INPUT_GAMEPORT 0x04 +#define PCI_SUBCLASS_INPUT_MISC 0x80 + +/* 0x0a dock subclasses */ +#define PCI_SUBCLASS_DOCK_GENERIC 0x00 +#define PCI_SUBCLASS_DOCK_MISC 0x80 + +/* 0x0b processor subclasses */ +#define PCI_SUBCLASS_PROCESSOR_386 0x00 +#define PCI_SUBCLASS_PROCESSOR_486 0x01 +#define PCI_SUBCLASS_PROCESSOR_PENTIUM 0x02 +#define PCI_SUBCLASS_PROCESSOR_ALPHA 0x10 +#define PCI_SUBCLASS_PROCESSOR_POWERPC 0x20 +#define PCI_SUBCLASS_PROCESSOR_MIPS 0x30 +#define PCI_SUBCLASS_PROCESSOR_COPROC 0x40 + +/* 0x0c serial bus subclasses */ +#define PCI_SUBCLASS_SERIALBUS_FIREWIRE 0x00 +#define PCI_SUBCLASS_SERIALBUS_ACCESS 0x01 +#define PCI_SUBCLASS_SERIALBUS_SSA 0x02 +#define PCI_SUBCLASS_SERIALBUS_USB 0x03 +#define PCI_SUBCLASS_SERIALBUS_FIBER 0x04 +#define PCI_SUBCLASS_SERIALBUS_SMBUS 0x05 +#define PCI_SUBCLASS_SERIALBUS_INFINIBAND 0x06 +#define PCI_SUBCLASS_SERIALBUS_IPMI 0x07 +#define PCI_SUBCLASS_SERIALBUS_SERCOS 0x08 +#define PCI_SUBCLASS_SERIALBUS_CANBUS 0x09 + +/* 0x0d wireless subclasses */ +#define PCI_SUBCLASS_WIRELESS_IRDA 0x00 +#define PCI_SUBCLASS_WIRELESS_CONSUMERIR 0x01 +#define PCI_SUBCLASS_WIRELESS_RF 0x10 +#define PCI_SUBCLASS_WIRELESS_MISC 0x80 + +/* 0x0e I2O (Intelligent I/O) subclasses */ +#define PCI_SUBCLASS_I2O_STANDARD 0x00 + +/* 0x0f satellite communication subclasses */ +/* PCI_SUBCLASS_SATCOM_??? 0x00 / * XXX ??? */ +#define PCI_SUBCLASS_SATCOM_TV 0x01 +#define PCI_SUBCLASS_SATCOM_AUDIO 0x02 +#define PCI_SUBCLASS_SATCOM_VOICE 0x03 +#define PCI_SUBCLASS_SATCOM_DATA 0x04 + +/* 0x10 encryption/decryption subclasses */ +#define PCI_SUBCLASS_CRYPTO_NETCOMP 0x00 +#define PCI_SUBCLASS_CRYPTO_ENTERTAINMENT 0x10 +#define PCI_SUBCLASS_CRYPTO_MISC 0x80 + +/* 0x11 data acquisition and signal processing subclasses */ +#define PCI_SUBCLASS_DASP_DPIO 0x00 +#define PCI_SUBCLASS_DASP_TIMEFREQ 0x01 +#define PCI_SUBCLASS_DASP_MISC 0x80 + +/* + * PCI BIST/Header Type/Latency Timer/Cache Line Size Register. + */ +#define PCI_BHLC_REG 0x0c + +#define PCI_BIST_SHIFT 24 +#define PCI_BIST_MASK 0xff +#define PCI_BIST(bhlcr) \ + (((bhlcr) >> PCI_BIST_SHIFT) & PCI_BIST_MASK) + +#define PCI_HDRTYPE_SHIFT 16 +#define PCI_HDRTYPE_MASK 0xff +#define PCI_HDRTYPE(bhlcr) \ + (((bhlcr) >> PCI_HDRTYPE_SHIFT) & PCI_HDRTYPE_MASK) + +#define PCI_HDRTYPE_TYPE(bhlcr) \ + (PCI_HDRTYPE(bhlcr) & 0x7f) +#define PCI_HDRTYPE_MULTIFN(bhlcr) \ + ((PCI_HDRTYPE(bhlcr) & 0x80) != 0) + +#define PCI_LATTIMER_SHIFT 8 +#define PCI_LATTIMER_MASK 0xff +#define PCI_LATTIMER(bhlcr) \ + (((bhlcr) >> PCI_LATTIMER_SHIFT) & PCI_LATTIMER_MASK) + +#define PCI_CACHELINE_SHIFT 0 +#define PCI_CACHELINE_MASK 0xff +#define PCI_CACHELINE(bhlcr) \ + (((bhlcr) >> PCI_CACHELINE_SHIFT) & PCI_CACHELINE_MASK) + +/* config registers for header type 0 devices */ + +#define PCI_MAPS 0x10 +#define PCI_CARDBUSCIS 0x28 +#define PCI_SUBVEND_0 0x2c +#define PCI_SUBDEV_0 0x2e +#define PCI_INTLINE 0x3c +#define PCI_INTPIN 0x3d +#define PCI_MINGNT 0x3e +#define PCI_MAXLAT 0x3f + +/* config registers for header type 1 devices */ + +#define PCI_SECSTAT_1 0 /**/ + +#define PCI_PRIBUS_1 0x18 +#define PCI_SECBUS_1 0x19 +#define PCI_SUBBUS_1 0x1a +#define PCI_SECLAT_1 0x1b + +#define PCI_IOBASEL_1 0x1c +#define PCI_IOLIMITL_1 0x1d +#define PCI_IOBASEH_1 0x30 /**/ +#define PCI_IOLIMITH_1 0x32 /**/ + +#define PCI_MEMBASE_1 0x20 +#define PCI_MEMLIMIT_1 0x22 + +#define PCI_PMBASEL_1 0x24 +#define PCI_PMLIMITL_1 0x26 +#define PCI_PMBASEH_1 0 /**/ +#define PCI_PMLIMITH_1 0 /**/ + +#define PCI_BRIDGECTL_1 0 /**/ + +#define PCI_SUBVEND_1 0x34 +#define PCI_SUBDEV_1 0x36 + +/* config registers for header type 2 devices */ + +#define PCI_SECSTAT_2 0x16 + +#define PCI_PRIBUS_2 0x18 +#define PCI_SECBUS_2 0x19 +#define PCI_SUBBUS_2 0x1a +#define PCI_SECLAT_2 0x1b + +#define PCI_MEMBASE0_2 0x1c +#define PCI_MEMLIMIT0_2 0x20 +#define PCI_MEMBASE1_2 0x24 +#define PCI_MEMLIMIT1_2 0x28 +#define PCI_IOBASE0_2 0x2c +#define PCI_IOLIMIT0_2 0x30 +#define PCI_IOBASE1_2 0x34 +#define PCI_IOLIMIT1_2 0x38 + +#define PCI_BRIDGECTL_2 0x3e + +#define PCI_SUBVEND_2 0x40 +#define PCI_SUBDEV_2 0x42 + +#define PCI_PCCARDIF_2 0x44 + +/* + * Mapping registers + */ +#define PCI_MAPREG_START 0x10 +#define PCI_MAPREG_END 0x28 +#define PCI_MAPREG_ROM 0x30 +#define PCI_MAPREG_PPB_END 0x18 +#define PCI_MAPREG_PCB_END 0x14 + +#define PCI_MAPREG_TYPE(mr) \ + ((mr) & PCI_MAPREG_TYPE_MASK) +#define PCI_MAPREG_TYPE_MASK 0x00000001 + +#define PCI_MAPREG_TYPE_MEM 0x00000000 +#define PCI_MAPREG_TYPE_IO 0x00000001 +#define PCI_MAPREG_TYPE_ROM 0x00000001 + +#define PCI_MAPREG_MEM_TYPE(mr) \ + ((mr) & PCI_MAPREG_MEM_TYPE_MASK) +#define PCI_MAPREG_MEM_TYPE_MASK 0x00000006 + +#define PCI_MAPREG_MEM_TYPE_32BIT 0x00000000 +#define PCI_MAPREG_MEM_TYPE_32BIT_1M 0x00000002 +#define PCI_MAPREG_MEM_TYPE_64BIT 0x00000004 + +#define PCI_MAPREG_MEM_CACHEABLE(mr) \ + (((mr) & PCI_MAPREG_MEM_CACHEABLE_MASK) != 0) +#define PCI_MAPREG_MEM_CACHEABLE_MASK 0x00000008 + +#define PCI_MAPREG_MEM_PREFETCHABLE(mr) \ + (((mr) & PCI_MAPREG_MEM_PREFETCHABLE_MASK) != 0) +#define PCI_MAPREG_MEM_PREFETCHABLE_MASK 0x00000008 + +#define PCI_MAPREG_MEM_ADDR(mr) \ + ((mr) & PCI_MAPREG_MEM_ADDR_MASK) +#define PCI_MAPREG_MEM_SIZE(mr) \ + (PCI_MAPREG_MEM_ADDR(mr) & -PCI_MAPREG_MEM_ADDR(mr)) +#define PCI_MAPREG_MEM_ADDR_MASK 0xfffffff0 + +#define PCI_MAPREG_MEM64_ADDR(mr) \ + ((mr) & PCI_MAPREG_MEM64_ADDR_MASK) +#define PCI_MAPREG_MEM64_SIZE(mr) \ + (PCI_MAPREG_MEM64_ADDR(mr) & -PCI_MAPREG_MEM64_ADDR(mr)) +#define PCI_MAPREG_MEM64_ADDR_MASK 0xfffffffffffffff0 + +#define PCI_MAPREG_IO_ADDR(mr) \ + ((mr) & PCI_MAPREG_IO_ADDR_MASK) +#define PCI_MAPREG_IO_SIZE(mr) \ + (PCI_MAPREG_IO_ADDR(mr) & -PCI_MAPREG_IO_ADDR(mr)) +#define PCI_MAPREG_IO_ADDR_MASK 0xfffffffe + +#define PCI_MAPREG_ROM_ADDR(mr) \ + ((mr) & PCI_MAPREG_ROM_ADDR_MASK) +#define PCI_MAPREG_ROM_SIZE(mr) \ + (PCI_MAPREG_ROM_ADDR(mr) & -PCI_MAPREG_ROM_ADDR(mr)) +#define PCI_MAPREG_ROM_ADDR_MASK 0xfffff800 + +/* + * Cardbus CIS pointer (PCI rev. 2.1) + */ +#define PCI_CARDBUS_CIS_REG 0x28 + +/* + * Subsystem identification register; contains a vendor ID and a device ID. + * Types/macros for PCI_ID_REG apply. + * (PCI rev. 2.1) + */ +#define PCI_SUBSYS_ID_REG 0x2c + +/* + * capabilities link list (PCI rev. 2.2) + */ +#define PCI_CAPLISTPTR_REG 0x34 +#define PCI_CAPLIST_PTR(cpr) ((cpr) & 0xff) +#define PCI_CAPLIST_NEXT(cr) (((cr) >> 8) & 0xff) +#define PCI_CAPLIST_CAP(cr) ((cr) & 0xff) + +#define PCI_CAP_REESSERVED 0x00 +#define PCI_CAP_PWRMGMT 0x01 +#define PCI_CAP_AGP 0x02 +#define PCI_CAP_VPD 0x03 +#define PCI_CAP_SLOTID 0x04 +#define PCI_CAP_MBI 0x05 +#define PCI_CAP_CPCI_HOTSWAP 0x06 +#define PCI_CAP_PCIX 0x07 +#define PCI_CAP_LDT 0x08 +#define PCI_CAP_VENDSPEC 0x09 +#define PCI_CAP_DEBUGPORT 0x0a +#define PCI_CAP_CPCI_RSRCCTL 0x0b +#define PCI_CAP_HOTPLUG 0x0c + +/* + * Power Management Control Status Register; access via capability pointer. + */ +#define PCI_PMCSR_STATE_MASK 0x03 +#define PCI_PMCSR_STATE_D0 0x00 +#define PCI_PMCSR_STATE_D1 0x01 +#define PCI_PMCSR_STATE_D2 0x02 +#define PCI_PMCSR_STATE_D3 0x03 + +/* + * Interrupt Configuration Register; contains interrupt pin and line. + */ +#define PCI_INTERRUPT_REG 0x3c + +typedef u_int8_t pci_intr_pin_t; +typedef u_int8_t pci_intr_line_t; + +#define PCI_INTERRUPT_PIN_SHIFT 8 +#define PCI_INTERRUPT_PIN_MASK 0xff +#define PCI_INTERRUPT_PIN(icr) \ + (((icr) >> PCI_INTERRUPT_PIN_SHIFT) & PCI_INTERRUPT_PIN_MASK) + +#define PCI_INTERRUPT_LINE_SHIFT 0 +#define PCI_INTERRUPT_LINE_MASK 0xff +#define PCI_INTERRUPT_LINE(icr) \ + (((icr) >> PCI_INTERRUPT_LINE_SHIFT) & PCI_INTERRUPT_LINE_MASK) + +#define PCI_MIN_GNT_SHIFT 16 +#define PCI_MIN_GNT_MASK 0xff +#define PCI_MIN_GNT(icr) \ + (((icr) >> PCI_MIN_GNT_SHIFT) & PCI_MIN_GNT_MASK) + +#define PCI_MAX_LAT_SHIFT 24 +#define PCI_MAX_LAT_MASK 0xff +#define PCI_MAX_LAT(icr) \ + (((icr) >> PCI_MAX_LAT_SHIFT) & PCI_MAX_LAT_MASK) + +#define PCI_INTERRUPT_PIN_NONE 0x00 +#define PCI_INTERRUPT_PIN_A 0x01 +#define PCI_INTERRUPT_PIN_B 0x02 +#define PCI_INTERRUPT_PIN_C 0x03 +#define PCI_INTERRUPT_PIN_D 0x04 +#define PCI_INTERRUPT_PIN_MAX 0x04 + +#endif /* _DEV_PCI_PCIREG_H_ */ diff --git a/arch/mips/lemote/lm2f/lmbook/Makefile b/arch/mips/lemote/lm2f/lmbook/Makefile new file mode 100644 index 0000000..deacf01 --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbook/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for Lemote Loongson-2F mini notebook +# + +obj-y += setup.o prom.o reset.o irq.o bonito-irq.o dbg_io.o + +obj-$(CONFIG_SUSPEND) += pm.o + +EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/lemote/lm2f/lmbook/bonito-irq.c b/arch/mips/lemote/lm2f/lmbook/bonito-irq.c new file mode 100644 index 0000000..ce04b4d --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbook/bonito-irq.c @@ -0,0 +1,105 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include +#include +#include +#include + +#include + +#define bonito_irq_shutdown bonito_irq_disable + + +static inline void bonito_irq_enable(unsigned int irq) +{ + BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE)); + (void)BONITO_INTENSET; + mmiowb(); +} + +static unsigned int bonito_irq_startup(unsigned int irq) +{ + bonito_irq_enable(irq); + return 0; +} + +static inline void bonito_irq_ack(unsigned int irq) +{ + BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE)); + (void)BONITO_INTENCLR; + mmiowb(); +} + +static inline void bonito_irq_end(unsigned int irq) +{ + BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE )); + mmiowb(); +} + +static inline void bonito_irq_disable(unsigned int irq) +{ + BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE)); + (void)BONITO_INTENCLR; + mmiowb(); +} + +static struct irq_chip bonito_irq_type = { + .name = "bonito_irq", + .startup = bonito_irq_startup, + .shutdown = bonito_irq_shutdown, + .enable = bonito_irq_enable, + .disable = bonito_irq_disable, + .ack = bonito_irq_ack, + .end = bonito_irq_end, + .mask = bonito_irq_disable, + .mask_ack = bonito_irq_disable, + .unmask = bonito_irq_enable, +}; + +/* There is no need to handle the DMA IO problem on godson2f any more. */ +/* +static struct irqaction dma_timeout_irqaction = { + .handler = no_action, + .name = "dma_timeout", +}; +*/ + +void bonito_irq_init(void) +{ + u32 i; + + for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) { + set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); + } + + /* setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction); */ +} diff --git a/arch/mips/lemote/lm2f/lmbook/dbg_io.c b/arch/mips/lemote/lm2f/lmbook/dbg_io.c new file mode 100644 index 0000000..be80ca0 --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbook/dbg_io.c @@ -0,0 +1,170 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include +#include +#include /* For the serial port location and base baud */ + +#define UART16550_BAUD_2400 2400 +#define UART16550_BAUD_4800 4800 +#define UART16550_BAUD_9600 9600 +#define UART16550_BAUD_19200 19200 +#define UART16550_BAUD_38400 38400 +#define UART16550_BAUD_57600 57600 +#define UART16550_BAUD_115200 115200 + +#define UART16550_PARITY_NONE 0 +#define UART16550_PARITY_ODD 0x08 +#define UART16550_PARITY_EVEN 0x18 +#define UART16550_PARITY_MARK 0x28 +#define UART16550_PARITY_SPACE 0x38 + +#define UART16550_DATA_5BIT 0x0 +#define UART16550_DATA_6BIT 0x1 +#define UART16550_DATA_7BIT 0x2 +#define UART16550_DATA_8BIT 0x3 + +#define UART16550_STOP_1BIT 0x0 +#define UART16550_STOP_2BIT 0x4 + +/* ----------------------------------------------------- */ + +/* === CONFIG === */ +#ifdef CONFIG_64BIT +#define BASE (0xffffffffbff003f8) +#else +#define BASE (0xbff003f8) +#endif + +#define MAX_BAUD BASE_BAUD +/* === END OF CONFIG === */ + +#define REG_OFFSET 1 + +/* register offset */ +#define OFS_RCV_BUFFER 0 +#define OFS_TRANS_HOLD 0 +#define OFS_SEND_BUFFER 0 +#define OFS_INTR_ENABLE (1*REG_OFFSET) +#define OFS_INTR_ID (2*REG_OFFSET) +#define OFS_DATA_FORMAT (3*REG_OFFSET) +#define OFS_LINE_CONTROL (3*REG_OFFSET) +#define OFS_MODEM_CONTROL (4*REG_OFFSET) +#define OFS_RS232_OUTPUT (4*REG_OFFSET) +#define OFS_LINE_STATUS (5*REG_OFFSET) +#define OFS_MODEM_STATUS (6*REG_OFFSET) +#define OFS_RS232_INPUT (6*REG_OFFSET) +#define OFS_SCRATCH_PAD (7*REG_OFFSET) + +#define OFS_DIVISOR_LSB (0*REG_OFFSET) +#define OFS_DIVISOR_MSB (1*REG_OFFSET) + +/* memory-mapped read/write of the port */ +#define UART16550_READ(y) (*((volatile u8*)(BASE + y))) +#define UART16550_WRITE(y, z) ((*((volatile u8*)(BASE + y))) = z) + +void debugInit(u32 baud, u8 data, u8 parity, u8 stop) +{ + /* disable interrupts */ + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + /* set up buad rate */ + { + u32 divisor; + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + divisor = MAX_BAUD / baud; + UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); + UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); + + /* clear DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x0); + } + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized = 0; + +u8 getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_115200, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0) ; + return UART16550_READ(OFS_RCV_BUFFER); +} + +int putDebugChar(u8 byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + /* + debugInit(UART16550_BAUD_115200, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); */ + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0) ; + UART16550_WRITE(OFS_SEND_BUFFER, byte); + return 1; +} + +extern void prom_putchar(char c); + +void prom_printf(char *fmt, ...) +{ + va_list args; + char ppbuf[1024]; + char *bptr; + + va_start(args, fmt); + vsprintf(ppbuf, fmt, args); + + bptr = ppbuf; + + while (*bptr != 0) { + if (*bptr == '\n') + prom_putchar('\r'); + + prom_putchar(*bptr++); + } + va_end(args); +} diff --git a/arch/mips/lemote/lm2f/lmbook/irq.c b/arch/mips/lemote/lm2f/lmbook/irq.c new file mode 100644 index 0000000..57f3b76 --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbook/irq.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define BONITO_INT_BIT_GPIO0 (1 << 0) +#define BONITO_INT_BIT_GPIO1 (1 << 1) +#define BONITO_INT_BIT_GPIO2 (1 << 2) +#define BONITO_INT_BIT_GPIO3 (1 << 3) +#define BONITO_INT_BIT_PCI_INTA (1 << 4) +#define BONITO_INT_BIT_PCI_INTB (1 << 5) +#define BONITO_INT_BIT_PCI_INTC (1 << 6) +#define BONITO_INT_BIT_PCI_INTD (1 << 7) +#define BONITO_INT_BIT_PCI_PERR (1 << 8) +#define BONITO_INT_BIT_PCI_SERR (1 << 9) +#define BONITO_INT_BIT_DDR (1 << 10) +#define BONITO_INT_BIT_INT0 (1 << 11) +#define BONITO_INT_BIT_INT1 (1 << 12) +#define BONITO_INT_BIT_INT2 (1 << 13) +#define BONITO_INT_BIT_INT3 (1 << 14) + +#define BONITO_INT_TIMER_OFF 7 +#define BONITO_INT_BONITO_OFF 6 +#define BONITO_INT_UART_OFF 3 +#define BONITO_INT_I8259_OFF 2 + +/****************************************************************/ + +static void loongson2f_timer_dispatch(void) +{ + /* place the loongson2f timer interrupt on 23 */ + do_IRQ(MIPS_CPU_IRQ_BASE + BONITO_INT_TIMER_OFF); + return; +} + +static void loongson2f_bonito_dispatch(void) +{ + int int_status; + int i = 0; + + /* place the other interrupt on bit6 for bonito, inclding PCI and so on */ + int_status = BONITO_INTISR & BONITO_INTEN; + + for(i = 0; (i < 10) && int_status; i++){ + if(int_status & (1 << i)){ + if(i == 10) + printk("ddr int.\n"); + if(int_status & 0x000000f0) + do_IRQ(BONITO_IRQ_BASE + i); + int_status &= ~(1 << i); + } + } + + return; +} + +static void loongson2f_int3_dispatch(void) +{ + int int_status; + + int_status = BONITO_INTISR & BONITO_INTEN; + if(int_status & BONITO_INT_BIT_INT3){ + } + + return; +} + +static void loongson2f_int2_dispatch(void) +{ + int int_status; + + int_status = BONITO_INTISR & BONITO_INTEN; + if(int_status & BONITO_INT_BIT_INT2){ + } + + return; +} + +static void loongson2f_int1_dispatch(void) +{ + /* place the loongson2f uart interrupt on int1 */ + do_IRQ(MIPS_CPU_IRQ_BASE + BONITO_INT_UART_OFF); +} + +static void i8259_irqdispatch(void) +{ + int irq, isr; + extern unsigned int cached_irq_mask; + + if((BONITO_INTISR & BONITO_INTEN) & BONITO_INT_BIT_INT0) { + + isr = inb(0x20) | (inb(0xa0) << 8); + isr &= ~0x4; // irq2 for cascade + isr &= ~cached_irq_mask; + irq = ffs(isr) - 1; + + if(irq >= 0) { + do_IRQ(irq); + } else { + spurious_interrupt(); + } + } +} + +static void loongson2f_steer1_dispatch(void) +{ + return; +} + +static void loongson2f_steer0_dispatch(void) +{ + return; +} + + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + + if(pending & CAUSEF_IP7){ + loongson2f_timer_dispatch(); + }else if(pending & CAUSEF_IP6){ /*north bridge*/ + do_IRQ(MIPS_CPU_IRQ_BASE + 6); + loongson2f_bonito_dispatch(); + }else if(pending & CAUSEF_IP5){ + loongson2f_int3_dispatch(); + }else if(pending & CAUSEF_IP4){ + loongson2f_int2_dispatch(); + }else if(pending & CAUSEF_IP3){ /*cpu uart*/ + loongson2f_int1_dispatch(); + }else if(pending & CAUSEF_IP2){ /*south bridge*/ + i8259_irqdispatch(); + }else if(pending & CAUSEF_IP1){ + loongson2f_steer1_dispatch(); + }else if(pending & CAUSEF_IP0){ + loongson2f_steer0_dispatch(); + }else{ + spurious_interrupt(); + } + return; +} + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .mask = CPU_MASK_NONE, + .name = "cascade", +}; + +irqreturn_t ip6_action(int cpl, void *dev_id, struct pt_regs *regs) +{ + return IRQ_HANDLED; +} + +static struct irqaction ip6_irqaction = { + .handler = ip6_action, + .mask = CPU_MASK_NONE, + .name = "cascade", + .flags = IRQF_SHARED, +}; + +void __init arch_init_irq(void) +{ + extern void bonito_irq_init(void); + + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + local_irq_disable(); + + /* setup cs5536 as high level */ + BONITO_INTPOL = (1 << 11 | 1 << 12); + BONITO_INTEDGE &= ~(1 << 11 | 1 << 12); + + /* no steer */ + BONITO_INTSTEER = 0; + + /* + * Mask out all interrupt by writing "1" to all bit position in + * the interrupt reset reg. + */ + BONITO_INTENCLR = ~0; + + /* init all controller + * 0-15 ------> i8259 interrupt + * 16-23 ------> mips cpu interrupt + * 32-63 ------> bonito irq + */ + + /* Sets the first-level interrupt dispatcher. */ + mips_cpu_irq_init(); + + init_i8259_irqs(); + bonito_irq_init(); + + /* setup bonito interrupt */ + setup_irq(MIPS_CPU_IRQ_BASE + BONITO_INT_BONITO_OFF, &ip6_irqaction); + /* 8259 irq at IP2 */ + setup_irq(MIPS_CPU_IRQ_BASE + BONITO_INT_I8259_OFF, &cascade_irqaction); + +} diff --git a/arch/mips/lemote/lm2f/lmbook/pm.c b/arch/mips/lemote/lm2f/lmbook/pm.c new file mode 100644 index 0000000..f759200 --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbook/pm.c @@ -0,0 +1,240 @@ +/* + * Loongson2F-specific STR/Standby + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin + * Author: Hongbing Hu + * + * + * 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. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "../../../../../drivers/misc/loongson/ec.h" + +#define KBD_ENABLE 0x01 +#define I8042_KBD_IRQ 1 +#define SCI_IRQ_NUM 10 + +#ifdef CONFIG_64BIT +#define PTR_PAD(p) ((0xffffffff00000000)|((unsigned long long)(p))) +#else +#define PTR_PAD(p) (p) +#endif + +static unsigned int cached_master_mask; /* i8259A */ +static unsigned int cached_slave_mask; +static unsigned int cached_bonito_irq_mask; /* bonito */ + +extern void ec_write(unsigned short addr, unsigned char val); +extern unsigned char ec_read(unsigned short addr); +extern int i8042_flush(); + +void shutdown_devices(void) +{ + unsigned int value; + + /* close crt output */ + outb(0x21, 0x3c4); + value = inb(0x3c5); + value |= (1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + /* close lcd output */ + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x02; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + /* LCD backlight off */ + ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_OFF); + + /* shutdown three usb ports */ + ec_write(0xf461,0x00); + ec_write(0xf462,0x00); + ec_write(0xf463,0x00); +} + +void poweron_devices(void) +{ + unsigned int value; + + /* open lcd output */ + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x03; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + /* LCD backlight on */ + ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_ON); + + /* three usb ports power on */ + ec_write(0xf461,0x01); + ec_write(0xf462,0x01); + ec_write(0xf463,0x01); +} + +void mach_irqs_disable(void) +{ + /* disable all interrupts of i8259A */ + cached_slave_mask = inb(PIC_SLAVE_IMR); + cached_master_mask = inb(PIC_MASTER_IMR); + + outb(0xff, PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); + outb(0xff, PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); + + /* disable all interrupts of bonito */ + cached_bonito_irq_mask = BONITO_INTEN; + BONITO_INTENCLR = 0xffff; + (void)BONITO_INTENCLR; + mmiowb(); +} + +void mach_irqs_enable(void) +{ + /* only enable the cached interrupts of i8259A */ + outb(cached_slave_mask, PIC_SLAVE_IMR); + outb(cached_master_mask, PIC_MASTER_IMR); + + /* enable all cached interrupts of bonito */ + BONITO_INTENSET = cached_bonito_irq_mask; + (void)BONITO_INTENSET; + mmiowb(); +} +extern int sci_get_event_num(void); +extern int ec_query_seq(unsigned char cmd); + +int check_wakeup_event(void) +{ + int irq, isr; + + /* query the interrupt number */ + isr = inb(0x20) | (inb(0xa0) << 8); + isr &= ~0x4; // irq2 for cascade + isr &= ~(cached_master_mask|cached_slave_mask << 8); + irq = ffs(isr) - 1; + + if (irq < 0) + return 0; + printk("irq = %d\n", irq); + + if (irq == I8042_KBD_IRQ) + return 1; +#if 0 + else if (irq == SCI_IRQ_NUM) { + int ret, sci_event; + /* query the event number */ + ret = ec_query_seq(CMD_GET_EVENT_NUM); + if (ret < 0) + return 0; + sci_event = sci_get_event_num(); + if (sci_event < 0) + return 0; + if (sci_event == SCI_EVENT_NUM_LID) { + int lid_status; + /* check the LID status */ + lid_status = ec_read(REG_LID_DETECT); + /* wakeup cpu when people open the LID */ + if (lid_status == BIT_LID_DETECT_ON) + return 1; + } + } +#endif + return 0; +} + +static int ls2f_pm_standby(void) +{ + unsigned int cpu_freq, hi, lo, error, irq_mask; + unsigned char kbd = KBD_ENABLE; + + mach_irqs_disable(); + shutdown_devices(); + /* Enable kbd to wakeup cpu */ + outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); + error = i8042_command(&kbd, I8042_CMD_CTL_WCTR); + if(error){ + printk(KERN_ERR "Can't enable kbd\n"); + return error; + } +#if 0 + /* Enable the feature that open notebook to wakeup cpu */ + irq_mask = inb(PIC_MASTER_IMR); + outb(irq_mask & ~(1 << (SCI_IRQ_NUM - 8)), PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); + outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); +#endif + cpu_freq = *(volatile u32*)PTR_PAD(0xbfe00180); + /* Put CPU into wait mode zzzz....., wait for wakeup event */ + *(volatile u32*)PTR_PAD(0xbfe00180) &= ~0x7; + i8042_flush(); + *(volatile u32*)PTR_PAD(0xbfe00180) &= ~0x7; + /* Wakeup......, restore CPU freq */ + *(volatile u32*)PTR_PAD(0xbfe00180) = cpu_freq; + +wait: + if (!check_wakeup_event()) { + *(volatile u32*)PTR_PAD(0xbfe00180)&= ~0x7; + goto wait; + } + + poweron_devices(); + mach_irqs_enable(); + + return 0; +} + +/* Need to hardware support,later it will be ok -) */ +static int ls2f_pm_mem(void) +{ + return 0; +} + +/* For standby, for mem in the future */ +static int ls2f_pm_valid_state(suspend_state_t state) +{ + return state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM; +} + +static int ls2f_pm_enter(suspend_state_t state) +{ + switch(state){ + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + return ls2f_pm_standby(); + default: + return 0; + } +} + +struct platform_suspend_ops ls2f_pm_ops ={ + .valid = ls2f_pm_valid_state, + .enter = ls2f_pm_enter, +}; + +static int __init ls2f_pm_init(void) +{ + printk(KERN_INFO "Loongson2F Power Management \n"); + suspend_set_ops(&ls2f_pm_ops); + + return 0; +} +arch_initcall(ls2f_pm_init); diff --git a/arch/mips/lemote/lm2f/lmbook/prom.c b/arch/mips/lemote/lm2f/lmbook/prom.c new file mode 100644 index 0000000..795fe8e --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbook/prom.c @@ -0,0 +1,157 @@ +/* + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2003 ICT CAS + * Author: Michael Guo + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ +#include +#include +#include +#include + +#include +#include + +extern unsigned long bus_clock; +extern unsigned long cpu_clock_freq; +extern unsigned int memsize, highmemsize; +extern int putDebugChar(unsigned char byte); + +static int argc; +/* pmon passes arguments in 32bit pointers */ +static int *arg; +static int *env; + +const char *get_system_type(void) +{ + return "lemote-yeeloong"; +} + +void __init prom_init_cmdline(void) +{ + int i; + long l; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < argc; i++) { + l = (long)arg[i]; + if (strlen(arcs_cmdline) + strlen(((char *)l) + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, ((char *)l)); + strcat(arcs_cmdline, " "); + } +} + +extern void _wrmsr(u32 msr, u32 hi, u32 lo); + +void __init prom_init(void) +{ + long l; + unsigned char default_root[50] = "/dev/hda1"; + argc = fw_arg0; + arg = (int *)fw_arg1; + env = (int *)fw_arg2; + + /* set lpc irq to quiet mode*/ + //_wrmsr(0x8000004e, 0, 0); + //_wrmsr(0x8000004e, 0, 0xc0); + _wrmsr(0x80000014, 0x00, 0x16000003); + + /*Emulate post for usb*/ + _wrmsr(0x40000001, 0x4, 0xBF000); + + prom_init_cmdline(); + +#if 1 + if (!strstr(arcs_cmdline, "no_auto_cmd")) { + char *pmon_ver, *ec_ver, *p, version[60], ec_version[64]; + + p = arcs_cmdline; + + pmon_ver = strstr(arcs_cmdline, "PMON_VER"); + if (pmon_ver) { + if((p = strstr(pmon_ver, " "))) + *p++ = '\0'; + strncpy(version, pmon_ver, 60); + } else + strncpy(version, "PMON_VER=Unknown", 60); + + ec_ver = strstr(p, "EC_VER"); + if (ec_ver) { + if((p = strstr(ec_ver, " "))) + *p = '\0'; + strncpy(ec_version, ec_ver, 64); + } else + strncpy(ec_version, "EC_VER=Unknown", 64); + + p = strstr(arcs_cmdline, "root="); + if(p) { + strncpy(default_root, p, sizeof(default_root)); + if(p=strstr(default_root, " ")) + *p = '\0'; + } + + memset(arcs_cmdline, 0, sizeof(arcs_cmdline)); + strcat(arcs_cmdline, version); + strcat(arcs_cmdline, " "); + strcat(arcs_cmdline, ec_version); + strcat(arcs_cmdline, " "); + strcat(arcs_cmdline, " console=tty2"); + strcat(arcs_cmdline, " quiet"); + strcat(arcs_cmdline, " splash=silent,theme:yeeloong"); + } +#endif + if ((strstr(arcs_cmdline, "console=")) == NULL) + strcat(arcs_cmdline, " console=ttyS0,115200"); + + if ((strstr(arcs_cmdline, "root=")) == NULL) + strcat(arcs_cmdline, " root=/dev/hda1"); + + l = (long)*env; + while (l != 0) { + if (strncmp("busclock", (char *)l, strlen("busclock")) == 0) { + bus_clock = simple_strtol((char *)l + strlen("busclock="), + NULL, 10); + } + if (strncmp("cpuclock", (char *)l, strlen("cpuclock")) == 0) { + cpu_clock_freq = simple_strtol((char *)l + strlen("cpuclock="), + NULL, 10); + } + if (strncmp("memsize", (char *)l, strlen("memsize")) == 0) { + memsize = simple_strtol((char *)l + strlen("memsize="), + NULL, 10); + } + if (strncmp("highmemsize", (char *)l, strlen("highmemsize")) == 0) { + highmemsize = simple_strtol((char *)l + strlen("highmemsize="), + NULL, 10); + } + env++; + l = (long)*env; + } + if (memsize == 0) + memsize = 256; + + printk("busclock=%ld, cpuclock=%ld,memsize=%d,highmemsize=%d\n", + bus_clock, cpu_clock_freq, memsize, highmemsize); +} + +void __init prom_free_prom_memory(void) +{ +} + +void prom_putchar(char c) +{ + putDebugChar(c); +} diff --git a/arch/mips/lemote/lm2f/lmbook/reset.c b/arch/mips/lemote/lm2f/lmbook/reset.c new file mode 100644 index 0000000..a4af771 --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbook/reset.c @@ -0,0 +1,80 @@ +/* + * 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. + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +extern void _wrmsr(u32 reg, u32 hi, u32 lo); +extern void _rdmsr(u32 reg, u32 *hi, u32 *lo); + +static void loongson2f_restart(char *command) +{ +#ifdef CONFIG_32BIT + *(volatile u32*)0xbfe00180 |= 0x7; +#else + *(volatile u32*)0xffffffffbfe00180 |= 0x7; +#endif + +#ifdef CONFIG_64BIT + *((volatile u8*)(0xffffffffbfd00381)) = 0xf4; + *((volatile u8*)(0xffffffffbfd00382)) = 0xec; + *((volatile u8*)(0xffffffffbfd00383)) = 0x01; +#else + *((volatile u8*)(0xbfd00381)) = 0xf4; + *((volatile u8*)(0xbfd00382)) = 0xec; + *((volatile u8*)(0xbfd00383)) = 0x01; +#endif + + while (1); + /* Wait the system reset completely */ +#if 0 + __asm__ __volatile__ ( + ".long 0x3c02bfc0\n" + ".long 0x00400008\n" + :::"v0" + ); +#endif +} + +static void loongson2f_halt(void) +{ +#ifdef CONFIG_64BIT + /* cpu-gpio0 output low */ + *((volatile u32*)(0xffffffffbfe0011c)) &= ~0x00000001; + /* cpu-gpio0 as output */ + *((volatile u32*)(0xffffffffbfe00120)) &= ~0x00000001; +#else + /* cpu-gpio0 output low */ + *((volatile u32*)(0xbfe0011c)) &= ~0x00000001; + /* cpu-gpio0 as output */ + *((volatile u32*)(0xbfe00120)) &= ~0x00000001; +#endif + +} + +static void loongson2f_power_off(void) +{ + loongson2f_halt(); +} + +void mips_reboot_setup(void) +{ + _machine_restart = loongson2f_restart; + _machine_halt = loongson2f_halt; + pm_power_off = loongson2f_power_off; +} diff --git a/arch/mips/lemote/lm2f/lmbook/setup.c b/arch/mips/lemote/lm2f/lmbook/setup.c new file mode 100644 index 0000000..33c422c --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbook/setup.c @@ -0,0 +1,134 @@ +/* + * BRIEF MODULE DESCRIPTION + * setup.c - board dependent boot routines + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_VT +#include +#include +#endif + +extern void mips_reboot_setup(void); + +#ifdef CONFIG_64BIT +#define PTR_PAD(p) ((0xffffffff00000000)|((unsigned long long)(p))) +#else +#define PTR_PAD(p) (p) +#endif + +unsigned long cpu_clock_freq; +unsigned long bus_clock; +unsigned int memsize; +unsigned int highmemsize = 0; + +extern int __init init_mfgpt_clocksource(void); + +void __init plat_time_init(void) +{ + /* setup mips r4k timer */ + mips_hpt_frequency = cpu_clock_freq / 2; + +#ifdef CONFIG_LS2F_CPU_FREQ + init_mfgpt_clocksource(); +#endif +} + +unsigned long read_persistent_clock(void) +{ + return mc146818_get_cmos_time(); +} + +void (*__wbflush)(void); +EXPORT_SYMBOL(__wbflush); + +static void wbflush_loongson2f(void) +{ + asm(".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set mips3\n\t" + "sync\n\t" + "nop\n\t" + ".set\tpop\n\t" + ".set mips0\n\t"); +} + +void __init plat_mem_setup(void) +{ + set_io_port_base(PTR_PAD(0xbfd00000)); + + mips_reboot_setup(); + + __wbflush = wbflush_loongson2f; + + add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); +#ifdef CONFIG_64BIT + __asm__( + ".set mips3\n" + "dli $2, 0x900000003ff00000\n" + "dli $3, 0x0000000080000000\n" + "sd $3, 0x10($2)\n" + "sd $0, 0x50($2)\n" + "dli $3, 0xffffffffc0000000\n" + "sd $3, 0x30($2)\n" + ".set mips0\n" + :::"$2","$3","memory"); + if (highmemsize > 0) { + add_memory_region(0x90000000, highmemsize << 20, BOOT_MEM_RAM); + } +#endif + +#ifdef CONFIG_VT +#if defined(CONFIG_VGA_CONSOLE) + conswitchp = &vga_con; + + screen_info = (struct screen_info) { + 0, 25, /* orig-x, orig-y */ + 0, /* unused */ + 0, /* orig-video-page */ + 0, /* orig-video-mode */ + 80, /* orig-video-cols */ + 0, 0, 0, /* ega_ax, ega_bx, ega_cx */ + 25, /* orig-video-lines */ + VIDEO_TYPE_VGAC, /* orig-video-isVGA */ + 16 /* orig-video-points */ + }; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif +#endif + +} + +EXPORT_SYMBOL(cpu_clock_freq); diff --git a/arch/mips/lemote/lm2f/lmbox/Makefile b/arch/mips/lemote/lm2f/lmbox/Makefile new file mode 100644 index 0000000..e8f2740 --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbox/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for Lemote Loongson-2F based mini box. +# + +obj-y += setup.o prom.o reset.o irq.o bonito-irq.o dbg_io.o + +obj-$(CONFIG_SUSPEND) += pm.o + +EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/lemote/lm2f/lmbox/bonito-irq.c b/arch/mips/lemote/lm2f/lmbox/bonito-irq.c new file mode 100644 index 0000000..ce04b4d --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbox/bonito-irq.c @@ -0,0 +1,105 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include +#include +#include +#include + +#include + +#define bonito_irq_shutdown bonito_irq_disable + + +static inline void bonito_irq_enable(unsigned int irq) +{ + BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE)); + (void)BONITO_INTENSET; + mmiowb(); +} + +static unsigned int bonito_irq_startup(unsigned int irq) +{ + bonito_irq_enable(irq); + return 0; +} + +static inline void bonito_irq_ack(unsigned int irq) +{ + BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE)); + (void)BONITO_INTENCLR; + mmiowb(); +} + +static inline void bonito_irq_end(unsigned int irq) +{ + BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE )); + mmiowb(); +} + +static inline void bonito_irq_disable(unsigned int irq) +{ + BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE)); + (void)BONITO_INTENCLR; + mmiowb(); +} + +static struct irq_chip bonito_irq_type = { + .name = "bonito_irq", + .startup = bonito_irq_startup, + .shutdown = bonito_irq_shutdown, + .enable = bonito_irq_enable, + .disable = bonito_irq_disable, + .ack = bonito_irq_ack, + .end = bonito_irq_end, + .mask = bonito_irq_disable, + .mask_ack = bonito_irq_disable, + .unmask = bonito_irq_enable, +}; + +/* There is no need to handle the DMA IO problem on godson2f any more. */ +/* +static struct irqaction dma_timeout_irqaction = { + .handler = no_action, + .name = "dma_timeout", +}; +*/ + +void bonito_irq_init(void) +{ + u32 i; + + for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) { + set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); + } + + /* setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction); */ +} diff --git a/arch/mips/lemote/lm2f/lmbox/dbg_io.c b/arch/mips/lemote/lm2f/lmbox/dbg_io.c new file mode 100644 index 0000000..5900fdc --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbox/dbg_io.c @@ -0,0 +1,182 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include +#include +#include /* For the serial port location and base baud */ + +#define UART16550_BAUD_2400 2400 +#define UART16550_BAUD_4800 4800 +#define UART16550_BAUD_9600 9600 +#define UART16550_BAUD_19200 19200 +#define UART16550_BAUD_38400 38400 +#define UART16550_BAUD_57600 57600 +#define UART16550_BAUD_115200 115200 + +#define UART16550_PARITY_NONE 0 +#define UART16550_PARITY_ODD 0x08 +#define UART16550_PARITY_EVEN 0x18 +#define UART16550_PARITY_MARK 0x28 +#define UART16550_PARITY_SPACE 0x38 + +#define UART16550_DATA_5BIT 0x0 +#define UART16550_DATA_6BIT 0x1 +#define UART16550_DATA_7BIT 0x2 +#define UART16550_DATA_8BIT 0x3 + +#define UART16550_STOP_1BIT 0x0 +#define UART16550_STOP_2BIT 0x4 + +/* ----------------------------------------------------- */ + +#ifdef USE_GODSON2F_UART + +/* === CONFIG === */ +#ifdef CONFIG_64BIT +#define BASE (0xffffffffbff003f8) +#else +#define BASE (0xbff003f8) +#endif + +#else /* USE_CS5536_UART1/2 */ + +#ifdef CONFIG_64BIT +#define BASE 0xffffffffbfd002f8 +#else +#define BASE 0xbfd002f8 +#endif + +#endif /* end of USE_GODSON2F_UART */ + +#define MAX_BAUD BASE_BAUD +/* === END OF CONFIG === */ + +#define REG_OFFSET 1 + +/* register offset */ +#define OFS_RCV_BUFFER 0 +#define OFS_TRANS_HOLD 0 +#define OFS_SEND_BUFFER 0 +#define OFS_INTR_ENABLE (1*REG_OFFSET) +#define OFS_INTR_ID (2*REG_OFFSET) +#define OFS_DATA_FORMAT (3*REG_OFFSET) +#define OFS_LINE_CONTROL (3*REG_OFFSET) +#define OFS_MODEM_CONTROL (4*REG_OFFSET) +#define OFS_RS232_OUTPUT (4*REG_OFFSET) +#define OFS_LINE_STATUS (5*REG_OFFSET) +#define OFS_MODEM_STATUS (6*REG_OFFSET) +#define OFS_RS232_INPUT (6*REG_OFFSET) +#define OFS_SCRATCH_PAD (7*REG_OFFSET) + +#define OFS_DIVISOR_LSB (0*REG_OFFSET) +#define OFS_DIVISOR_MSB (1*REG_OFFSET) + +/* memory-mapped read/write of the port */ +#define UART16550_READ(y) (*((volatile u8*)(BASE + y))) +#define UART16550_WRITE(y, z) ((*((volatile u8*)(BASE + y))) = z) + +void debugInit(u32 baud, u8 data, u8 parity, u8 stop) +{ + /* disable interrupts */ + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + /* set up buad rate */ + { + u32 divisor; + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + divisor = MAX_BAUD / baud; + UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); + UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); + + /* clear DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x0); + } + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized = 0; + +u8 getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_115200, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0) ; + return UART16550_READ(OFS_RCV_BUFFER); +} + +int putDebugChar(u8 byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + /* + debugInit(UART16550_BAUD_115200, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); */ + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0) ; + UART16550_WRITE(OFS_SEND_BUFFER, byte); + return 1; +} + +extern void prom_putchar(char c); + +void prom_printf(char *fmt, ...) +{ + va_list args; + char ppbuf[1024]; + char *bptr; + + va_start(args, fmt); + vsprintf(ppbuf, fmt, args); + + bptr = ppbuf; + + while (*bptr != 0) { + if (*bptr == '\n') + prom_putchar('\r'); + + prom_putchar(*bptr++); + } + va_end(args); +} diff --git a/arch/mips/lemote/lm2f/lmbox/irq.c b/arch/mips/lemote/lm2f/lmbox/irq.c new file mode 100644 index 0000000..57f3b76 --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbox/irq.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define BONITO_INT_BIT_GPIO0 (1 << 0) +#define BONITO_INT_BIT_GPIO1 (1 << 1) +#define BONITO_INT_BIT_GPIO2 (1 << 2) +#define BONITO_INT_BIT_GPIO3 (1 << 3) +#define BONITO_INT_BIT_PCI_INTA (1 << 4) +#define BONITO_INT_BIT_PCI_INTB (1 << 5) +#define BONITO_INT_BIT_PCI_INTC (1 << 6) +#define BONITO_INT_BIT_PCI_INTD (1 << 7) +#define BONITO_INT_BIT_PCI_PERR (1 << 8) +#define BONITO_INT_BIT_PCI_SERR (1 << 9) +#define BONITO_INT_BIT_DDR (1 << 10) +#define BONITO_INT_BIT_INT0 (1 << 11) +#define BONITO_INT_BIT_INT1 (1 << 12) +#define BONITO_INT_BIT_INT2 (1 << 13) +#define BONITO_INT_BIT_INT3 (1 << 14) + +#define BONITO_INT_TIMER_OFF 7 +#define BONITO_INT_BONITO_OFF 6 +#define BONITO_INT_UART_OFF 3 +#define BONITO_INT_I8259_OFF 2 + +/****************************************************************/ + +static void loongson2f_timer_dispatch(void) +{ + /* place the loongson2f timer interrupt on 23 */ + do_IRQ(MIPS_CPU_IRQ_BASE + BONITO_INT_TIMER_OFF); + return; +} + +static void loongson2f_bonito_dispatch(void) +{ + int int_status; + int i = 0; + + /* place the other interrupt on bit6 for bonito, inclding PCI and so on */ + int_status = BONITO_INTISR & BONITO_INTEN; + + for(i = 0; (i < 10) && int_status; i++){ + if(int_status & (1 << i)){ + if(i == 10) + printk("ddr int.\n"); + if(int_status & 0x000000f0) + do_IRQ(BONITO_IRQ_BASE + i); + int_status &= ~(1 << i); + } + } + + return; +} + +static void loongson2f_int3_dispatch(void) +{ + int int_status; + + int_status = BONITO_INTISR & BONITO_INTEN; + if(int_status & BONITO_INT_BIT_INT3){ + } + + return; +} + +static void loongson2f_int2_dispatch(void) +{ + int int_status; + + int_status = BONITO_INTISR & BONITO_INTEN; + if(int_status & BONITO_INT_BIT_INT2){ + } + + return; +} + +static void loongson2f_int1_dispatch(void) +{ + /* place the loongson2f uart interrupt on int1 */ + do_IRQ(MIPS_CPU_IRQ_BASE + BONITO_INT_UART_OFF); +} + +static void i8259_irqdispatch(void) +{ + int irq, isr; + extern unsigned int cached_irq_mask; + + if((BONITO_INTISR & BONITO_INTEN) & BONITO_INT_BIT_INT0) { + + isr = inb(0x20) | (inb(0xa0) << 8); + isr &= ~0x4; // irq2 for cascade + isr &= ~cached_irq_mask; + irq = ffs(isr) - 1; + + if(irq >= 0) { + do_IRQ(irq); + } else { + spurious_interrupt(); + } + } +} + +static void loongson2f_steer1_dispatch(void) +{ + return; +} + +static void loongson2f_steer0_dispatch(void) +{ + return; +} + + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + + if(pending & CAUSEF_IP7){ + loongson2f_timer_dispatch(); + }else if(pending & CAUSEF_IP6){ /*north bridge*/ + do_IRQ(MIPS_CPU_IRQ_BASE + 6); + loongson2f_bonito_dispatch(); + }else if(pending & CAUSEF_IP5){ + loongson2f_int3_dispatch(); + }else if(pending & CAUSEF_IP4){ + loongson2f_int2_dispatch(); + }else if(pending & CAUSEF_IP3){ /*cpu uart*/ + loongson2f_int1_dispatch(); + }else if(pending & CAUSEF_IP2){ /*south bridge*/ + i8259_irqdispatch(); + }else if(pending & CAUSEF_IP1){ + loongson2f_steer1_dispatch(); + }else if(pending & CAUSEF_IP0){ + loongson2f_steer0_dispatch(); + }else{ + spurious_interrupt(); + } + return; +} + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .mask = CPU_MASK_NONE, + .name = "cascade", +}; + +irqreturn_t ip6_action(int cpl, void *dev_id, struct pt_regs *regs) +{ + return IRQ_HANDLED; +} + +static struct irqaction ip6_irqaction = { + .handler = ip6_action, + .mask = CPU_MASK_NONE, + .name = "cascade", + .flags = IRQF_SHARED, +}; + +void __init arch_init_irq(void) +{ + extern void bonito_irq_init(void); + + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + local_irq_disable(); + + /* setup cs5536 as high level */ + BONITO_INTPOL = (1 << 11 | 1 << 12); + BONITO_INTEDGE &= ~(1 << 11 | 1 << 12); + + /* no steer */ + BONITO_INTSTEER = 0; + + /* + * Mask out all interrupt by writing "1" to all bit position in + * the interrupt reset reg. + */ + BONITO_INTENCLR = ~0; + + /* init all controller + * 0-15 ------> i8259 interrupt + * 16-23 ------> mips cpu interrupt + * 32-63 ------> bonito irq + */ + + /* Sets the first-level interrupt dispatcher. */ + mips_cpu_irq_init(); + + init_i8259_irqs(); + bonito_irq_init(); + + /* setup bonito interrupt */ + setup_irq(MIPS_CPU_IRQ_BASE + BONITO_INT_BONITO_OFF, &ip6_irqaction); + /* 8259 irq at IP2 */ + setup_irq(MIPS_CPU_IRQ_BASE + BONITO_INT_I8259_OFF, &cascade_irqaction); + +} diff --git a/arch/mips/lemote/lm2f/lmbox/pm.c b/arch/mips/lemote/lm2f/lmbox/pm.c new file mode 100644 index 0000000..0b1f3eb --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbox/pm.c @@ -0,0 +1,186 @@ +/* + * loongson-specific STR/Standby support + * + * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology + * Author: Wu Zhangjin + * + * 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. + */ + +#include +#include +#include + +#include +#include + +#include + +#include "../common/cs5536_pci.h" +#include "../common/cs5536.h" + +#define BONITO_CHIPCFG0 BONITO(BONITO_REGBASE + 0x80) + +extern void _rdmsr(u32 reg, u32 *hi, u32 *lo); +static u32 mfgpt_base, gpio_base, smb_base; + +static unsigned int cached_master_mask; /* i8259A */ +static unsigned int cached_slave_mask; +static unsigned int cached_bonito_irq_mask; /* bonito */ + +void arch_suspend_disable_irqs(void) +{ + /* disable all mips eventss */ + local_irq_disable(); + + /* disable all eventss of i8259A */ + cached_slave_mask = inb(PIC_SLAVE_IMR); + cached_master_mask = inb(PIC_MASTER_IMR); + + outb(0xff, PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); + outb(0xff, PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); + + /* disable all eventss of bonito */ + cached_bonito_irq_mask = BONITO_INTEN; + BONITO_INTENCLR = 0xffff; + (void)BONITO_INTENCLR; +} + +void arch_suspend_enable_irqs(void) +{ + /* enable all mips eventss */ + local_irq_enable(); + + /* only enable the cached eventss of i8259A */ + outb(cached_slave_mask, PIC_SLAVE_IMR); + outb(cached_master_mask, PIC_MASTER_IMR); + + /* enable all cached eventss of bonito */ + BONITO_INTENSET = cached_bonito_irq_mask; + (void)BONITO_INTENSET; +} + +/* setup the board-specific events for waking up loongson from wait mode */ +void __attribute__((weak)) setup_wakeup_events(void) +{ +} + +/* check wakeup events */ +int __attribute__((weak)) wakeup_loongson(void) +{ + return 1; +} + +/* if the events are really what we want to wakeup cpu, wake up it, otherwise, + * we Put CPU into wait mode again. + */ +static void wait_for_wakeup_events(void) +{ + while (!wakeup_loongson()) + BONITO_CHIPCFG0 &= ~0x7; +} + +/* stop all perf counters by default + * $24 is the control register of loongson perf counter + */ +static inline void stop_perf_counters(void) +{ + __write_64bit_c0_register($24, 0, 0); +} + + +static void loongson_suspend_enter(void) +{ + static unsigned int cached_cpu_freq; + + /* setup wakeup events via enabling the IRQs */ + setup_wakeup_events(); + + /* stop all perf counters */ + stop_perf_counters(); + + cached_cpu_freq = BONITO_CHIPCFG0; + + /* Put CPU into wait mode */ + BONITO_CHIPCFG0 &= ~0x7; + + /* wait for the given events to wakeup cpu from wait mode */ + wait_for_wakeup_events(); + + BONITO_CHIPCFG0 = cached_cpu_freq; + mmiowb(); +} + +#define MFGPT0_SETUP (mfgpt_base + 6) + +void __attribute__((weak)) mach_suspend(void) +{ + /* disable mfgpt */ + outw(inw(MFGPT0_SETUP) & 0x7fff, MFGPT0_SETUP); +} + +void __attribute__((weak)) mach_resume(void) +{ + /* enable mfgpt */ + outw(0xe310, MFGPT0_SETUP); +} + +static int loongson_pm_enter(suspend_state_t state) +{ + /* mach specific suspend */ + mach_suspend(); + + /* processor specific suspend */ + loongson_suspend_enter(); + + /* mach specific resume */ + mach_resume(); + + return 0; +} + +static int loongson_pm_valid_state(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_ON: + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + return 1; + + default: + return 0; + } +} + +static int loongson_pm_prepare(void) +{ + u32 hi; + + /* get gpio_base */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base); + /* get mfgpt base */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &mfgpt_base); + /* get smb base */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &smb_base); + + return 0; +} + +static struct platform_suspend_ops loongson_pm_ops = { + .prepare = loongson_pm_prepare, + .valid = loongson_pm_valid_state, + .enter = loongson_pm_enter, +}; + +static int __init loongson_pm_init(void) +{ + suspend_set_ops(&loongson_pm_ops); + + return 0; +} +arch_initcall(loongson_pm_init); diff --git a/arch/mips/lemote/lm2f/lmbox/prom.c b/arch/mips/lemote/lm2f/lmbox/prom.c new file mode 100644 index 0000000..3ea4216 --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbox/prom.c @@ -0,0 +1,106 @@ +/* + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2003 ICT CAS + * Author: Michael Guo + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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. + */ +#include +#include +#include +#include + +#include +#include + +extern unsigned long bus_clock; +extern unsigned long cpu_clock_freq; +extern unsigned int memsize, highmemsize; +extern int putDebugChar(unsigned char byte); + +static int argc; +/* pmon passes arguments in 32bit pointers */ +static int *arg; +static int *env; + +const char *get_system_type(void) +{ + return "lemote-fuloong"; +} + +void __init prom_init_cmdline(void) +{ + int i; + long l; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < argc; i++) { + l = (long)arg[i]; + if (strlen(arcs_cmdline) + strlen(((char *)l) + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, ((char *)l)); + strcat(arcs_cmdline, " "); + } +} + +void __init prom_init(void) +{ + long l; + argc = fw_arg0; + arg = (int *)fw_arg1; + env = (int *)fw_arg2; + + prom_init_cmdline(); + + if ((strstr(arcs_cmdline, "console=")) == NULL) + strcat(arcs_cmdline, " console=ttyS0,115200"); + if ((strstr(arcs_cmdline, "root=")) == NULL) + strcat(arcs_cmdline, " root=/dev/hda1"); + + l = (long)*env; + while (l != 0) { + if (strncmp("busclock", (char *)l, strlen("busclock")) == 0) { + bus_clock = simple_strtol((char *)l + strlen("busclock="), + NULL, 10); + } + if (strncmp("cpuclock", (char *)l, strlen("cpuclock")) == 0) { + cpu_clock_freq = simple_strtol((char *)l + strlen("cpuclock="), + NULL, 10); + } + if (strncmp("memsize", (char *)l, strlen("memsize")) == 0) { + memsize = simple_strtol((char *)l + strlen("memsize="), + NULL, 10); + } + if (strncmp("highmemsize", (char *)l, strlen("highmemsize")) == 0) { + highmemsize = simple_strtol((char *)l + strlen("highmemsize="), + NULL, 10); + } + env++; + l = (long)*env; + } + if (memsize == 0) + memsize = 256; + + printk("busclock=%ld, cpuclock=%ld,memsize=%d,highmemsize=%d\n", + bus_clock, cpu_clock_freq, memsize, highmemsize); +} + +void __init prom_free_prom_memory(void) +{ +} + +void prom_putchar(char c) +{ + putDebugChar(c); +} diff --git a/arch/mips/lemote/lm2f/lmbox/reset.c b/arch/mips/lemote/lm2f/lmbox/reset.c new file mode 100644 index 0000000..64dfe84 --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbox/reset.c @@ -0,0 +1,87 @@ +/* + * 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. + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +extern void _wrmsr(u32 reg, u32 hi, u32 lo); +extern void _rdmsr(u32 reg, u32 *hi, u32 *lo); + +static void loongson2f_restart(char *command) +{ + u32 hi, lo; + +#ifdef CONFIG_32BIT + *(volatile u32*)0xbfe00180 |= 0x7; +#else + *(volatile u32*)0xffffffffbfe00180 |= 0x7; +#endif + _rdmsr(0xe0000014, &hi, &lo); + lo |= 0x00000001; + _wrmsr(0xe0000014, hi, lo); + + printk("Hard reset not take effect!!\n"); + __asm__ __volatile__ ( + ".long 0x3c02bfc0\n" + ".long 0x00400008\n" + :::"v0" + ); +} + + +static void delay(void) +{ + volatile int i; + for (i=0; i<0x10000; i++); +} +static void loongson2f_halt(void) +{ +#ifdef CONFIG_32BIT + u32 base; +#else + u64 base; +#endif + u32 hi, lo, val; + + _rdmsr(0x8000000c, &hi, &lo); +#ifdef CONFIG_32BIT + base = (lo & 0xff00) | 0xbfd00000; +#else + base = (lo & 0xff00) | 0xffffffffbfd00000ULL; +#endif + val = (val & ~(1 << (16 + 13))) | (1 << 13); + delay(); + *(__volatile__ u32 *)(base + 0x04) = val; + delay(); + val = (val & ~(1 << (13))) | (1 << (16 + 13)); + delay(); + *(__volatile__ u32 *)(base + 0x00) = val; + delay(); +} + +static void loongson2f_power_off(void) +{ + loongson2f_halt(); +} + +void mips_reboot_setup(void) +{ + _machine_restart = loongson2f_restart; + _machine_halt = loongson2f_halt; + pm_power_off = loongson2f_power_off; +} diff --git a/arch/mips/lemote/lm2f/lmbox/setup.c b/arch/mips/lemote/lm2f/lmbox/setup.c new file mode 100644 index 0000000..6cd278a --- /dev/null +++ b/arch/mips/lemote/lm2f/lmbox/setup.c @@ -0,0 +1,130 @@ +/* + * BRIEF MODULE DESCRIPTION + * setup.c - board dependent boot routines + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_VT +#include +#include +#endif + +extern void mips_reboot_setup(void); + +#ifdef CONFIG_64BIT +#define PTR_PAD(p) ((0xffffffff00000000)|((unsigned long long)(p))) +#else +#define PTR_PAD(p) (p) +#endif + +unsigned long cpu_clock_freq; +unsigned long bus_clock; +unsigned int memsize; +unsigned int highmemsize = 0; + +extern int __init init_mfgpt_clocksource(void); + +void __init plat_time_init(void) +{ + /* setup mips r4k timer */ + mips_hpt_frequency = cpu_clock_freq / 2; + + init_mfgpt_clocksource(); +} + +unsigned long read_persistent_clock(void) +{ + return mc146818_get_cmos_time(); +} + +void (*__wbflush)(void); +EXPORT_SYMBOL(__wbflush); + +static void wbflush_loongson2f(void) +{ + asm(".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set mips3\n\t" + "sync\n\t" + "nop\n\t" + ".set\tpop\n\t" + ".set mips0\n\t"); +} + +void __init plat_mem_setup(void) +{ + set_io_port_base(PTR_PAD(0xbfd00000)); + + mips_reboot_setup(); + + __wbflush = wbflush_loongson2f; + + add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); +#ifdef CONFIG_64BIT + __asm__( + ".set mips3\n" + "dli $2, 0x900000003ff00000\n" + "dli $3, 0x0000000080000000\n" + "sd $3, 0x10($2)\n" + "sd $0, 0x50($2)\n" + "dli $3, 0xffffffff80000000\n" + "sd $3, 0x30($2)\n" + ".set mips0\n" + :::"$2","$3","memory"); + if (highmemsize > 0) { + add_memory_region(0x90000000, highmemsize << 20, BOOT_MEM_RAM); + } +#endif + +#ifdef CONFIG_VT +#if defined(CONFIG_VGA_CONSOLE) + conswitchp = &vga_con; + + screen_info = (struct screen_info) { + 0, 25, /* orig-x, orig-y */ + 0, /* unused */ + 0, /* orig-video-page */ + 0, /* orig-video-mode */ + 80, /* orig-video-cols */ + 0, 0, 0, /* ega_ax, ega_bx, ega_cx */ + 25, /* orig-video-lines */ + VIDEO_TYPE_VGAC, /* orig-video-isVGA */ + 16 /* orig-video-points */ + }; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif +#endif + +} diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index b08fc65..7ec0b21 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -1299,12 +1299,12 @@ static int __init debugfs_fpuemu(void) if (!mips_debugfs_dir) return -ENODEV; dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir); - if (IS_ERR(dir)) - return PTR_ERR(dir); + if (!dir) + return -ENOMEM; for (i = 0; i < ARRAY_SIZE(vars); i++) { d = debugfs_create_u32(vars[i].name, S_IRUGO, dir, vars[i].v); - if (IS_ERR(d)) - return PTR_ERR(d); + if (!d) + return -ENOMEM; } return 0; } diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 891312f..e6acb0c 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -40,6 +40,12 @@ static inline int cpu_is_noncoherent_r10000(struct device *dev) current_cpu_type() == CPU_R12000); } +static inline int cpu_is_noncoherent_loongson(struct device *dev) +{ + return !plat_device_is_coherent(dev) && + (current_cpu_data.cputype == CPU_LOONGSON2); +} + static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) { /* ignore region specifiers */ @@ -166,7 +172,7 @@ EXPORT_SYMBOL(dma_map_single); void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction) { - if (cpu_is_noncoherent_r10000(dev)) + if (cpu_is_noncoherent_r10000(dev) || cpu_is_noncoherent_loongson(dev)) __dma_sync(dma_addr_to_virt(dma_addr), size, direction); @@ -257,7 +263,7 @@ void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, { BUG_ON(direction == DMA_NONE); - if (cpu_is_noncoherent_r10000(dev)) { + if (cpu_is_noncoherent_r10000(dev) || cpu_is_noncoherent_loongson(dev)) { unsigned long addr; addr = dma_addr_to_virt(dma_handle); @@ -324,7 +330,6 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, if (cpu_is_noncoherent_r10000(dev)) __dma_sync((unsigned long)page_address(sg_page(sg)), sg->length, direction); - plat_unmap_dma_mem(sg->dma_address); } } @@ -342,7 +347,6 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele if (!plat_device_is_coherent(dev)) __dma_sync((unsigned long)page_address(sg_page(sg)), sg->length, direction); - plat_unmap_dma_mem(sg->dma_address); } } diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index bf3be6f..d039d6b 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile @@ -15,3 +15,4 @@ oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o +oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index dd2fbd6..cee1e3b 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -16,6 +16,7 @@ extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak)); extern struct op_mips_model op_model_rm9000_ops __attribute__((weak)); +extern struct op_mips_model op_model_loongson2_ops __attribute__((weak)); static struct op_mips_model *model; @@ -93,6 +94,10 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case CPU_RM9000: lmodel = &op_model_rm9000_ops; break; + + case CPU_LOONGSON2: + lmodel = &op_model_loongson2_ops; + break; }; if (!lmodel) diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c new file mode 100644 index 0000000..c0120f6 --- /dev/null +++ b/arch/mips/oprofile/op_model_loongson2.c @@ -0,0 +1,197 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include "op_impl.h" + +#define PERF_IRQ (MIPS_CPU_IRQ_BASE + 6 ) + +#define LOONGSON_COUNTER1_EVENT(event) ((event&0x0f) << 5) +#define LOONGSON_COUNTER1_SUPERVISOR (1UL << 2) +#define LOONGSON_COUNTER1_KERNEL (1UL << 1) +#define LOONGSON_COUNTER1_USER (1UL << 3) +#define LOONGSON_COUNTER1_ENABLE (1UL << 4) +#define LOONGSON_COUNTER1_OVERFLOW (1ULL << 31) +#define LOONGSON_COUNTER1_EXL (1UL << 0) + +#define LOONGSON_COUNTER2_EVENT(event) ((event&0x0f) << 9) +#define LOONGSON_COUNTER2_SUPERVISOR LOONGSON_COUNTER1_SUPERVISOR +#define LOONGSON_COUNTER2_KERNEL LOONGSON_COUNTER1_KERNEL +#define LOONGSON_COUNTER2_USER LOONGSON_COUNTER1_USER +#define LOONGSON_COUNTER2_ENABLE LOONGSON_COUNTER1_ENABLE +#define LOONGSON_COUNTER2_OVERFLOW (1ULL << 31) +#define LOONGSON_COUNTER2_EXL (1UL << 0 ) +#define LOONGSON_COUNTER_EXL (1UL << 0) + +/* Loongson2 PerfCount performance counter register */ +#define read_c0_perflo() __read_64bit_c0_register($24, 0) +#define write_c0_perflo(val) __write_64bit_c0_register($24, 0, val) +#define read_c0_perfhi() __read_64bit_c0_register($25, 0) +#define write_c0_perfhi(val) __write_64bit_c0_register($25, 0, val) + +extern unsigned int loongson2_perfcount_irq; + +static struct loongson2_register_config { + unsigned int control; + unsigned long long reset_counter1; + unsigned long long reset_counter2; + int ctr1_enable, ctr2_enable; +} reg; + +#if 0 +unsigned long ctr3_enable, ctr3_count; +#endif + +DEFINE_SPINLOCK(sample_lock); + +static char *oprofid = "LoongsonPerf"; +static irqreturn_t loongson2_perfcount_handler(int irq, void * dev_id); +/* Compute all of the registers in preparation for enabling profiling. */ + +static void loongson2_reg_setup(struct op_counter_config *ctr) +{ + unsigned int control = 0; + + reg.reset_counter1 = 0; + reg.reset_counter2 = 0; + /* Compute the performance counter control word. */ + /* For now count kernel and user mode */ + if (ctr[0].enabled){ + control |= LOONGSON_COUNTER1_EVENT(ctr[0].event) | + LOONGSON_COUNTER1_ENABLE; + if(ctr[0].kernel) + control |= LOONGSON_COUNTER1_KERNEL; + if(ctr[0].user) + control |= LOONGSON_COUNTER1_USER; + reg.reset_counter1 = 0x80000000ULL - ctr[0].count; + } + + if (ctr[1].enabled){ + control |= LOONGSON_COUNTER2_EVENT(ctr[1].event) | + LOONGSON_COUNTER2_ENABLE; + if(ctr[1].kernel) + control |= LOONGSON_COUNTER2_KERNEL; + if(ctr[1].user) + control |= LOONGSON_COUNTER2_USER; + reg.reset_counter2 = (0x80000000ULL- ctr[1].count) ; + } + + if(ctr[0].enabled ||ctr[1].enabled) + control |= LOONGSON_COUNTER_EXL; + +#if 0 + if(ctr[2].enabled){ + ctr3_enable = 1; + ctr3_count = ctr[2].count; + } +#endif + + reg.control = control; + + reg.ctr1_enable = ctr[0].enabled; + reg.ctr2_enable = ctr[1].enabled; + +} + +/* Program all of the registers in preparation for enabling profiling. */ + +static void loongson2_cpu_setup (void *args) +{ + uint64_t perfcount; + + perfcount = (reg.reset_counter2 << 32) |reg.reset_counter1; + write_c0_perfhi(perfcount); +} + +static void loongson2_cpu_start(void *args) +{ + /* Start all counters on current CPU */ + if(reg.ctr1_enable || reg.ctr2_enable) { + write_c0_perflo(reg.control); + } +} + +static void loongson2_cpu_stop(void *args) +{ + /* Stop all counters on current CPU */ + //ctr3_enable = 0; + write_c0_perflo(0); + memset(®, 0, sizeof(reg)); +} + +static irqreturn_t loongson2_perfcount_handler(int irq, void * dev_id) +{ + uint64_t counter, counter1, counter2; + struct pt_regs *regs = get_irq_regs(); + int enabled; + unsigned long flags; + + /* + * LOONGSON2 defines two 32-bit performance counters. + * To avoid a race updating the registers we need to stop the counters + * while we're messing with + * them ... + */ + + /* Check whether the irq belongs to me*/ + enabled = reg.ctr1_enable| reg.ctr2_enable; + if(!enabled){ + return IRQ_NONE; + } + + counter = read_c0_perfhi(); + counter1 = counter & 0xffffffff; + counter2 = counter >> 32; + + spin_lock_irqsave(&sample_lock, flags); + + if (counter1 & LOONGSON_COUNTER1_OVERFLOW) { + if(reg.ctr1_enable) + oprofile_add_sample(regs, 0); + counter1 = reg.reset_counter1; + } + if (counter2 & LOONGSON_COUNTER2_OVERFLOW) { + if(reg.ctr2_enable) + oprofile_add_sample(regs, 1); + counter2 = reg.reset_counter2; + } + + spin_unlock_irqrestore(&sample_lock, flags); + + write_c0_perfhi((counter2 << 32) | counter1); + + return IRQ_HANDLED; +} + +static int __init loongson2_init(void) +{ + return request_irq(PERF_IRQ, loongson2_perfcount_handler, + IRQF_SHARED, "Perfcounter", oprofid); +} + +static void loongson2_exit(void) +{ + free_irq(PERF_IRQ, oprofid); +} + +struct op_mips_model op_model_loongson2_ops = { + .reg_setup = loongson2_reg_setup, + .cpu_setup = loongson2_cpu_setup, + .init = loongson2_init, + .exit = loongson2_exit, + .cpu_start = loongson2_cpu_start, + .cpu_stop = loongson2_cpu_stop, + .cpu_type = "mips/loongson2", + .num_counters = 2 +}; diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index c8c32f4..b023e1c 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -27,6 +27,8 @@ obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o obj-$(CONFIG_LEMOTE_FULONG) += fixup-lm2e.o ops-bonito64.o +obj-$(CONFIG_LEMOTE_FULONG2F) += fixup-lm2f.o ops-loongson2f.o +obj-$(CONFIG_LEMOTE_2FNOTEBOOK) += fixup-lmbook.o ops-loongson2f.o obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o diff --git a/arch/mips/pci/fixup-lm2f.c b/arch/mips/pci/fixup-lm2f.c new file mode 100644 index 0000000..c8b2f81 --- /dev/null +++ b/arch/mips/pci/fixup-lm2f.c @@ -0,0 +1,239 @@ +/* + * fixup-lm2f.c + * + * Copyright (C) 2004 ICT CAS + * Author: Li xiaoyu, ICT CAS + * lixy@ict.ac.cn + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include + +/* PCI interrupt pins */ +/* These should not be changed, or you should consider godson2f interrupt register and + * your pci card dispatch + */ +#define PCIA 4 +#define PCIB 5 +#define PCIC 6 +#define PCID 7 + +/* all the pci device has the PCIA pin, check the datasheet. */ +static char irq_tab[][5] __initdata = { + /* INTA INTB INTC INTD */ + {0, 0, 0, 0, 0 }, /* 11: Unused */ + {0, 0, 0, 0, 0 }, /* 12: Unused */ + {0, 0, 0, 0, 0 }, /* 13: Unused */ + {0, 0, 0, 0, 0 }, /* 14: Unused */ + {0, 0, 0, 0, 0 }, /* 15: Unused */ + {0, 0, 0, 0, 0 }, /* 16: Unused */ + {0, PCIA, 0, 0, 0 }, /* 17: RTL8110-0 */ + {0, PCIB, 0, 0, 0 }, /* 18: RTL8110-1 */ + {0, PCIC, 0, 0, 0 }, /* 19: SiI3114 */ + {0, 0, 0, 0, 0 }, /* 20: Unused */ + {0, PCIA, PCIB, PCIC, PCID }, /* 21: PCI-SLOT */ + {0, 0, 0, 0, 0 }, /* 22: Unused */ + {0, 0, 0, 0, 0 }, /* 23: Unused */ + {0, 0, 0, 0, 0 }, /* 24: Unused */ + {0, 0, 0, 0, 0 }, /* 25: Unused */ + {0, 0, 0, 0, 0 }, /* 26: Unused */ + {0, 0, 0, 0, 0 }, /* 27: Unused */ +}; + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + int virq; +#if 0 + if(PCI_SLOT(dev->devfn) == (17 - 11) ){ /* RTL8110SC_0 */ + dev->irq = BONITO_IRQ_BASE + 25 + 1; + (void) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + return dev->irq; + }else if(PCI_SLOT(dev->devfn) == (18 - 11)){ /* RTL8110SC_1 */ + dev->irq = BONITO_IRQ_BASE + 25 + 2; + (void) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + return dev->irq; + }else if(PCI_SLOT(dev->devfn) == (19 - 11)){ /* SiI3114 */ + dev->irq = BONITO_IRQ_BASE + 25 + 3; + (void) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + return dev->irq; + //} + //else if(PCI_SLOT(dev->devfn) == (21 - 11)){ /* PCI SLOT */ + // dev->irq = BONITO_IRQ_BASE + 25 + 4; + // (void) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + // return dev->irq; + }else +#endif + + if( (PCI_SLOT(dev->devfn) != (14)) && (PCI_SLOT(dev->devfn) < 32) ){ + virq = irq_tab[slot][pin]; + printk("slot: %d, pin: %d, irq: %d\n", slot, pin, virq+BONITO_IRQ_BASE); + if(virq != 0) + return (BONITO_IRQ_BASE + virq); + else + return 0; + }else if( PCI_SLOT(dev->devfn) == 14){ // cs5536 + switch(PCI_FUNC(dev->devfn)){ + case 2 : + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 14); + return 14; // for IDE + case 3 : + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 9); + return 9; // for AUDIO + case 4 : // for OHCI + case 5 : // for EHCI + case 6 : // for UDC + case 7 : // for OTG + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); + return 11; + } + return dev->irq; + }else{ + printk(" strange pci slot number.\n"); + return 0; + } +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +#ifndef TEST_NO_CS5536 +/* CS5536 SPEC. fixup */ +static void __init loongson2e_cs5536_isa_fixup(struct pci_dev *pdev) +{ + /* the uart1 and uart2 interrupt in PIC is enabled as default */ + pci_write_config_dword(pdev, 0x50, 1); + pci_write_config_dword(pdev, 0x54, 1); + /* enable the pci MASTER ABORT/ TARGET ABORT etc. */ + pci_write_config_dword(pdev, 0x58, 1); + return; +} + + +static void __init loongson2e_cs5536_ide_fixup(struct pci_dev *pdev) +{ + /* setting the mutex pin as IDE function */ + /* the IDE interrupt in PIC is enabled as default */ + pci_write_config_dword(pdev, 0x40, 0xDEADBEEF); + return; +} + +static void __init loongson2e_cs5536_acc_fixup(struct pci_dev *pdev) +{ + u8 val; + + /* enable the AUDIO interrupt in PIC */ + pci_write_config_dword(pdev, 0x50, 1); + +#if 1 + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &val); + printk("cs5536 acc latency %x\n", val); + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0); +#endif + return; +} + +static void __init loongson2e_cs5536_ohci_fixup(struct pci_dev *pdev) +{ + /* enable the OHCI interrupt in PIC */ + /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */ + pci_write_config_dword(pdev, 0x50, 1); + return; +} + +static void __init loongson2e_cs5536_ehci_fixup(struct pci_dev *pdev) +{ + /* setting the USB2.0 micro frame length */ + pci_write_config_dword(pdev, 0x60, 0x2000); + return; +} +#endif /* TEST_NO_CS5536 */ + +static void __init loongson2e_fixup_pcimap(struct pci_dev *pdev) +{ + static int first = 1; + u32 tmp; + + (void)pdev; + if (first) + first = 0; + else + return; + + /* local to PCI mapping: [256M,512M] -> [256M,512M]; differ from pmon */ + /* + * cpu address space [256M,448M] is window for accessing pci space + * we set pcimap_lo[0,1,2] to map it to pci space [256M,448M] + * pcimap: bit18,pcimap_2; bit[17-12],lo2;bit[11-6],lo1;bit[5-0],lo0 + */ + /* 1,00 0110 ,0001 01,00 0000 */ + BONITO_PCIMAP = 0x46140; + //1, 00 0010, 0000,01, 00 0000 + //BONITO_PCIMAP = 0x42040; + + /* + * PCI to local mapping: [2G,2G+256M] -> [0,256M] + */ +#if 1 // for GODSON2F + BONITO_PCIBASE0 = 0x80000000; + BONITO_PCIBASE1 = 0x00000000; + BONITO(BONITO_REGBASE + 0x50) = 0x8000000c; + BONITO(BONITO_REGBASE + 0x54) = 0xffffffff; +#else // for GODSON2E + BONITO_PCIBASE0 = 0x80000000; + BONITO_PCIBASE1 = 0x00800000; + BONITO_PCIBASE2 = 0x90000000; +#endif + +#ifdef CONFIG_64BIT + *(volatile u32*)0xffffffffbfe0004c = 0xd2000001; +/* + tmp = *(volatile u32*)0xffffffffbfe00058ULL; + tmp &= ~0x0000ff00; + tmp |= 0x0000ff80; + *(volatile u32*)0xffffffffbfe00058 = tmp; +*/ +#else + *(volatile u32*)0xbfe0004c = 0xd2000001; +#endif +} + +#ifndef TEST_NO_CS5536 +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, + loongson2e_cs5536_isa_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC, + loongson2e_cs5536_ohci_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC, + loongson2e_cs5536_ehci_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO, + loongson2e_cs5536_acc_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, + loongson2e_cs5536_ide_fixup); +#endif /* TEST_NO_CS5536 */ +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, loongson2e_fixup_pcimap); diff --git a/arch/mips/pci/fixup-lmbook.c b/arch/mips/pci/fixup-lmbook.c new file mode 100644 index 0000000..58a1a18 --- /dev/null +++ b/arch/mips/pci/fixup-lmbook.c @@ -0,0 +1,256 @@ +/* + * fixup-lm2f.c + * + * Copyright (C) 2004 ICT CAS + * Author: Li xiaoyu, ICT CAS + * lixy@ict.ac.cn + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include + +/* PCI interrupt pins */ +/* These should not be changed, or you should consider godson2f interrupt register and + * your pci card dispatch + */ +#define PCIA 4 +#define PCIB 5 +#define PCIC 6 +#define PCID 7 + +/* all the pci device has the PCIA pin, check the datasheet. */ +static char irq_tab[][5] __initdata = { + /* INTA INTB INTC INTD */ + {0, 0, 0, 0, 0 }, /* 11: Unused */ + {0, 0, 0, 0, 0 }, /* 12: Unused */ + {0, 0, 0, 0, 0 }, /* 13: Unused */ + {0, 0, 0, 0, 0 }, /* 14: Unused */ + {0, 0, 0, 0, 0 }, /* 15: Unused */ + {0, 0, 0, 0, 0 }, /* 16: Unused */ + {0, PCIA, 0, 0, 0 }, /* 17: RTL8110-0 */ + {0, PCIB, 0, 0, 0 }, /* 18: RTL8110-1 */ + {0, PCIC, 0, 0, 0 }, /* 19: SiI3114 */ + {0, PCID, 0, 0, 0 }, /* 20: 3-ports nec usb*/ + {0, PCIA, PCIB, PCIC, PCID }, /* 21: PCI-SLOT */ + {0, 0, 0, 0, 0 }, /* 22: Unused */ + {0, 0, 0, 0, 0 }, /* 23: Unused */ + {0, 0, 0, 0, 0 }, /* 24: Unused */ + {0, 0, 0, 0, 0 }, /* 25: Unused */ + {0, 0, 0, 0, 0 }, /* 26: Unused */ + {0, 0, 0, 0, 0 }, /* 27: Unused */ +}; + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + int virq; + + if( (PCI_SLOT(dev->devfn) != (14)) && (PCI_SLOT(dev->devfn) < 32) ){ + virq = irq_tab[slot][pin]; + printk("slot: %d, pin: %d, irq: %d\n", slot, pin, virq+BONITO_IRQ_BASE); + if(virq != 0) + return (BONITO_IRQ_BASE + virq); + else + return 0; + }else if( PCI_SLOT(dev->devfn) == 14){ // cs5536 + switch(PCI_FUNC(dev->devfn)){ + case 2 : + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 14); + return 14; // for IDE + case 3 : + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 9); + return 9; // for AUDIO + case 4 : // for OHCI + case 5 : // for EHCI + case 6 : // for UDC + case 7 : // for OTG + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); + return 11; + } + return dev->irq; + }else{ + printk(" strange pci slot number.\n"); + return 0; + } +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +#ifndef TEST_NO_CS5536 + +extern void _wrmsr(u32 reg, u32 hi, u32 lo); +extern void _rdmsr(u32 reg, u32 *hi, u32 *lo); + +/* CS5536 SPEC. fixup */ +static void __init loongson2f_cs5536_isa_fixup(struct pci_dev *pdev) +{ + /* the uart1 and uart2 interrupt in PIC is enabled as default */ + pci_write_config_dword(pdev, 0x50, 1); + pci_write_config_dword(pdev, 0x54, 1); + /* enable the pci MASTER ABORT/ TARGET ABORT etc. */ + //pci_write_config_dword(pdev, 0x58, 1); + return; +} + + +static void __init loongson2f_cs5536_ide_fixup(struct pci_dev *pdev) +{ + /* setting the mutex pin as IDE function */ + /* the IDE interrupt in PIC is enabled as default */ + pci_write_config_dword(pdev, 0x40, 0xDEADBEEF); + return; +} + +static void __init loongson2f_cs5536_acc_fixup(struct pci_dev *pdev) +{ + u8 val; + + /* enable the AUDIO interrupt in PIC */ + pci_write_config_dword(pdev, 0x50, 1); + +#if 1 + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &val); + printk("cs5536 acc latency %x\n", val); + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0); +#endif + return; +} + +static void __init loongson2f_cs5536_ohci_fixup(struct pci_dev *pdev) +{ + /* enable the OHCI interrupt in PIC */ + /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */ + pci_write_config_dword(pdev, 0x50, 1); + return; +} + +static void __init loongson2f_cs5536_ehci_fixup(struct pci_dev *pdev) +{ + u32 hi, lo; +#if 0 + u32 bar; + void __iomem *base; +#endif + + /* Serial short detect enable */ + _rdmsr(0x40000001, &hi, &lo); + _wrmsr(0x40000001, (1<<1)|(1<<2)|(1<<3), lo); + +#if 0 + /* Write to clear diag register */ + _rdmsr(0x40000005, &hi, &lo); + _wrmsr(0x40000005, hi, lo); + + pci_read_config_dword(pdev, 0x10, &bar); + base = ioremap_nocache(bar, 0x100); + + /* Make HCCAPARMS writable */ + writel(readl(base + 0xA0) | (1<<1), (base + 0xA0)); + + /* EECP=50h, IST=01h, ASPC=1h */ + writel(0x00000012, base + 0x08); + iounmap(base); +#endif + + /* setting the USB2.0 micro frame length */ + pci_write_config_dword(pdev, 0x60, 0x2000); + return; +} +#endif /* TEST_NO_CS5536 */ + +static void __init loongson2f_fixup_pcimap(struct pci_dev *pdev) +{ + static int first = 1; + + (void)pdev; + if (first) + first = 0; + else + return; + + /* local to PCI mapping: [256M,512M] -> [256M,512M]; differ from pmon */ + /* + * cpu address space [256M,448M] is window for accessing pci space + * we set pcimap_lo[0,1,2] to map it to pci space [256M,448M] + * pcimap: bit18,pcimap_2; bit[17-12],lo2;bit[11-6],lo1;bit[5-0],lo0 + */ + /* 1,00 0110 ,0001 01,00 0000 */ + BONITO_PCIMAP = 0x46140; + //1, 00 0010, 0000,01, 00 0000 + //BONITO_PCIMAP = 0x42040; + + /* + * PCI to local mapping: [2G,2G+256M] -> [0,256M] + */ +#if 1 // for GODSON2F + BONITO_PCIBASE0 = 0x80000000; + BONITO_PCIBASE1 = 0x00000000; + BONITO(BONITO_REGBASE + 0x50) = 0xc000000c; + BONITO(BONITO_REGBASE + 0x54) = 0xffffffff; + BONITO(BONITO_REGBASE + 0x58) = 0x00000006; + BONITO(BONITO_REGBASE + 0x5c) = 0x00000000; + BONITO(BONITO_REGBASE + 0x60) = 0x00000006; + BONITO(BONITO_REGBASE + 0x64) = 0x00000000; +#else // for GODSON2E + BONITO_PCIBASE0 = 0x80000000; + BONITO_PCIBASE1 = 0x00800000; + BONITO_PCIBASE2 = 0x90000000; +#endif + +#ifdef CONFIG_64BIT + *(volatile u32*)0xffffffffbfe0004c = 0xd2000001; +#else + *(volatile u32*)0xbfe0004c = 0xd2000001; +#endif +} + +static void __init loongson2f_nec_fixup(struct pci_dev *pdev) +{ + unsigned int val; + + /* Configues port 1, 2, 3 to be validate*/ + pci_read_config_dword(pdev, 0xe0, &val); + pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2); /*Only 2 port be used*/ +} +#ifndef TEST_NO_CS5536 +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, + loongson2f_cs5536_isa_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC, + loongson2f_cs5536_ohci_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC, + loongson2f_cs5536_ehci_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO, + loongson2f_cs5536_acc_fixup); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, + loongson2f_cs5536_ide_fixup); +#endif /* TEST_NO_CS5536 */ +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, loongson2f_fixup_pcimap); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, + loongson2f_nec_fixup); diff --git a/arch/mips/pci/ops-loongson2f.c b/arch/mips/pci/ops-loongson2f.c new file mode 100644 index 0000000..08e8b7f --- /dev/null +++ b/arch/mips/pci/ops-loongson2f.c @@ -0,0 +1,205 @@ +/* + * ops-lm2f.c + * + * Copyright (C) 2004 ICT CAS + * Author: Li xiaoyu, ICT CAS + * lixy@ict.ac.cn + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * 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 +#include +#include + +#include + +#define PCI_OPS_CS5536_IDSEL 14 + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +extern void cs5536_pci_conf_write4(int function, int reg, u32 value); +extern u32 cs5536_pci_conf_read4(int function, int reg); + +static inline void bflush(void) +{ + /* flush Bonito register writes */ + (void)BONITO_PCICMD; +} + +static int lm2f_pci_config_access(unsigned char access_type, + struct pci_bus *bus, unsigned int devfn, + int where, u32 *data) +{ + u32 busnum = bus->number; + u32 addr, type; + void *addrp; + int device = PCI_SLOT(devfn); + int function = PCI_FUNC(devfn); + int reg = where & ~3; + + /************************************************************************/ + /* CS5536 PCI ACCESS ROUTINE : */ + /* Note the functions circle call : */ + /* lm2e_pci_config_access()--->cs5536_pci_conf_read/write4()---> */ + /* _rdmsr/_wrmsr()--->lm2e_pci_config_access() */ + /************************************************************************/ + if( (busnum == 0) && (device == PCI_OPS_CS5536_IDSEL) && (reg < 0xF0) ){ + switch(access_type){ + case PCI_ACCESS_READ : + *data = cs5536_pci_conf_read4(function, reg); + break; + case PCI_ACCESS_WRITE : + cs5536_pci_conf_write4(function, reg, *data); + break; + } + return 0; + } + + if (busnum == 0) { + /* Type 0 configuration on onboard PCI bus */ + if (device > 20 || function > 7) { + *data = -1; /* device out of range */ + return PCIBIOS_DEVICE_NOT_FOUND; + } + addr = (1 << (device + 11)) | (function << 8) | reg; + type = 0; + } else { + /* Type 1 configuration on offboard PCI bus */ + if (device > 31 || function > 7) { + *data = -1; /* device out of range */ + return PCIBIOS_DEVICE_NOT_FOUND; + } + addr = (busnum << 16) | (device << 11) | (function << 8) | reg; + type = 0x10000; + } + + /* clear aborts */ + BONITO_PCICMD |= BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR; + + BONITO_PCIMAP_CFG = (addr >> 16) | type; + bflush(); + + addrp = (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (addr & 0xffff)); + if (access_type == PCI_ACCESS_WRITE) { + *(volatile unsigned int *)addrp = cpu_to_le32(*data); + } else { + *data = le32_to_cpu(*(volatile unsigned int *)addrp); + } + + /* Detect Master/Target abort */ + if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR)) { + BONITO_PCICMD |= BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR; + *data = -1; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + return PCIBIOS_SUCCESSFUL; + +} + +static int lm2f_pci_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + u32 data = 0; + + int ret = lm2f_pci_config_access(PCI_ACCESS_READ, + bus, devfn, where, &data); + + if (ret != PCIBIOS_SUCCESSFUL) + return ret; + + if (size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int lm2f_pci_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + int ret; + + if (size == 4) + data = val; + else { + ret = lm2f_pci_config_access(PCI_ACCESS_READ, + bus, devfn, where, &data); + if (ret != PCIBIOS_SUCCESSFUL) + return ret; + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + } + + ret = lm2f_pci_config_access(PCI_ACCESS_WRITE, + bus, devfn, where, &data); + if (ret != PCIBIOS_SUCCESSFUL) + return ret; + + return PCIBIOS_SUCCESSFUL; +} + +void _rdmsr(u32 msr, u32 *hi, u32 *lo) +{ + struct pci_bus bus = { + .number = 0 + }; + u32 devfn = PCI_DEVFN(14, 0); + lm2f_pci_pcibios_write(&bus, devfn, 0xf4, 4, msr); + lm2f_pci_pcibios_read(&bus, devfn, 0xf8, 4, lo); + lm2f_pci_pcibios_read(&bus, devfn, 0xfc, 4, hi); + //printk("rdmsr msr %x, lo %x, hi %x\n", msr, *lo, *hi); +} + +void _wrmsr(u32 msr, u32 hi, u32 lo) +{ + struct pci_bus bus = { + .number = 0 + }; + u32 devfn = PCI_DEVFN(14, 0); + lm2f_pci_pcibios_write(&bus, devfn, 0xf4, 4, msr); + lm2f_pci_pcibios_write(&bus, devfn, 0xf8, 4, lo); + lm2f_pci_pcibios_write(&bus, devfn, 0xfc, 4, hi); + //printk("wrmsr msr %x, lo %x, hi %x\n", msr, lo, hi); +} + +EXPORT_SYMBOL(_rdmsr); +EXPORT_SYMBOL(_wrmsr); + +struct pci_ops loongson2f_pci_pci_ops = { + .read = lm2f_pci_pcibios_read, + .write = lm2f_pci_pcibios_write +}; diff --git a/arch/mips/power/Makefile b/arch/mips/power/Makefile new file mode 100644 index 0000000..73d56b8 --- /dev/null +++ b/arch/mips/power/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_HIBERNATION) += cpu.o hibernate.o diff --git a/arch/mips/power/cpu.c b/arch/mips/power/cpu.c new file mode 100644 index 0000000..b799bfe --- /dev/null +++ b/arch/mips/power/cpu.c @@ -0,0 +1,48 @@ +/* + * Suspend support specific for mips. + * + */ +#include +#include +#include +#include + +/* References to section boundaries */ +extern const void __nosave_begin, __nosave_end; +static uint32_t saved_status; +unsigned long + saved_ra, + saved_sp, + saved_fp, + saved_gp, + saved_s0, + saved_s1, + saved_s2, + saved_s3, + saved_s4, + saved_s5, + saved_s6, + saved_s7, + saved_a0, + saved_a1, + saved_a2, + saved_a3, + saved_v0, + saved_v1; + +void save_processor_state(void) +{ + saved_status = read_c0_status(); +} + +void restore_processor_state(void) +{ + write_c0_status(saved_status); +} + +int pfn_is_nosave(unsigned long pfn) +{ + unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; + unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT; + return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); +} diff --git a/arch/mips/power/hibernate.S b/arch/mips/power/hibernate.S new file mode 100644 index 0000000..e45ec45 --- /dev/null +++ b/arch/mips/power/hibernate.S @@ -0,0 +1,78 @@ +#incldue +#include +#include +#include + +.text +LEAF(swsusp_arch_suspend) + PTR_LA t0, saved_ra + PTR_S ra, (t0) + PTR_LA t0, saved_sp + PTR_S sp, (t0) + PTR_LA t0, saved_fp + PTR_S fp, (t0) + PTR_LA t0, saved_gp + PTR_S gp, (t0) + PTR_LA t0, saved_s0 + PTR_S s0, (t0) + PTR_LA t0, saved_s1 + PTR_S s1, (t0) + PTR_LA t0, saved_s2 + PTR_S s2, (t0) + PTR_LA t0, saved_s3 + PTR_S s3, (t0) + PTR_LA t0, saved_s4 + PTR_S s4, (t0) + PTR_LA t0, saved_s5 + PTR_S s5, (t0) + PTR_LA t0, saved_s6 + PTR_S s6, (t0) + PTR_LA t0, saved_s7 + PTR_S s7, (t0) + PTR_LA t0, saved_a0 + PTR_S a0, (t0) + PTR_LA t0, saved_a1 + PTR_S a1, (t0) + PTR_LA t0, saved_a2 + PTR_S a2, (t0) + PTR_LA t0, saved_v1 + PTR_S v1, (t0) + j swsusp_save + nop +END(swsusp_arch_suspend) + +LEAF(swsusp_arch_resume) + PTR_L t0, restore_pblist +0: + PTR_L t1, PBE_ADDRESS(t0) /* source */ + PTR_L t2, PBE_ORIG_ADDRESS(t0) /* destination */ + PTR_ADDIU t3, t1, _PAGE_SIZE +1: + REG_L t8, (t1) + REG_S t8, (t2) + PTR_ADDIU t1, t1, SZREG + PTR_ADDIU t2, t2, SZREG + bne t1, t3, 1b + PTR_L t0, PBE_NEXT(t0) + bnez t0, 0b + //flush cache and tlb. no need?I am not sure. + PTR_L ra, saved_ra + PTR_L sp, saved_sp + PTR_L fp, saved_fp + PTR_L s0, saved_s0 + PTR_L s1, saved_s1 + PTR_L s2, saved_s2 + PTR_L s3, saved_s3 + PTR_L s4, saved_s4 + PTR_L s5, saved_s5 + PTR_L s6, saved_s6 + PTR_L s7, saved_s7 + PTR_L a0, saved_a0 + PTR_L a1, saved_a1 + PTR_L a2, saved_a2 + PTR_L a3, saved_a3 + PTR_LI v0, 0x0 + PTR_L v1, saved_v1 + jr ra + nop +END(swsusp_arch_resume) diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index f6d9bf4..d061481 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -68,7 +68,7 @@ static void enable_local1_irq(unsigned int irq) sgint->imask1 |= (1 << (irq - SGINT_LOCAL1)); } -void disable_local1_irq(unsigned int irq) +static void disable_local1_irq(unsigned int irq) { sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); } @@ -87,7 +87,7 @@ static void enable_local2_irq(unsigned int irq) sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); } -void disable_local2_irq(unsigned int irq) +static void disable_local2_irq(unsigned int irq) { sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); if (!sgint->cmeimask0) @@ -108,7 +108,7 @@ static void enable_local3_irq(unsigned int irq) sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); } -void disable_local3_irq(unsigned int irq) +static void disable_local3_irq(unsigned int irq) { sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); if (!sgint->cmeimask1) @@ -344,6 +344,6 @@ void __init arch_init_irq(void) #ifdef CONFIG_EISA if (ip22_is_fullhouse()) /* Only Indigo-2 has EISA stuff */ - ip22_eisa_init(); + ip22_eisa_init(); #endif } diff --git a/arch/mips/zboot/Makefile b/arch/mips/zboot/Makefile new file mode 100644 index 0000000..9c3bc8a --- /dev/null +++ b/arch/mips/zboot/Makefile @@ -0,0 +1,62 @@ +# +# arch/mips/zboot/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. + +# Adapted for MIPS Pete Popov, Dan Malek +# +# Copyright (C) 1994 by Linus Torvalds +# Adapted for PowerPC by Gary Thomas +# modified by Cort (cort@cs.nmt.edu) +# + +targets := bzImage + +EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/zboot/include + +CFLAGS := $(ZBOOT_FLAGS) + + +.c.s: + $(CC) $(CFLAGS) -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $*.o $< +.S.s: + $(CPP) $(AFLAGS) -o $*.o $< +.S.o: + $(CC) $(AFLAGS) -c -o $*.o $< + +GZIP_FLAGS = -v9f +EXTRA_CFLAGS := $(CFLAGS) \ + -I$(TOPDIR)/arch/$(ARCH)/zboot/include \ + -I$(TOPDIR)/include/asm +AFLAGS += -D__BOOTER__ + +BOOT_TARGETS = zImage zImage.initrd zImage.flash zImage.initrd.flash + +images/vmlinux.gz: $(TOPDIR)/vmlinux + $(MAKE) -C images vmlinux.gz + +$(BOOT_TARGETS): lib/zlib.a images/vmlinux.gz + +ifdef CONFIG_LEMOTE_FULONG +SUBARCH := $(obj)/lm2e +KBUILD_IMAGE := arch/mips/zboot/lm2e/bzImage +endif +ifdef CONFIG_MACH_LM2F +SUBARCH := $(obj)/lm2f +KBUILD_IMAGE := arch/mips/zboot/lm2f/bzImage +endif + +$(obj)/bzImage: + $(Q)$(MAKE) $(build)=$(SUBARCH) $(KBUILD_IMAGE) + +# Do the dirs +clean: + $(MAKE) -C common clean + $(MAKE) -C images clean + diff --git a/arch/mips/zboot/common/Makefile b/arch/mips/zboot/common/Makefile new file mode 100644 index 0000000..1beb038 --- /dev/null +++ b/arch/mips/zboot/common/Makefile @@ -0,0 +1,26 @@ +# +# arch/mips/zboot/common/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Tom Rini January 2001 +# + +CFLAGS :=$(CFLAGS) -fno-builtin +.c.s: + $(CC) $(CFLAGS) -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) -c -o $*.o $< +.S.s: + $(CPP) $(AFLAGS) -o $*.o $< +.S.o: + $(CC) $(AFLAGS) -c -o $*.o $< + +clean: + rm -rf *.o + +OBJCOPY_ARGS = -O elf32-tradlittlemips diff --git a/arch/mips/zboot/common/au1k_uart.c b/arch/mips/zboot/common/au1k_uart.c new file mode 100644 index 0000000..a8cf1e1 --- /dev/null +++ b/arch/mips/zboot/common/au1k_uart.c @@ -0,0 +1,103 @@ +/* + * BRIEF MODULE DESCRIPTION + * Simple Au1000 uart routines. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 +#include +#include +#include "ns16550.h" + +typedef unsigned char uint8; +typedef unsigned int uint32; + +#define UART16550_BAUD_2400 2400 +#define UART16550_BAUD_4800 4800 +#define UART16550_BAUD_9600 9600 +#define UART16550_BAUD_19200 19200 +#define UART16550_BAUD_38400 38400 +#define UART16550_BAUD_57600 57600 +#define UART16550_BAUD_115200 115200 + +#define UART16550_PARITY_NONE 0 +#define UART16550_PARITY_ODD 0x08 +#define UART16550_PARITY_EVEN 0x18 +#define UART16550_PARITY_MARK 0x28 +#define UART16550_PARITY_SPACE 0x38 + +#define UART16550_DATA_5BIT 0x0 +#define UART16550_DATA_6BIT 0x1 +#define UART16550_DATA_7BIT 0x2 +#define UART16550_DATA_8BIT 0x3 + +#define UART16550_STOP_1BIT 0x0 +#define UART16550_STOP_2BIT 0x4 + +/* It would be nice if we had a better way to do this. + * It could be a variable defined in one of the board specific files. + */ +#undef UART_BASE +#ifdef CONFIG_COGENT_CSB250 +#define UART_BASE UART3_ADDR +#else +#define UART_BASE UART0_ADDR +#endif + +/* memory-mapped read/write of the port */ +#define UART16550_READ(y) (readl(UART_BASE + y) & 0xff) +#define UART16550_WRITE(y,z) (writel(z&0xff, UART_BASE + y)) + +/* + * We use uart 0, which is already initialized by + * yamon. + */ +volatile struct NS16550 * +serial_init(int chan) +{ + volatile struct NS16550 *com_port; + com_port = (struct NS16550 *) UART_BASE; + return (com_port); +} + +void +serial_putc(volatile struct NS16550 *com_port, unsigned char c) +{ + while ((UART16550_READ(UART_LSR)&0x40) == 0); + UART16550_WRITE(UART_TX, c); +} + +unsigned char +serial_getc(volatile struct NS16550 *com_port) +{ + while((UART16550_READ(UART_LSR) & 0x1) == 0); + return UART16550_READ(UART_RX); +} + +int +serial_tstc(volatile struct NS16550 *com_port) +{ + return((UART16550_READ(UART_LSR) & LSR_DR) != 0); +} diff --git a/arch/mips/zboot/common/ctype.c b/arch/mips/zboot/common/ctype.c new file mode 100644 index 0000000..b5f72a5 --- /dev/null +++ b/arch/mips/zboot/common/ctype.c @@ -0,0 +1,35 @@ +/* + * linux/lib/ctype.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include + +unsigned char _ctype[] = { +_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ +_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ +_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ +_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ +_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ +_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ +_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ +_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ +_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ +_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ +_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ +_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ +_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ +_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ + + diff --git a/arch/mips/zboot/common/dummy.c b/arch/mips/zboot/common/dummy.c new file mode 100644 index 0000000..31dbf45 --- /dev/null +++ b/arch/mips/zboot/common/dummy.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/arch/mips/zboot/common/misc-common.c b/arch/mips/zboot/common/misc-common.c new file mode 100644 index 0000000..e363e1a --- /dev/null +++ b/arch/mips/zboot/common/misc-common.c @@ -0,0 +1,437 @@ +/* + * arch/mips/zboot/common/misc-common.c + * + * Misc. bootloader code (almost) all platforms can use + * + * Author: Johnnie Peters + * Editor: Tom Rini + * + * Derived from arch/ppc/boot/prep/misc.c + * + * Ported by Pete Popov to + * support mips board(s). I also got rid of the vga console + * code. + * + * Copyright 2000-2001 MontaVista Software 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 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 "zlib.h" +#include + +extern char *avail_ram; +extern char *end_avail; +extern char _end[]; + +int puts(const char *); +void exit(void); +void putc(const char c); +void puthex(unsigned long val); +void _bcopy(char *src, char *dst, int len); +void gunzip(void *, int, unsigned char *, int *); +static int _cvt(unsigned long val, char *buf, long radix, char *digits); +int strlen(const char *s); +void _vprintk(void(*)(const char), const char *, va_list ap); + +struct NS16550 *com_port; + +int serial_tstc(volatile struct NS16550 *); +unsigned char serial_getc(volatile struct NS16550 *); +void serial_putc(volatile struct NS16550 *, unsigned char); + +void pause(void) +{ + puts("pause\n"); +} + +void exit(void) +{ + puts("exit\n"); + while(1); +} + +int tstc(void) +{ + return (serial_tstc(com_port)); +} + +int getc(void) +{ + while (1) { + if (serial_tstc(com_port)) + return (serial_getc(com_port)); + } +} + +void +putc(const char c) +{ + serial_putc(com_port, c); + if ( c == '\n' ) + serial_putc(com_port, '\r'); +} + +int puts(const char *s) +{ + char c; + while ( ( c = *s++ ) != '\0' ) { + serial_putc(com_port, c); + if ( c == '\n' ) serial_putc(com_port, '\r'); + } + + return 0; +} + +void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while(1); /* Halt */ +} + +void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p = avail_ram; + + size *= items; + size = (size + 7) & -8; + avail_ram += size; + if (avail_ram > end_avail) { + puts("oops... out of memory\n"); + pause(); + } + return p; +} + +void zfree(void *x, void *addr, unsigned nb) +{ +} + +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 + +#define DEFLATED 8 + +void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != DEFLATED || (flags & RESERVED) != 0) { + puts("bad gzipped data\n"); + exit(); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + puts("gunzip: ran out of data in header\n"); + exit(); + } + + s.zalloc = zalloc; + s.zfree = zfree; + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + puts("inflateInit2 returned %d\n"); + exit(); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = inflate(&s, Z_FINISH); + if (r != Z_OK && r != Z_STREAM_END) { + puts("inflate returned %d\n"); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + inflateEnd(&s); +} + +void +puthex(unsigned long val) +{ + + unsigned char buf[10]; + int i; + for (i = 7; i >= 0; i--) + { + buf[i] = "0123456789ABCDEF"[val & 0x0F]; + val >>= 4; + } + buf[8] = '\0'; + puts(buf); +} + +#define FALSE 0 +#define TRUE 1 + +void +_printk(char const *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + _vprintk(putc, fmt, ap); + va_end(ap); + return; +} + +#define is_digit(c) ((c >= '0') && (c <= '9')) + +void +_vprintk(void(*putc)(const char), const char *fmt0, va_list ap) +{ + char c, sign, *cp = 0; + int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right; + char buf[32]; + long val; + while ((c = *fmt0++)) + { + if (c == '%') + { + c = *fmt0++; + left_prec = right_prec = pad_on_right = 0; + if (c == '-') + { + c = *fmt0++; + pad_on_right++; + } + if (c == '0') + { + zero_fill = TRUE; + c = *fmt0++; + } else + { + zero_fill = FALSE; + } + while (is_digit(c)) + { + left_prec = (left_prec * 10) + (c - '0'); + c = *fmt0++; + } + if (c == '.') + { + c = *fmt0++; + zero_fill++; + while (is_digit(c)) + { + right_prec = (right_prec * 10) + (c - '0'); + c = *fmt0++; + } + } else + { + right_prec = left_prec; + } + sign = '\0'; + switch (c) + { + case 'd': + case 'x': + case 'X': + val = va_arg(ap, long); + switch (c) + { + case 'd': + if (val < 0) + { + sign = '-'; + val = -val; + } + length = _cvt(val, buf, 10, "0123456789"); + break; + case 'x': + length = _cvt(val, buf, 16, "0123456789abcdef"); + break; + case 'X': + length = _cvt(val, buf, 16, "0123456789ABCDEF"); + break; + } + cp = buf; + break; + case 's': + cp = va_arg(ap, char *); + length = strlen(cp); + break; + case 'c': + c = va_arg(ap, long /*char*/); + (*putc)(c); + continue; + default: + (*putc)('?'); + } + pad = left_prec - length; + if (sign != '\0') + { + pad--; + } + if (zero_fill) + { + c = '0'; + if (sign != '\0') + { + (*putc)(sign); + sign = '\0'; + } + } else + { + c = ' '; + } + if (!pad_on_right) + { + while (pad-- > 0) + { + (*putc)(c); + } + } + if (sign != '\0') + { + (*putc)(sign); + } + while (length-- > 0) + { + (*putc)(c = *cp++); + if (c == '\n') + { + (*putc)('\r'); + } + } + if (pad_on_right) + { + while (pad-- > 0) + { + (*putc)(c); + } + } + } else + { + (*putc)(c); + if (c == '\n') + { + (*putc)('\r'); + } + } + } +} + +int +_cvt(unsigned long val, char *buf, long radix, char *digits) +{ + char temp[80]; + char *cp = temp; + int length = 0; + if (val == 0) + { /* Special case */ + *cp++ = '0'; + } else + while (val) + { + *cp++ = digits[val % radix]; + val /= radix; + } + while (cp != temp) + { + *buf++ = *--cp; + length++; + } + *buf = '\0'; + return (length); +} + +void +_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base) +{ + int i, c; + if ((unsigned int)s > (unsigned int)p) + { + s = (unsigned int)s - (unsigned int)p; + } + while (s > 0) + { + if (base) + { + _printk("%06X: ", (int)p - (int)base); + } else + { + _printk("%06X: ", p); + } + for (i = 0; i < 16; i++) + { + if (i < s) + { + _printk("%02X", p[i] & 0xFF); + } else + { + _printk(" "); + } + if ((i % 2) == 1) _printk(" "); + if ((i % 8) == 7) _printk(" "); + } + _printk(" |"); + for (i = 0; i < 16; i++) + { + if (i < s) + { + c = p[i] & 0xFF; + if ((c < 0x20) || (c >= 0x7F)) c = '.'; + } else + { + c = ' '; + } + _printk("%c", c); + } + _printk("|\n"); + s -= 16; + p += 16; + } +} + +void +_dump_buf(unsigned char *p, int s) +{ + _printk("\n"); + _dump_buf_with_offset(p, s, 0); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff --git a/arch/mips/zboot/common/misc-simple.c b/arch/mips/zboot/common/misc-simple.c new file mode 100644 index 0000000..982c6e8 --- /dev/null +++ b/arch/mips/zboot/common/misc-simple.c @@ -0,0 +1,126 @@ +/* + * arch/mips/zboot/common/misc-simple.c + * + * Misc. bootloader code for many machines. This assumes you have are using + * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory + * below 8MB is free. Finally, it assumes you have a NS16550-style uart for + * your serial console. If a machine meets these requirements, it can quite + * likely use this code during boot. + * + * Author: Matt Porter + * Derived from arch/ppc/boot/prep/misc.c + * + * Copyright 2001 MontaVista Software 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. + */ + +#include +#include +#include +#include +#include + +#include "zlib.h" + +extern struct NS16550 *com_port; + +char *avail_ram; +char *end_avail; +extern char _end[]; +char *zimage_start; + +#ifdef CONFIG_CMDLINE +#define CMDLINE CONFIG_CMDLINE +#else +#define CMDLINE "" +#endif +char cmd_preset[] = CMDLINE; +char cmd_buf[256]; +char *cmd_line = cmd_buf; + +/* The linker tells us where the image is. +*/ +extern unsigned char __image_begin, __image_end; +extern unsigned char __ramdisk_begin, __ramdisk_end; +unsigned long initrd_size; + +extern void puts(const char *); +extern void putc(const char c); +extern void puthex(unsigned long val); +extern void *memcpy(void * __dest, __const void * __src, + __kernel_size_t __n); +extern void gunzip(void *, int, unsigned char *, int *); +extern void udelay(long delay); +extern int tstc(void); +extern int getc(void); +extern volatile struct NS16550 *serial_init(int chan); + +extern void flush_cache_all(void); +void +decompress_kernel(unsigned long load_addr, int num_words, + unsigned long cksum, unsigned long *sp) +{ + extern unsigned long start; + int zimage_size; + + com_port = (struct NS16550 *)serial_init(0); + + initrd_size = (unsigned long)(&__ramdisk_end) - + (unsigned long)(&__ramdisk_begin); + + /* + * Reveal where we were loaded at and where we + * were relocated to. + */ + puts("loaded at: "); puthex(load_addr); + puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); + if ( (unsigned long)load_addr != (unsigned long)&start ) + { + puts("relocated to: "); puthex((unsigned long)&start); + puts(" "); + puthex((unsigned long)((unsigned long)&start + (4*num_words))); + puts("\n"); + } + + /* + * We link ourself to an arbitrary low address. When we run, we + * relocate outself to that address. __image_being points to + * the part of the image where the zImage is. -- Tom + */ + zimage_start = (char *)(unsigned long)(&__image_begin); + zimage_size = (unsigned long)(&__image_end) - + (unsigned long)(&__image_begin); + + /* + * The zImage and initrd will be between start and _end, so they've + * already been moved once. We're good to go now. -- Tom + */ + puts("zimage at: "); puthex((unsigned long)zimage_start); + puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); + puts("\n"); + + if ( initrd_size ) { + puts("initrd at: "); + puthex((unsigned long)(&__ramdisk_begin)); + puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); + } + + /* assume the chunk below 8M is free */ + avail_ram = (char *)AVAIL_RAM_START; + end_avail = (char *)AVAIL_RAM_END; + + /* Display standard Linux/MIPS boot prompt for kernel args */ + puts("Uncompressing Linux at load address "); + puthex(LOADADDR); + puts("\n"); + /* I don't like this hard coded gunzip size (fixme) */ + gunzip((void *)LOADADDR, 0x1000000, zimage_start, &zimage_size); +#if 1 + flush_cache_all(); +#endif + puts("Now booting the kernel\n"); +} diff --git a/arch/mips/zboot/common/no_initrd.c b/arch/mips/zboot/common/no_initrd.c new file mode 100644 index 0000000..ed5dcdb --- /dev/null +++ b/arch/mips/zboot/common/no_initrd.c @@ -0,0 +1,2 @@ +char initrd_data[1]; +int initrd_len = 0; diff --git a/arch/mips/zboot/common/ns16550.c b/arch/mips/zboot/common/ns16550.c new file mode 100644 index 0000000..0477ec5 --- /dev/null +++ b/arch/mips/zboot/common/ns16550.c @@ -0,0 +1,57 @@ +/* + * NS16550 support + */ + +#include +#include +#include "ns16550.h" + +typedef struct NS16550 *NS16550_t; + +const NS16550_t COM_PORTS[] = { (NS16550_t) COM1, + (NS16550_t) COM2, + (NS16550_t) COM3, + (NS16550_t) COM4 }; + +volatile struct NS16550 * +serial_init(int chan) +{ + volatile struct NS16550 *com_port; + com_port = (struct NS16550 *) COM_PORTS[chan]; + /* See if port is present */ + com_port->lcr = 0x00; + com_port->ier = 0xFF; +#if 0 + if (com_port->ier != 0x0F) return ((struct NS16550 *)0); +#endif + com_port->ier = 0x00; + com_port->lcr = 0x80; /* Access baud rate */ +#ifdef CONFIG_SERIAL_CONSOLE_NONSTD + com_port->dll = (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD); + com_port->dlm = (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD) >> 8; +#endif + com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */ + com_port->mcr = 0x03; /* RTS/DTR */ + com_port->fcr = 0x07; /* Clear & enable FIFOs */ + return (com_port); +} + +void +serial_putc(volatile struct NS16550 *com_port, unsigned char c) +{ + while ((com_port->lsr & LSR_THRE) == 0) ; + com_port->thr = c; +} + +unsigned char +serial_getc(volatile struct NS16550 *com_port) +{ + while ((com_port->lsr & LSR_DR) == 0) ; + return (com_port->rbr); +} + +int +serial_tstc(volatile struct NS16550 *com_port) +{ + return ((com_port->lsr & LSR_DR) != 0); +} diff --git a/arch/mips/zboot/common/string.c b/arch/mips/zboot/common/string.c new file mode 100644 index 0000000..c6cf31b --- /dev/null +++ b/arch/mips/zboot/common/string.c @@ -0,0 +1,497 @@ +/* + * linux/lib/string.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* + * stupid library routines.. The optimized versions should generally be found + * as inline code in + * + * These are buggy as well.. + * + * * Fri Jun 25 1999, Ingo Oeser + * - Added strsep() which will replace strtok() soon (because strsep() is + * reentrant and should be faster). Use only strsep() in new code, please. + */ + +#include +#include +#include + +/** + * strnicmp - Case insensitive, length-limited string comparison + * @s1: One string + * @s2: The other string + * @len: the maximum number of characters to compare + */ +int strnicmp(const char *s1, const char *s2, size_t len) +{ + /* Yes, Virginia, it had better be unsigned */ + unsigned char c1, c2; + + c1 = 0; c2 = 0; + if (len) { + do { + c1 = *s1; c2 = *s2; + s1++; s2++; + if (!c1) + break; + if (!c2) + break; + if (c1 == c2) + continue; + c1 = tolower(c1); + c2 = tolower(c2); + if (c1 != c2) + break; + } while (--len); + } + return (int)c1 - (int)c2; +} + +char * ___strtok; + +/** + * strcpy - Copy a %NUL terminated string + * @dest: Where to copy the string to + * @src: Where to copy the string from + */ + #ifndef __HAVE_ARCH_MEMCPY +char * strcpy(char * dest,const char *src) +{ + char *tmp = dest; + + while ((*dest++ = *src++) != '\0') + /* nothing */; + return tmp; +} +#endif + +/** + * strncpy - Copy a length-limited, %NUL-terminated string + * @dest: Where to copy the string to + * @src: Where to copy the string from + * @count: The maximum number of bytes to copy + * + * Note that unlike userspace strncpy, this does not %NUL-pad the buffer. + * However, the result is not %NUL-terminated if the source exceeds + * @count bytes. + */ + #ifndef __HAVE_ARCH_STRNCPY +char * strncpy(char * dest,const char *src,size_t count) +{ + char *tmp = dest; + + while (count-- && (*dest++ = *src++) != '\0') + /* nothing */; + + return tmp; +} +#endif + +/** + * strcat - Append one %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + */ +char * strcat(char * dest, const char * src) +{ + char *tmp = dest; + + while (*dest) + dest++; + while ((*dest++ = *src++) != '\0') + ; + + return tmp; +} + +/** + * strncat - Append a length-limited, %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + * @count: The maximum numbers of bytes to copy + * + * Note that in contrast to strncpy, strncat ensures the result is + * terminated. + */ +char * strncat(char *dest, const char *src, size_t count) +{ + char *tmp = dest; + + if (count) { + while (*dest) + dest++; + while ((*dest++ = *src++)) { + if (--count == 0) { + *dest = '\0'; + break; + } + } + } + + return tmp; +} + +/** + * strcmp - Compare two strings + * @cs: One string + * @ct: Another string + */ + #ifndef __HAVE_ARCH_STRCMP +int strcmp(const char * cs,const char * ct) +{ + register signed char __res; + + while (1) { + if ((__res = *cs - *ct++) != 0 || !*cs++) + break; + } + + return __res; +} +#endif + +/** + * strncmp - Compare two length-limited strings + * @cs: One string + * @ct: Another string + * @count: The maximum number of bytes to compare + */ + #ifndef __HAVE_ARCH_STRNCMP +int strncmp(const char * cs,const char * ct,size_t count) +{ + register signed char __res = 0; + + while (count) { + if ((__res = *cs - *ct++) != 0 || !*cs++) + break; + count--; + } + + return __res; +} +#endif + +/** + * strchr - Find the first occurrence of a character in a string + * @s: The string to be searched + * @c: The character to search for + */ +char * strchr(const char * s, int c) +{ + for(; *s != (char) c; ++s) + if (*s == '\0') + return NULL; + return (char *) s; +} + +/** + * strrchr - Find the last occurrence of a character in a string + * @s: The string to be searched + * @c: The character to search for + */ +size_t strlen(const char * s); + +char * strrchr(const char * s, int c) +{ + const char *p = s + strlen(s); + do { + if (*p == (char)c) + return (char *)p; + } while (--p >= s); + return NULL; +} + +/** + * strlen - Find the length of a string + * @s: The string to be sized + */ +size_t strlen(const char * s) +{ + const char *sc; + + for (sc = s; *sc != '\0'; ++sc) + /* nothing */; + return sc - s; +} + +/** + * strnlen - Find the length of a length-limited string + * @s: The string to be sized + * @count: The maximum number of bytes to search + */ +size_t strnlen(const char * s, size_t count) +{ + const char *sc; + + for (sc = s; count-- && *sc != '\0'; ++sc) + /* nothing */; + return sc - s; +} + +/** + * strspn - Calculate the length of the initial substring of @s which only + * contain letters in @accept + * @s: The string to be searched + * @accept: The string to search for + */ +size_t strspn(const char *s, const char *accept) +{ + const char *p; + const char *a; + size_t count = 0; + + for (p = s; *p != '\0'; ++p) { + for (a = accept; *a != '\0'; ++a) { + if (*p == *a) + break; + } + if (*a == '\0') + return count; + ++count; + } + + return count; +} + +/** + * strpbrk - Find the first occurrence of a set of characters + * @cs: The string to be searched + * @ct: The characters to search for + */ +char * strpbrk(const char * cs,const char * ct) +{ + const char *sc1,*sc2; + + for( sc1 = cs; *sc1 != '\0'; ++sc1) { + for( sc2 = ct; *sc2 != '\0'; ++sc2) { + if (*sc1 == *sc2) + return (char *) sc1; + } + } + return NULL; +} + +/** + * strtok - Split a string into tokens + * @s: The string to be searched + * @ct: The characters to search for + * + * WARNING: strtok is deprecated, use strsep instead. + */ +char * strtok(char * s,const char * ct) +{ + char *sbegin, *send; + + sbegin = s ? s : ___strtok; + if (!sbegin) { + return NULL; + } + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') { + ___strtok = NULL; + return( NULL ); + } + send = strpbrk( sbegin, ct); + if (send && *send != '\0') + *send++ = '\0'; + ___strtok = send; + return (sbegin); +} + +/** + * strsep - Split a string into tokens + * @s: The string to be searched + * @ct: The characters to search for + * + * strsep() updates @s to point after the token, ready for the next call. + * + * It returns empty tokens, too, behaving exactly like the libc function + * of that name. In fact, it was stolen from glibc2 and de-fancy-fied. + * Same semantics, slimmer shape. ;) + */ +char * strsep(char **s, const char *ct) +{ + char *sbegin = *s, *end; + + if (sbegin == NULL) + return NULL; + + end = strpbrk(sbegin, ct); + if (end) + *end++ = '\0'; + *s = end; + + return sbegin; +} + +/** + * memset - Fill a region of memory with the given value + * @s: Pointer to the start of the area. + * @c: The byte to fill the area with + * @count: The size of the area. + * + * Do not use memset() to access IO space, use memset_io() instead. + */ +void * memset(void * s,int c, size_t count) +{ + char *xs = (char *) s; + + while (count--) + *xs++ = c; + + return s; +} + +/** + * bcopy - Copy one area of memory to another + * @src: Where to copy from + * @dest: Where to copy to + * @count: The size of the area. + * + * Note that this is the same as memcpy(), with the arguments reversed. + * memcpy() is the standard, bcopy() is a legacy BSD function. + * + * You should not use this function to access IO space, use memcpy_toio() + * or memcpy_fromio() instead. + */ +char * bcopy(const char * src, char * dest, int count) +{ + char *tmp = dest; + + while (count--) + *tmp++ = *src++; + + return dest; +} + +/** + * memcpy - Copy one area of memory to another + * @dest: Where to copy to + * @src: Where to copy from + * @count: The size of the area. + * + * You should not use this function to access IO space, use memcpy_toio() + * or memcpy_fromio() instead. + */ +void * memcpy(void * dest,const void *src,size_t count) +{ + char *tmp = (char *) dest, *s = (char *) src; + + while (count--) + *tmp++ = *s++; + + return dest; +} + +/** + * memmove - Copy one area of memory to another + * @dest: Where to copy to + * @src: Where to copy from + * @count: The size of the area. + * + * Unlike memcpy(), memmove() copes with overlapping areas. + */ +void * memmove(void * dest,const void *src,size_t count) +{ + char *tmp, *s; + + if (dest <= src) { + tmp = (char *) dest; + s = (char *) src; + while (count--) + *tmp++ = *s++; + } + else { + tmp = (char *) dest + count; + s = (char *) src + count; + while (count--) + *--tmp = *--s; + } + + return dest; +} + +/** + * memcmp - Compare two areas of memory + * @cs: One area of memory + * @ct: Another area of memory + * @count: The size of the area. + */ +int memcmp(const void * cs,const void * ct,size_t count) +{ + const unsigned char *su1, *su2; + signed char res = 0; + + for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) + if ((res = *su1 - *su2) != 0) + break; + return res; +} + +/** + * memscan - Find a character in an area of memory. + * @addr: The memory area + * @c: The byte to search for + * @size: The size of the area. + * + * returns the address of the first occurrence of @c, or 1 byte past + * the area if @c is not found + */ +void * memscan(void * addr, int c, size_t size) +{ + unsigned char * p = (unsigned char *) addr; + unsigned char * e = p + size; + + while (p != e) { + if (*p == c) + return (void *) p; + p++; + } + + return (void *) p; +} + +/** + * strstr - Find the first substring in a %NUL terminated string + * @s1: The string to be searched + * @s2: The string to search for + */ +char * strstr(const char * s1,const char * s2) +{ + int l1, l2; + + l2 = strlen(s2); + if (!l2) + return (char *) s1; + l1 = strlen(s1); + while (l1 >= l2) { + l1--; + if (!memcmp(s1,s2,l2)) + return (char *) s1; + s1++; + } + return NULL; +} + +/** + * memchr - Find a character in an area of memory. + * @s: The memory area + * @c: The byte to search for + * @n: The size of the area. + * + * returns the address of the first occurrence of @c, or %NULL + * if @c is not found + */ +void *memchr(const void *s, int c, size_t n) +{ + const unsigned char *p = s; + while (n-- != 0) { + if ((unsigned char)c == *p++) { + return (void *)(p-1); + } + } + return NULL; +} diff --git a/arch/mips/zboot/images/Makefile b/arch/mips/zboot/images/Makefile new file mode 100644 index 0000000..d980c29 --- /dev/null +++ b/arch/mips/zboot/images/Makefile @@ -0,0 +1,12 @@ +STRIPFLAGS := --strip-all +ifdef CONFIG_32BIT +vmlinux.gz: $(TOPDIR)/vmlinux +else +vmlinux.gz: $(TOPDIR)/vmlinux.32 +endif + $(Q)echo " GZIP " vmlinux + $(Q)$(OBJCOPY) -O binary $(STRIPFLAGS) $< $(obj)/vmlinux + $(Q)gzip -cf $(obj)/vmlinux >$(obj)/$@ + +clean: + rm -f $(obj)/vmlinux.* $(obj)/zImage.* diff --git a/arch/mips/zboot/include/config.h b/arch/mips/zboot/include/config.h new file mode 100644 index 0000000..4bf63fd --- /dev/null +++ b/arch/mips/zboot/include/config.h @@ -0,0 +1,8 @@ +#ifndef __CONFIG_H__ +#define __CONFIG_H__ +#include +#ifdef CONFIG_64BIT +#undef CONFIG_64BIT +#define CONFIG_32BIT +#endif +#endif diff --git a/arch/mips/zboot/include/nonstdio.h b/arch/mips/zboot/include/nonstdio.h new file mode 100644 index 0000000..664b838 --- /dev/null +++ b/arch/mips/zboot/include/nonstdio.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * 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. + */ +typedef int FILE; +extern FILE *stdin, *stdout; +#define NULL ((void *)0) +#define EOF (-1) +#define fopen(n, m) NULL +#define fflush(f) 0 +#define fclose(f) 0 +extern char *fgets(); + +#define perror(s) printf("%s: no files!\n", (s)) diff --git a/arch/mips/zboot/include/ns16550.h b/arch/mips/zboot/include/ns16550.h new file mode 100644 index 0000000..eebce89 --- /dev/null +++ b/arch/mips/zboot/include/ns16550.h @@ -0,0 +1,43 @@ +/* + * NS16550 Serial Port + */ + + +/* Some machines have their uart registers 16 bytes apart. Most don't. + * TODO: Make this work like drivers/char/serial does - Tom */ +#if !defined(UART_REG_PAD) +#define UART_REG_PAD(x) +#endif + +struct NS16550 + { + unsigned char rbr; /* 0 */ + UART_REG_PAD(rbr) + unsigned char ier; /* 1 */ + UART_REG_PAD(ier) + unsigned char fcr; /* 2 */ + UART_REG_PAD(fcr) + unsigned char lcr; /* 3 */ + UART_REG_PAD(lcr) + unsigned char mcr; /* 4 */ + UART_REG_PAD(mcr) + unsigned char lsr; /* 5 */ + UART_REG_PAD(lsr) + unsigned char msr; /* 6 */ + UART_REG_PAD(msr) + unsigned char scr; /* 7 */ + }; + +#define thr rbr +#define iir fcr +#define dll rbr +#define dlm ier + +#define LSR_DR 0x01 /* Data ready */ +#define LSR_OE 0x02 /* Overrun */ +#define LSR_PE 0x04 /* Parity error */ +#define LSR_FE 0x08 /* Framing error */ +#define LSR_BI 0x10 /* Break */ +#define LSR_THRE 0x20 /* Xmit holding register empty */ +#define LSR_TEMT 0x40 /* Xmitter empty */ +#define LSR_ERR 0x80 /* Error */ diff --git a/arch/mips/zboot/include/pb1000_serial.h b/arch/mips/zboot/include/pb1000_serial.h new file mode 100644 index 0000000..eb907f8 --- /dev/null +++ b/arch/mips/zboot/include/pb1000_serial.h @@ -0,0 +1,20 @@ +/* + * arch/ppc/boot/include/sandpoint_serial.h + * + * Location of the COM ports on Motorola SPS Sandpoint machines + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software 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. + */ + +#define COM1 0xfe0003f8 +#define COM2 0xfe0002f8 +#define COM3 0x00000000 /* No COM3 */ +#define COM4 0x00000000 /* No COM4 */ diff --git a/arch/mips/zboot/include/zlib.h b/arch/mips/zboot/include/zlib.h new file mode 100644 index 0000000..8e1b48b --- /dev/null +++ b/arch/mips/zboot/include/zlib.h @@ -0,0 +1,432 @@ +/* $Id: zlib.h,v 1.1.1.1 2006/05/08 03:33:28 cpu Exp $ */ + +/* + * This file is derived from zlib.h and zconf.h from the zlib-0.95 + * distribution by Jean-loup Gailly and Mark Adler, with some additions + * by Paul Mackerras to aid in implementing Deflate compression and + * decompression for PPP packets. + */ + +/* + * ==FILEVERSION 960122== + * + * This marker is used by the Linux installation script to determine + * whether an up-to-date version of this file is already installed. + */ + +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 0.95, Aug 16th, 1995. + + Copyright (C) 1995 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + gzip@prep.ai.mit.edu madler@alumni.caltech.edu + */ + +#ifndef _ZLIB_H +#define _ZLIB_H + +/* #include "zconf.h" */ /* included directly here */ + +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ + +/* + The library does not install any signal handler. It is recommended to + add at least a handler for SIGSEGV when decompressing; the library checks + the consistency of the input data whenever possible but may go nuts + for some forms of corrupted input. + */ + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints + * at addresses which are not a multiple of their size. + * Under DOS, -DFAR=far or -DFAR=__far may be needed. + */ + +#ifndef STDC +# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) +# define STDC +# endif +#endif + +#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ +# include +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +#ifndef FAR +# define FAR +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + 1 << (windowBits+2) + 1 << (memLevel+9) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +typedef unsigned char Byte; /* 8 bits */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef Byte FAR Bytef; +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +/* end of original zconf.h */ + +#define ZLIB_VERSION "0.95P" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms may be added later and will have the same + stream interface. + + For compression the application must provide the output buffer and + may optionally provide the input buffer for optimization. For decompression, + the application must provide the input buffer and may optionally provide + the output buffer for optimization. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidp opaque; /* private data object passed to zalloc and zfree */ + + Byte data_type; /* best guess about the data type: ascii or binary */ + +} z_stream; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_FULL_FLUSH 2 +#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ +#define Z_FINISH 4 +#define Z_PACKET_FLUSH 5 +/* See deflate() below for the usage of these constants */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +/* error codes for the compression/decompression functions */ + +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Used to set the data_type field */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +extern char *zlib_version; +/* The application can compare zlib_version and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + */ + + /* basic functions */ + +extern int inflateInit OF((z_stream *strm)); +/* + Initializes the internal stream state for decompression. The fields + zalloc and zfree must be initialized before by the caller. If zalloc and + zfree are set to Z_NULL, inflateInit updates them to use default allocation + functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory. msg is set to null if there is no error message. + inflateInit does not perform any decompression: this will be done by + inflate(). +*/ + + +extern int inflate OF((z_stream *strm, int flush)); +/* + Performs one or both of the following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() always provides as much output as possible + (until there is no more input data or no more space in the output buffer). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). + + If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, + inflate flushes as much output as possible to the output buffer. The + flushing behavior of inflate is not specified for values of the flush + parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the + current implementation actually flushes as much output as possible + anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data + has been consumed, it is expecting to see the length field of a stored + block; if not, it returns Z_DATA_ERROR. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + inflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if the end of the + compressed data has been reached and all uncompressed output has been + produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if + the stream structure was inconsistent (for example if next_in or next_out + was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no + progress is possible or if there was not enough room in the output buffer + when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then + call inflateSync to look for a good compression block. */ + + +extern int inflateEnd OF((z_stream *strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* advanced functions */ + +extern int inflateInit2 OF((z_stream *strm, + int windowBits)); +/* + This is another version of inflateInit with more compression options. The + fields next_out, zalloc and zfree must be initialized before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library (the value 16 will be allowed soon). The + default value is 15 if inflateInit is used instead. If a compressed stream + with a larger window size is given as input, inflate() will return with + the error code Z_DATA_ERROR instead of trying to allocate a larger window. + + If next_out is not null, the library will use this buffer for the history + buffer; the buffer must either be large enough to hold the entire output + data, or have at least 1<msg=z_errmsg[1-err], err) +/* To be used only when the state is known to be valid */ + +#ifndef NULL +#define NULL ((void *) 0) +#endif + + /* common constants */ + +#define DEFLATED 8 + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + + /* functions */ + +#include +#define zmemcpy memcpy +#define zmemzero(dest, len) memset(dest, 0, len) + +/* Diagnostic functions */ +#ifdef DEBUG_ZLIB +# include +# ifndef verbose +# define verbose 0 +# endif +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); + +/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ +/* void zcfree OF((voidpf opaque, voidpf ptr)); */ + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr, size) \ + (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) +#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} + +/* deflate.h -- internal compression state + * Copyright (C) 1995 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/*+++++*/ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +local inflate_blocks_statef * inflate_blocks_new OF(( + z_stream *z, + check_func c, /* check function */ + uInt w)); /* window size */ + +local int inflate_blocks OF(( + inflate_blocks_statef *, + z_stream *, + int)); /* initial return code */ + +local void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_stream *, + uLongf *)); /* check value on output */ + +local int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_stream *, + uLongf *)); /* check value on output */ + +local int inflate_addhistory OF(( + inflate_blocks_statef *, + z_stream *)); + +local int inflate_packet_flush OF(( + inflate_blocks_statef *)); + +/*+++++*/ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt Nalloc; /* number of these allocated here */ + Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit machines) */ + union { + uInt Base; /* literal, length base, or distance base */ + inflate_huft *Next; /* pointer to next level of table */ + } more; +}; + +#ifdef DEBUG_ZLIB + local uInt inflate_hufts; +#endif + +local int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + z_stream *)); /* for zalloc, zfree functions */ + +local int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_stream *)); /* for zalloc, zfree functions */ + +local int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *)); /* distance tree result */ + +local int inflate_trees_free OF(( + inflate_huft *, /* tables to free */ + z_stream *)); /* for zfree function */ + + +/*+++++*/ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +local inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_stream *)); + +local int inflate_codes OF(( + inflate_blocks_statef *, + z_stream *, + int)); + +local void inflate_codes_free OF(( + inflate_codes_statef *, + z_stream *)); + + +/*+++++*/ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* inflate private state */ +struct internal_state { + + /* mode */ + enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ + mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +int inflateReset(z) +z_stream *z; +{ + uLong c; + + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, &c); + Trace((stderr, "inflate: reset\n")); + return Z_OK; +} + + +int inflateEnd(z) +z_stream *z; +{ + uLong c; + + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z, &c); + ZFREE(z, z->state, sizeof(struct internal_state)); + z->state = Z_NULL; + Trace((stderr, "inflate: end\n")); + return Z_OK; +} + + +int inflateInit2(z, w) +z_stream *z; +int w; +{ + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; +/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ +/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ + if ((z->state = (struct internal_state FAR *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Trace((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + +int inflateInit(z) +z_stream *z; +{ + return inflateInit2(z, DEF_WBITS); +} + + +#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int inflate(z, f) +z_stream *z; +int f; +{ + int r; + uInt b; + + if (z == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) + { + z->state->mode = BAD; + z->msg = "unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = "invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + if ((b = NEXTBYTE) & 0x20) + { + z->state->mode = BAD; + z->msg = "invalid reserved bit"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = "incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Trace((stderr, "inflate: zlib header ok\n")); + z->state->mode = BLOCKS; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) + r = inflate_packet_flush(z->state->blocks); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r != Z_STREAM_END) + return r; + r = Z_OK; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = "incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Trace((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } + + empty: + if (f != Z_PACKET_FLUSH) + return r; + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_DATA_ERROR; +} + +/* + * This subroutine adds the data at next_in/avail_in to the output history + * without performing any output. The output buffer must be "caught up"; + * i.e. no pending output (hence s->read equals s->write), and the state must + * be BLOCKS (i.e. we should be willing to see the start of a series of + * BLOCKS). On exit, the output will also be caught up, and the checksum + * will have been updated if need be. + */ + +int inflateIncomp(z) +z_stream *z; +{ + if (z->state->mode != BLOCKS) + return Z_DATA_ERROR; + return inflate_addhistory(z->state->blocks, z); +} + + +int inflateSync(z) +z_stream *z; +{ + uInt n; /* number of bytes to look at */ + Bytef *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != BAD) + { + z->state->mode = BAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + if (*p == (Byte)(m < 2 ? 0 : 0xff)) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = BLOCKS; + return Z_OK; +} + +#undef NEEDBYTE +#undef NEXTBYTE + +/*+++++*/ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONEB, /* finished last block, done */ + BADB} /* got a data error--stuck here */ + mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + int nblens; /* # elements allocated at blens */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_huft *tl, *td; /* trees to free */ + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* + * The IBM 150 firmware munges the data right after _etext[]. This + * protects it. -- Cort + */ +/* And'ing with mask[n] masks the lower n bits */ +local uInt inflate_mask[] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +/* copy as much as possible from the sliding window to the output area */ +local int inflate_flush OF(( + inflate_blocks_statef *, + z_stream *, + int)); + +/*+++++*/ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +local int inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_stream *)); + + +/*+++++*/ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* Table for deflate from PKZIP's appnote.txt. */ +local uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +local void inflate_blocks_reset(s, z, c) +inflate_blocks_statef *s; +z_stream *z; +uLongf *c; +{ + if (s->checkfn != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); + if (s->mode == CODES) + { + inflate_codes_free(s->sub.decode.codes, z); + inflate_trees_free(s->sub.decode.td, z); + inflate_trees_free(s->sub.decode.tl, z); + } + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(0L, Z_NULL, 0); + Trace((stderr, "inflate: blocks reset\n")); +} + + +local inflate_blocks_statef *inflate_blocks_new(z, c, w) +z_stream *z; +check_func c; +uInt w; +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s, sizeof(struct inflate_blocks_state)); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Trace((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, &s->check); + return s; +} + + +local int inflate_blocks(s, z, r) +inflate_blocks_statef *s; +z_stream *z; +int r; +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Trace((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Trace((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.tl = Z_NULL; /* don't try to free these */ + s->sub.decode.td = Z_NULL; + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Trace((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BADB; + z->msg = "invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if (((~b) >> 16) != (b & 0xffff)) + { + s->mode = BADB; + z->msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : TYPE; + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BADB; + z->msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if (t < 19) + t = 19; + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.trees.nblens = t; + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + s->mode = BADB; + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->word.what.Bits; + c = h->more.Base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + s->mode = BADB; + z->msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + inflate_trees_free(s->sub.trees.tb, z); + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + s->mode = BADB; + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + inflate_trees_free(td, z); + inflate_trees_free(tl, z); + r = Z_MEM_ERROR; + LEAVE + } + ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); + s->sub.decode.codes = c; + s->sub.decode.tl = tl; + s->sub.decode.td = td; + } + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + inflate_trees_free(s->sub.decode.td, z); + inflate_trees_free(s->sub.decode.tl, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONEB; + case DONEB: + r = Z_STREAM_END; + LEAVE + case BADB: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +local int inflate_blocks_free(s, z, c) +inflate_blocks_statef *s; +z_stream *z; +uLongf *c; +{ + inflate_blocks_reset(s, z, c); + ZFREE(z, s->window, s->end - s->window); + ZFREE(z, s, sizeof(struct inflate_blocks_state)); + Trace((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + +/* + * This subroutine adds the data at next_in/avail_in to the output history + * without performing any output. The output buffer must be "caught up"; + * i.e. no pending output (hence s->read equals s->write), and the state must + * be BLOCKS (i.e. we should be willing to see the start of a series of + * BLOCKS). On exit, the output will also be caught up, and the checksum + * will have been updated if need be. + */ +local int inflate_addhistory(s, z) +inflate_blocks_statef *s; +z_stream *z; +{ + uLong b; /* bit buffer */ /* NOT USED HERE */ + uInt k; /* bits in bit buffer */ /* NOT USED HERE */ + uInt t; /* temporary storage */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + if (s->read != s->write) + return Z_STREAM_ERROR; + if (s->mode != TYPE) + return Z_DATA_ERROR; + + /* we're ready to rock */ + LOAD + /* while there is input ready, copy to output buffer, moving + * pointers as needed. + */ + while (n) { + t = n; /* how many to do */ + /* is there room until end of buffer? */ + if (t > m) t = m; + /* update check information */ + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(s->check, q, t); + zmemcpy(q, p, t); + q += t; + p += t; + n -= t; + z->total_out += t; + s->read = q; /* drag read pointer forward */ +/* WRAP */ /* expand WRAP macro by hand to handle s->read */ + if (q == s->end) { + s->read = q = s->window; + m = WAVAIL; + } + } + UPDATE + return Z_OK; +} + + +/* + * At the end of a Deflate-compressed PPP packet, we expect to have seen + * a `stored' block type value but not the (zero) length bytes. + */ +local int inflate_packet_flush(s) + inflate_blocks_statef *s; +{ + if (s->mode != LENS) + return Z_DATA_ERROR; + s->mode = TYPE; + return Z_OK; +} + + +/*+++++*/ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + uIntf *, /* list of base values for non-simple codes */ + uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + z_stream *)); /* for zalloc function */ + +local voidpf falloc OF(( + voidpf, /* opaque pointer (not used) */ + uInt, /* number of items */ + uInt)); /* size of item */ + +local void ffree OF(( + voidpf q, /* opaque pointer (not used) */ + voidpf p, /* what to free (not used) */ + uInt n)); /* number of bytes (not used) */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* actually lengths - 2; also see note #13 above about 258 */ +local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ +local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local uInt cpdext[] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ +#define N_MAX 288 /* maximum number of codes in any set */ + +#ifdef DEBUG_ZLIB + uInt inflate_hufts; +#endif + +local int huft_build(b, n, s, d, e, t, m, zs) +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ +uInt n; /* number of codes (assumed <= N_MAX) */ +uInt s; /* number of simple-valued codes (0..s-1) */ +uIntf *d; /* list of base values for non-simple codes */ +uIntf *e; /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t; /* result: starting table */ +uIntf *m; /* maximum lookup bits, returns actual */ +z_stream *zs; /* for zalloc function */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), Z_DATA_ERROR if the input is invalid (all zero length codes or an + over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + uInt v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate and link in new table */ + if ((q = (inflate_huft *)ZALLOC + (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) + { + if (h) + inflate_trees_free(u[0], zs); + return Z_MEM_ERROR; /* not enough memory */ + } + q->word.Nalloc = z + 1; +#ifdef DEBUG_ZLIB + inflate_hufts += z + 1; +#endif + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->next)) = Z_NULL; + u[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + r.next = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h-1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +local int inflate_trees_bits(c, bb, tb, z) +uIntf *c; /* 19 code lengths */ +uIntf *bb; /* bits tree desired/actual depth */ +inflate_huft * FAR *tb; /* bits tree result */ +z_stream *z; /* for zfree function */ +{ + int r; + + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); + if (r == Z_DATA_ERROR) + z->msg = "oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR) + { + inflate_trees_free(*tb, z); + z->msg = "incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + return r; +} + + +local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) +uInt nl; /* number of literal/length codes */ +uInt nd; /* number of distance codes */ +uIntf *c; /* that many (total) code lengths */ +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +z_stream *z; /* for zfree function */ +{ + int r; + + /* build literal/length tree */ + if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) + { + if (r == Z_DATA_ERROR) + z->msg = "oversubscribed literal/length tree"; + else if (r == Z_BUF_ERROR) + { + inflate_trees_free(*tl, z); + z->msg = "incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + return r; + } + + /* build distance tree */ + if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) + { + if (r == Z_DATA_ERROR) + z->msg = "oversubscribed literal/length tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + inflate_trees_free(*td, z); + z->msg = "incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + inflate_trees_free(*tl, z); + return r; +#endif + } + + /* done */ + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +local int fixed_lock = 0; +local int fixed_built = 0; +#define FIXEDH 530 /* number of hufts used by fixed tables */ +local uInt fixed_left = FIXEDH; +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; + + +local voidpf falloc(q, n, s) +voidpf q; /* opaque pointer (not used) */ +uInt n; /* number of items */ +uInt s; /* size of item */ +{ + Assert(s == sizeof(inflate_huft) && n <= fixed_left, + "inflate_trees falloc overflow"); + if (q) s++; /* to make some compilers happy */ + fixed_left -= n; + return (voidpf)(fixed_mem + fixed_left); +} + + +local void ffree(q, p, n) +voidpf q; +voidpf p; +uInt n; +{ + Assert(0, "inflate_trees ffree called!"); + if (q) q = p; /* to make some compilers happy */ +} + + +local int inflate_trees_fixed(bl, bd, tl, td) +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +{ + /* build fixed tables if not built already--lock out other instances */ + while (++fixed_lock > 1) + fixed_lock--; + if (!fixed_built) + { + int k; /* temporary variable */ + unsigned c[288]; /* length list for huft_build */ + z_stream z; /* for falloc function */ + + /* set up fake z_stream for memory routines */ + z.zalloc = falloc; + z.zfree = ffree; + z.opaque = Z_NULL; + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 7; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); + + /* done */ + fixed_built = 1; + } + fixed_lock--; + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} + + +local int inflate_trees_free(t, z) +inflate_huft *t; /* table to free */ +z_stream *z; /* for zfree function */ +/* Free the malloc'ed tables built by huft_build(), which makes a linked + list of the tables it made, with the links in a dummy first entry of + each table. */ +{ + register inflate_huft *p, *q; + + /* Go through linked list, freeing from the malloced (t[-1]) address. */ + p = t; + while (p != Z_NULL) + { + q = (--p)->next; + ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); + p = q; + } + return Z_OK; +} + +/*+++++*/ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ + mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl, *td; +z_stream *z; +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +local int inflate_codes(s, z, r) +inflate_blocks_statef *s; +z_stream *z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t->next; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t->next; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = "invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ +#ifndef __TURBOC__ /* Turbo C bug for following expression */ + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; +#else + f = q - c->sub.copy.dist; + if ((uInt)(q - s->window) < c->sub.copy.dist) + f = s->end - (c->sub.copy.dist - (q - s->window)); +#endif + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +local void inflate_codes_free(c, z) +inflate_codes_statef *c; +z_stream *z; +{ + ZFREE(z, c, sizeof(struct inflate_codes_state)); + Tracev((stderr, "inflate: codes free\n")); +} + +/*+++++*/ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* copy as much as possible from the sliding window to the output area */ +local int inflate_flush(s, z, r) +inflate_blocks_statef *s; +z_stream *z; +int r; +{ + uInt n; + Bytef *p, *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} + + +/*+++++*/ +/* inffast.c -- process literals and length/distance pairs fast + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +local int inflate_fast(bl, bd, tl, td, s, z) +uInt bl, bd; +inflate_huft *tl, *td; +inflate_blocks_statef *s; +z_stream *z; +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Bytef *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* offset before dest */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + } + else /* else offset after destination */ + { + e = d - (q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; + else + { + z->msg = "invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = "invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +} + + +/*+++++*/ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ + +char *zlib_version = ZLIB_VERSION; + +char *z_errmsg[] = { +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +""}; + + +/*+++++*/ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf) {s1 += *buf++; s2 += s1;} +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); +#define DO16(buf) DO8(buf); DO8(buf); + +/* ========================================================================= */ +uLong adler32(adler, buf, len) + uLong adler; + Bytef *buf; + uInt len; +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + k -= 16; + } + if (k != 0) do { + DO1(buf); + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff --git a/arch/mips/zboot/lm2f/Makefile b/arch/mips/zboot/lm2f/Makefile new file mode 100644 index 0000000..e92e567 --- /dev/null +++ b/arch/mips/zboot/lm2f/Makefile @@ -0,0 +1,130 @@ +# arch/mips/zboot/lm2f/Makefile +# +# Makefile for Alchemy Semiconductor Pb1[015]00 boards. +# All of the boot loader code was derived from the ppc +# boot code. +# +# Copyright 2001,2002 MontaVista Software Inc. +# +# Author: Mark A. Greer +# mgreer@mvista.com +# Ported and modified for mips support by +# Pete Popov +# +# 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. + +######################################################################### +# START BOARD SPECIFIC VARIABLES +BNAME=lm2f + +# These two variables control where the zImage is stored +# in flash and loaded in memory. It only controls how the srec +# file is generated, the code is the same. +ZBOOT_CFLAGS := -fno-pic -pipe -msoft-float -ffreestanding -march=r4600 -Wa,--trap -G 0 -mno-abicalls +ZBOOT_CFLAGS += -D__KERNEL__ +ZBOOT_CFLAGS += -I$(TOPDIR)/include -I$(TOPDIR)/includ/asm/ -I$(TOPDIR)/include/asm/mach-lemote/ -I$(TOPDIR)/include/asm/mach-generic -I$(TOPDIR)/arch/mips/zboot/include +ZBOOT_CFLAGS += -fno-builtin -isystem +ZBOOT_AFLAGS := -fno-pic -pipe -msoft-float -ffreestanding -march=r4600 -Wa,--trap + +RAM_RUN_ADDR = 0x81000000 +FLASH_LOAD_ADDR = 0xBFD00000 + +# These two variables specify the free ram region +# that can be used for temporary malloc area +AVAIL_RAM_START=0x83000000 +AVAIL_RAM_END=0x83f00000 + +# This one must match the LOADADDR in arch/mips/Makefile! +LOADADDR=0x80200000 +# END BOARD SPECIFIC VARIABLES +######################################################################### + +targets := bzImage + +libs-y := $(obj)/../lib +obj-y += $(obj)/../images +OBJECTS := $(obj)/head.o $(obj)/cache.o $(obj)/../common/misc-common.o \ + $(obj)/../common/misc-simple.o \ + $(obj)/ns16550.o $(obj)/../common/ctype.o $(obj)/../lib/zlib.o \ + $(obj)/../common/string.o + +ENTRY := $(obj)/../utils/entry +OFFSET := ../utils/offset +SIZE := ../utils/size + +LD_ARGS := -T $(obj)/../ld.script -Ttext $(RAM_RUN_ADDR) -Bstatic +OBJCOPY_ARGS = -O elf32-tradlittlemips + +all: bzImage + +clean: + rm -rf *.o vmlinux* zvmlinux.* ../images/*.srec + +$(obj)/head.o: $(obj)/head.S $(TOPDIR)/vmlinux + $(Q)$(CC) $(ZBOOT_CFLAGS) -I$(TOPDIR)/include -D__ASSEMBLY__ \ + -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) -c -o $@ $< + +$(obj)/cache.o: $(obj)/cache.c $(TOPDIR)/vmlinux + $(Q)$(CC) $(ZBOOT_CFLAGS) -I$(TOPDIR)/include -c -o $@ $< + +$(obj)/../common/misc-common.o: $(obj)/../common/misc-common.c + $(Q)$(CC) $(ZBOOT_CFLAGS) -I$(TOPDIR)/include -c -o $@ $< + +$(obj)/../common/ctype.o: $(obj)/../common/ctype.c + $(Q)$(CC) $(ZBOOT_CFLAGS) -I$(TOPDIR)/include -c -o $@ $< + +$(obj)/../common/string.o: $(obj)/../common/string.c + $(Q)$(CC) $(ZBOOT_CFLAGS) -I$(TOPDIR)/include -c -o $@ $< + +$(obj)/../common/dummy.o: $(obj)/../common/dummy.c + $(Q)$(CC) $(ZBOOT_CFLAGS) -I$(TOPDIR)/include -c -o $@ $< + +$(obj)/../lib/zlib.o: $(obj)/../lib/zlib.c + $(Q)$(CC) $(ZBOOT_CFLAGS) -I$(TOPDIR)/include -c -o $@ $< + +$(obj)/../common/misc-simple.o: $(obj)/../common/misc-simple.c + $(Q)$(CC) $(ZBOOT_CFLAGS) \ + -I$(TOPDIR)/include/asm/mach-generic -I$(TOPDIR)/include/asm/mach-mips \ + -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ + -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ + -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ + -DLOADADDR=$(LOADADDR) \ + -DZIMAGE_SIZE=0 -c -o $@ $< +ifeq (1,0) +$(obj)/../common/misc-simple.o: $(obj)/../common/misc-simple.c + $(CC) $(ZBOOT_CFLAGS) -I$(TOPDIR)/include/asm/mach-generic -I$(TOPDIR)/include/asm/mach-mips -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ + -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ + -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ + -DLOADADDR=$(LOADADDR) \ + -DZIMAGE_SIZE=0 -c -o $@ $< +endif +$(obj)/ns16550.o: $(obj)/ns16550.c + $(Q)$(CC) $(ZBOOT_CFLAGS) -I$(TOPDIR)/include -c -o $@ $< + +$(obj)/../lib/lib.a: + $(MAKE) $(build)=$(dir $@) + +$(obj)/../images/vmlinux.gz: $(TOPDIR)/vmlinux + $(Q)$(MAKE) $(build)=$(dir $@) vmlinux.gz +zvmlinux: $(OBJECTS) $(LIBS) $(obj)/../ld.script $(obj)/../images/vmlinux.gz $(obj)/../common/dummy.o + $(Q)$(OBJCOPY) \ + --add-section=.image=$(obj)/../images/vmlinux.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data \ + $(obj)/../common/dummy.o image.o + $(Q)$(LD) $(LD_ARGS) -o $@ $(OBJECTS) image.o + $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \ + -R .initrd -R .sysmap + +# Here we manipulate the image in order to get it the necessary +# srecord file we need. +$(obj)/bzImage: zvmlinux + $(Q)mv zvmlinux $(obj)/../images/bzImage.$(BNAME) + $(Q)echo " GEN " bzImage.$(BNAME) + $(Q)$(OBJCOPY) -O srec $(obj)/../images/bzImage.$(BNAME) $(obj)/../images/$(BNAME).srec + +zImage.flash: zImage + $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \ + ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec diff --git a/arch/mips/zboot/lm2f/cache.c b/arch/mips/zboot/lm2f/cache.c new file mode 100644 index 0000000..96d833f --- /dev/null +++ b/arch/mips/zboot/lm2f/cache.c @@ -0,0 +1,41 @@ +#define cache32_unroll32(base,op) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3 \n" \ + " cache %1, 0x000(%0); cache %1, 0x020(%0) \n" \ + " cache %1, 0x040(%0); cache %1, 0x060(%0) \n" \ + " cache %1, 0x080(%0); cache %1, 0x0a0(%0) \n" \ + " cache %1, 0x0c0(%0); cache %1, 0x0e0(%0) \n" \ + " cache %1, 0x100(%0); cache %1, 0x120(%0) \n" \ + " cache %1, 0x140(%0); cache %1, 0x160(%0) \n" \ + " cache %1, 0x180(%0); cache %1, 0x1a0(%0) \n" \ + " cache %1, 0x1c0(%0); cache %1, 0x1e0(%0) \n" \ + " cache %1, 0x200(%0); cache %1, 0x220(%0) \n" \ + " cache %1, 0x240(%0); cache %1, 0x260(%0) \n" \ + " cache %1, 0x280(%0); cache %1, 0x2a0(%0) \n" \ + " cache %1, 0x2c0(%0); cache %1, 0x2e0(%0) \n" \ + " cache %1, 0x300(%0); cache %1, 0x320(%0) \n" \ + " cache %1, 0x340(%0); cache %1, 0x360(%0) \n" \ + " cache %1, 0x380(%0); cache %1, 0x3a0(%0) \n" \ + " cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) \n" \ + " .set pop \n" \ + : \ + : "r" (base), \ + "i" (op)); + +void flush_cache_all(void) +{ + unsigned long start = 0x80000000; + unsigned long end = start + 512*1024/4; + unsigned long lsize = 32; + unsigned long addr; + + int i; + + for (i=0; i<4; i++) { + for (addr=start; addr < end; addr+= lsize*32) { + cache32_unroll32(addr|i, 0x03); /* Index Writeback scache */ + } + } +} diff --git a/arch/mips/zboot/lm2f/head.S b/arch/mips/zboot/lm2f/head.S new file mode 100644 index 0000000..592f4be --- /dev/null +++ b/arch/mips/zboot/lm2f/head.S @@ -0,0 +1,130 @@ +/* + * arch/mips/kernel/head.S + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 1995 Waldorf Electronics + * Written by Ralf Baechle and Andreas Busse + * Copyright (C) 1995 - 1999 Ralf Baechle + * Copyright (C) 1996 Paul M. Antoine + * Modified for DECStation and hence R3000 support by Paul M. Antoine + * Further modifications by David S. Miller and Harald Koerfgen + * Copyright (C) 1999 Silicon Graphics, Inc. + * + * Head.S contains the MIPS exception handler and startup code. + * + ************************************************************************** + * 9 Nov, 2000. + * Added Cache Error exception handler and SBDDP EJTAG debug exception. + * + * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + ************************************************************************** + */ +#include +#include + +#include +#include +#include +#include +#include +#include + +#define IndexInvalidate_I 0x00 +#define IndexWriteBack_D 0x01 + + .set noreorder + .cprestore + LEAF(start) +start: + bal locate + nop +locate: + subu s8, ra, 8 /* Where we were loaded */ + la sp, (.stack + 8192) + + move s0, a0 /* Save boot rom start args */ + move s1, a1 + move s2, a2 + move s3, a3 + + la a0, start /* Where we were linked to run */ + + move a1, s8 + la a2, _edata + subu t1, a2, a0 + srl t1, t1, 2 + + /* copy text section */ + li t0, 0 +1: lw v0, 0(a1) + nop + sw v0, 0(a0) + xor t0, t0, v0 + addu a0, 4 + bne a2, a0, 1b + addu a1, 4 + + /* Clear BSS */ + la a0, _edata + la a2, _end +2: sw zero, 0(a0) + bne a2, a0, 2b + addu a0, 4 + + move a0, s8 /* load address */ + move a1, t1 /* length in words */ + move a2, t0 /* checksum */ + move a3, sp + + la ra, 1f + la k0, decompress_kernel + jr k0 + nop +1: + + move a0, s0 + move a1, s1 + move a2, s2 + move a3, s3 + li k0, KERNEL_ENTRY + jr k0 + nop +3: + b 3b + END(start) + + LEAF(udelay) +udelay: + END(udelay) + +#if 0 + + LEAF(FlushCache) + li k0, 0x80000000 # start address + li k1, 0x80004000 # end address (16KB I-Cache) + subu k1, 128 + +1: + .set mips3 + cache IndexWriteBack_D, 0(k0) + cache IndexWriteBack_D, 32(k0) + cache IndexWriteBack_D, 64(k0) + cache IndexWriteBack_D, 96(k0) + cache IndexInvalidate_I, 0(k0) + cache IndexInvalidate_I, 32(k0) + cache IndexInvalidate_I, 64(k0) + cache IndexInvalidate_I, 96(k0) + .set mips0 + + bne k0, k1, 1b + addu k0, k0, 128 + jr ra + nop + END(FlushCache) +#endif + + .comm .stack,4096*2,4 diff --git a/arch/mips/zboot/lm2f/ns16550.c b/arch/mips/zboot/lm2f/ns16550.c new file mode 100644 index 0000000..2a6c877 --- /dev/null +++ b/arch/mips/zboot/lm2f/ns16550.c @@ -0,0 +1,73 @@ +/* + * NS16550 support + */ + +#include +#include +#include "ns16550.h" + +typedef struct NS16550 *NS16550_t; + +#ifdef CONFIG_LEMOTE_FULONG2F +#ifdef CONFIG_LEMOTE_NAS +#define COM1 0xbff003f8 +#else +#define COM1 0xbfd002f8 +#endif +#endif + +#ifdef CONFIG_LEMOTE_2FNOTEBOOK +#define COM1 0xbff003f8 +#undef BASE_BAUD +#define BASE_BAUD (3686400 / 16) +#endif + +const NS16550_t COM_PORTS[] = { + (NS16550_t) COM1 +}; + +volatile struct NS16550 * +serial_init(int chan) +{ + volatile struct NS16550 *com_port; + com_port = (struct NS16550 *) COM_PORTS[chan]; + /* See if port is present */ + com_port->lcr = 0x00; + com_port->ier = 0xFF; +#if 0 + if (com_port->ier != 0x0F) return ((struct NS16550 *)0); +#endif + com_port->ier = 0x00; + com_port->lcr = 0x80; /* Access baud rate */ + +#undef SERIAL_CONSOLE_BAUD +#define SERIAL_CONSOLE_BAUD 115200 + + com_port->dll = (BASE_BAUD / SERIAL_CONSOLE_BAUD) & 0xff; + com_port->dlm = ((BASE_BAUD / SERIAL_CONSOLE_BAUD) >> 8 ) & 0xff; + + com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */ + com_port->mcr = 0x03; /* RTS/DTR */ + com_port->fcr = 0x07; /* Clear & enable FIFOs */ + return (com_port); +} + +void +serial_putc(volatile struct NS16550 *com_port, unsigned char c) +{ + while ((com_port->lsr & LSR_THRE) == 0) ; + com_port->thr = c; +} + +unsigned char +serial_getc(volatile struct NS16550 *com_port) +{ + while ((com_port->lsr & LSR_DR) == 0) ; + return (com_port->rbr); +} + +int +serial_tstc(volatile struct NS16550 *com_port) +{ + return ((com_port->lsr & LSR_DR) != 0); +} diff --git a/arch/mips/zboot/utils/entry b/arch/mips/zboot/utils/entry new file mode 100644 index 0000000..376e822 --- /dev/null +++ b/arch/mips/zboot/utils/entry @@ -0,0 +1,12 @@ +#!/bin/sh + +# grab the kernel_entry address from the vmlinux elf image +entry=`$1 $2 | grep kernel_entry` + +fs=`echo $entry | grep ffffffff` # check toolchain output + +if [ -n "$fs" ]; then + echo "0x"`$1 $2 | grep kernel_entry | cut -c9- | awk '{print $1}'` +else + echo "0x"`$1 $2 | grep kernel_entry | cut -c1- | awk '{print $1}'` +fi diff --git a/arch/mips/zboot/utils/offset b/arch/mips/zboot/utils/offset new file mode 100644 index 0000000..25e7505 --- /dev/null +++ b/arch/mips/zboot/utils/offset @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "0x"`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'` diff --git a/arch/mips/zboot/utils/size b/arch/mips/zboot/utils/size new file mode 100644 index 0000000..6b13558 --- /dev/null +++ b/arch/mips/zboot/utils/size @@ -0,0 +1,4 @@ +#!/bin/sh + +OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'` +echo "0x"$OFFSET diff --git a/drivers/Makefile b/drivers/Makefile index 2735bde..cd93d84 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -9,6 +9,9 @@ obj-y += gpio/ obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ +# char/ comes before serial/ etc so that the VT console is the boot-time +# default. +obj-y += char/ obj-y += video/ obj-$(CONFIG_ACPI) += acpi/ # PnP must come after ACPI since it will eventually need to check if acpi @@ -18,10 +21,6 @@ obj-$(CONFIG_ARM_AMBA) += amba/ obj-$(CONFIG_XEN) += xen/ -# char/ comes before serial/ etc so that the VT console is the boot-time -# default. -obj-y += char/ - # gpu/ comes after char for AGP vs DRM startup obj-y += gpu/ diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 672b08e..0913295 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -35,6 +35,8 @@ # include #endif +static unsigned int uca = 1; +static unsigned long fb_start = 0xffffffffUL, fb_end = 0xffffffffUL; /* * Architectures vary in how they handle caching for addresses * outside of main memory. @@ -354,6 +356,13 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) size, vma->vm_page_prot); + if (uca) { + unsigned offset = vma->vm_pgoff << PAGE_SHIFT; + if (offset >= fb_start && (offset + size) <= fb_end){ + vma->vm_page_prot = __pgprot((pgprot_val(vma->vm_page_prot)&~_CACHE_MASK)|_CACHE_UNCACHED_ACCELERATED); + } + } + vma->vm_ops = &mmap_mem_ops; /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ @@ -1000,3 +1009,47 @@ static int __init chr_dev_init(void) } fs_initcall(chr_dev_init); + +/* setup for godson uncache acceleration */ + +#include +#ifndef pci_for_each_dev +#define pci_for_each_dev for_each_pci_dev +#endif + +static int __init find_vga_mem_init(void) +{ + struct pci_dev *dev = 0; + struct resource *r; + int idx; + printk("begin to find the vga mem range\n"); + if(!uca)return 0; + pci_for_each_dev(dev) { + if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA){ + for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + continue; + } + if (r->flags & IORESOURCE_IO) + continue; + if (r->flags & IORESOURCE_MEM){ + fb_start = r->start; +#ifdef CONFIG_LEMOTE_2FNOTEBOOK + fb_end = fb_start + 0x400000; /*sm712 have 4M memory*/ +#else + fb_end = r->end; +#endif + printk("find the frame buffer:start=%lx,end=%lx\n", fb_start, fb_end); + return 0; + } + } + + } + } + printk("<0>can not find vga device\n"); + return 0; +} + +late_initcall(find_vga_mem_init); + diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index f53d4d0..b2460df 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -258,6 +258,9 @@ static irqreturn_t rtc_interrupt(int irq, void *dev_id) rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); } +#ifdef CONFIG_CS5536_RTC_BUG + (void)CMOS_READ(RTC_VALID); +#endif if (rtc_status & RTC_TIMER_ON) mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100); @@ -1096,7 +1099,7 @@ no_irq: if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) BCD_TO_BIN(year); /* This should never happen... */ - +#if 0 if (year < 20) { epoch = 2000; guess = "SRM (post-2000)"; @@ -1116,6 +1119,9 @@ no_irq: guess = "Standard PC (1900)"; #endif } +#endif + epoch = 1900; + guess = "Standard PC (1900)"; if (guess) printk(KERN_INFO "rtc: %s epoch (%lu) detected\n", guess, epoch); @@ -1204,6 +1210,9 @@ static void rtc_dropped_irq(unsigned long data) spin_unlock_irq(&rtc_lock); +#ifdef CONFIG_CS5536_RTC_BUG + (void)CMOS_READ(RTC_CONTROL); +#endif if (printk_ratelimit()) { printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n", freq); diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index a896a28..2add633 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -345,11 +345,11 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) if (pm->pm_step == ide_pm_state_completed) ide_complete_pm_request(drive, rq); return; - } + } else + rq->errors = err; spin_lock_irqsave(&ide_lock, flags); HWGROUP(drive)->rq = NULL; - rq->errors = err; if (unlikely(__blk_end_request(rq, (rq->errors ? -EIO : 0), blk_rq_bytes(rq)))) BUG(); diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 1e66a96..0fb7e6e 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -23,6 +23,13 @@ #define DRV_NAME "amd74xx" +const char *amd74xx_quirk_drives[] = { + "FUJITSU MHZ2160BH G2", + "WDC WD1600BEVT-22ZCT0", + "ST9160310AS", + NULL +}; + enum { AMD_IDE_CONFIG = 0x41, AMD_CABLE_DETECT = 0x42, @@ -112,6 +119,21 @@ static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio) amd_set_drive(drive, XFER_PIO_0 + pio); } +static void amd_quirkproc(ide_drive_t *drive) +{ + const char **list, *m = (char *)&drive->id->model; +#ifdef CONFIG_LEMOTE_2FNOTEBOOK +/* for(list = amd74xx_quirk_drives; *list != NULL; list++) + if(strstr(m, *list) != NULL){ +*/ + drive->quirk_list = 2; + return; +/* } +*/ +#endif + drive->quirk_list = 0; +} + static void __devinit amd7409_cable_detect(struct pci_dev *dev) { /* no host side cable detection */ @@ -194,6 +216,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) static const struct ide_port_ops amd_port_ops = { .set_pio_mode = amd_set_pio_mode, .set_dma_mode = amd_set_drive, + .quirkproc = amd_quirkproc, .cable_detect = amd_cable_detect, }; diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index d4d2025..dd73db8 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o -psmouse-objs := psmouse-base.o synaptics.o +psmouse-objs := psmouse-base.o synaptics.o sentelic.o psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index f5a6be1..32b26f8 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -28,6 +28,7 @@ #include "lifebook.h" #include "trackpoint.h" #include "touchkit_ps2.h" +#include "sentelic.h" #define DRIVER_DESC "PS/2 mouse driver" @@ -630,6 +631,20 @@ static int psmouse_extensions(struct psmouse *psmouse, } } +/* + * Try Finger Sensing Pad + */ + if (max_proto > PSMOUSE_IMEX) { + if (fsp_detect(psmouse, set_properties) == 0) { + if (!set_properties || fsp_init(psmouse) == 0) + return PSMOUSE_FSP; +/* + * Init failed, try basic relative protocols + */ + max_proto = PSMOUSE_IMEX; + } + } + if (max_proto > PSMOUSE_IMEX) { if (genius_detect(psmouse, set_properties) == 0) @@ -713,6 +728,13 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = 1, .detect = intellimouse_detect, }, + { + .type = PSMOUSE_FSP, + .name = "FSPPS/2", + .alias = "fsp", + .detect = fsp_detect, + .init = fsp_init, + }, { .type = PSMOUSE_IMEX, .name = "ImExPS/2", diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 1317bdd..91ec7a5 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h @@ -89,6 +89,7 @@ enum psmouse_type { PSMOUSE_TRACKPOINT, PSMOUSE_TOUCHKIT_PS2, PSMOUSE_CORTRON, + PSMOUSE_FSP, PSMOUSE_AUTO /* This one should always be last */ }; diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c new file mode 100644 index 0000000..4101483 --- /dev/null +++ b/drivers/input/mouse/sentelic.c @@ -0,0 +1,1453 @@ +/*- + * Finger Sensing Pad PS/2 mouse driver. + * + * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. + * Copyright (C) 2005-2008 Tai-hwa Liang, Sentelic Corporation. + * + * 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. + * + * $Id: sentelic.c 28732 2008-10-17 07:03:29Z avatar $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "psmouse.h" +#include "sentelic.h" + +/** + * The timeout for FSP PS/2 command only(in millisecond). + */ +#define FSP_CMD_TIMEOUT (30) + +/** Driver version. */ +static unsigned int fsp_drv_ver[] = {1, 0, 0}; + +#ifdef FSP_DEBUG +static unsigned int ps2_packet_cnt = 0; +static unsigned int ps2_last_second = 0; +#endif + +/* + * A direct copy of ps2_command(), with reduced timeout value as the hardware + * will return non-standard response which results in timeout in almost all + * commanding sequences. + */ +static int +fsp_ps2_command(struct psmouse *psmouse, unsigned char *param, int command) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + int timeout; + int send = (command >> 12) & 0xf; + int receive = (command >> 8) & 0xf; + int rc = -1; + int i; + + if (receive > sizeof(ps2dev->cmdbuf)) { + WARN_ON(1); + return (-1); + } + + if (send && !param) { + WARN_ON(1); + return (-1); + } + + mutex_lock(&ps2dev->cmd_mutex); + + serio_pause_rx(ps2dev->serio); + ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; + ps2dev->cmdcnt = receive; + if (receive && param) + for (i = 0; i < receive; i++) + ps2dev->cmdbuf[(receive - 1) - i] = param[i]; + serio_continue_rx(ps2dev->serio); + + if (ps2_sendbyte(ps2dev, command & 0xff, + command == PS2_CMD_RESET_BAT ? 1000 : FSP_CMD_TIMEOUT)) + goto out; + + for (i = 0; i < send; i++) { + if (ps2_sendbyte(ps2dev, param[i], FSP_CMD_TIMEOUT)) + goto out; + } + + /* + * The reset command takes a long time to execute. + */ + timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500); + + timeout = wait_event_timeout(ps2dev->wait, + !(ps2dev->flags & PS2_FLAG_CMD1), timeout); + + if (ps2dev->cmdcnt && timeout > 0) { + wait_event_timeout(ps2dev->wait, + !(ps2dev->flags & PS2_FLAG_CMD), timeout); + } + + if (param) { + for (i = 0; i < receive; i++) + param[i] = ps2dev->cmdbuf[(receive - 1) - i]; + } + + if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) + goto out; + + rc = 0; +out: + serio_pause_rx(ps2dev->serio); + ps2dev->flags = 0; + serio_continue_rx(ps2dev->serio); + + mutex_unlock(&ps2dev->cmd_mutex); + return (rc); +} + +/* + * Make sure that the value being sent to FSP will not conflict with + * possible sample rate values. + */ +static unsigned char +fsp_test_swap_cmd(unsigned char reg_val) +{ + switch (reg_val) { + case 10: case 20: case 40: case 60: case 80: case 100: case 200: + /* + * The requested value being sent to FSP matched to possible + * sample rates, swap the given value such that the hardware + * wouldn't get confused. + */ + return ((reg_val >> 4) | (reg_val << 4)); + default: + return (reg_val); /* swap isn't necessary */ + } +} + +/* + * Make sure that the value being sent to FSP will not conflict with certain + * commands. + */ +static unsigned char +fsp_test_invert_cmd(unsigned char reg_val) +{ + switch (reg_val) { + case 0xe9: case 0xee: case 0xf2: case 0xff: + /* + * The requested value being sent to FSP matched to certain + * commands, inverse the given value such that the hardware + * wouldn't get confused. + */ + return ~(reg_val); + default: + return (reg_val); /* inversion isn't necessary */ + } +} + +static int +fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val) +{ + unsigned char param[3]; + unsigned char addr; +#ifdef FSP_DEBUG + printk(KERN_INFO "fsp_reg_read: READ REG\n"); +#endif + if (fsp_ps2_command(psmouse, NULL, 0x00f3) < 0) + return (-1); + + /* should return 0xfe(request for resending) */ + fsp_ps2_command(psmouse, NULL, 0x0066); + /* should return 0xfc(failed) */ + fsp_ps2_command(psmouse, NULL, 0x0088); + + if (fsp_ps2_command(psmouse, NULL, 0x00f3) < 0) + return (-1); + + if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) { + fsp_ps2_command(psmouse, NULL, 0x0068); + } else { + if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) { + /* swapping is required */ + fsp_ps2_command(psmouse, NULL, 0x00cc); + /* expect 0xfe */ + } else { + /* swapping isn't necessary */ + fsp_ps2_command(psmouse, NULL, 0x0066); + /* expect 0xfe */ + } + } + /* should return 0xfc(failed) */ + fsp_ps2_command(psmouse, NULL, addr); + + if (fsp_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO) < 0) + return (-1); + + *reg_val = param[2]; + + return (0); +} + +static int +fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val) +{ + unsigned char v; +#ifdef FSP_DEBUG + printk(KERN_INFO "fsp_reg_write: WRITE REG\n"); +#endif + if (fsp_ps2_command(psmouse, NULL, 0x00f3) < 0) + return (-1); + + if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) { + /* inversion is required */ + fsp_ps2_command(psmouse, NULL, 0x0074); + } else { + if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) { + /* swapping is required */ + fsp_ps2_command(psmouse, NULL, 0x0077); + } else { + /* swapping isn't necessary */ + fsp_ps2_command(psmouse, NULL, 0x0055); + } + } + /* write the register address in correct order */ + fsp_ps2_command(psmouse, NULL, v); + + if (fsp_ps2_command(psmouse, NULL, 0x00f3) < 0) + return (-1); + + if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { + /* inversion is required */ + fsp_ps2_command(psmouse, NULL, 0x0047); + } else { + if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) { + /* swapping is required */ + fsp_ps2_command(psmouse, NULL, 0x0044); + } else { + /* swapping isn't necessary */ + fsp_ps2_command(psmouse, NULL, 0x0033); + } + } + /* write the register value in correct order */ + fsp_ps2_command(psmouse, NULL, v); + + return (0); +} + +/* enable register clock gating for writing certain registers */ +static int +fsp_reg_write_enable(struct psmouse *psmouse, int en) +{ + int v, nv; + + if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1) + return (-1); + + if (en) { + nv = v | FSP_BIT_EN_REG_CLK; + } else { + nv = v & ~(FSP_BIT_EN_REG_CLK); + } + /* only write if necessary */ + if (nv != v) { + if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1) + return (-1); + } + return (0); +} + +static int +fsp_page_reg_read(struct psmouse *psmouse, int *reg_val) +{ + unsigned char param[3]; +#ifdef FSP_DEBUG + printk(KERN_INFO "fsp_page_reg_read: READ PAGE REG\n"); +#endif + if (fsp_ps2_command(psmouse, NULL, 0x00f3) < 0) + return (-1); + + fsp_ps2_command(psmouse, NULL, 0x0066); + fsp_ps2_command(psmouse, NULL, 0x0088); + + if (fsp_ps2_command(psmouse, NULL, 0x00f3) < 0) + return (-1); + + fsp_ps2_command(psmouse, NULL, 0x0083); + fsp_ps2_command(psmouse, NULL, 0x0088); + + /* get the returned result */ + if (fsp_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) + return (-1); + + *reg_val = param[2]; + + return (0); +} + +static int +fsp_page_reg_write(struct psmouse *psmouse, int reg_val) +{ + unsigned char v; +#ifdef FSP_DEBUG + printk(KERN_INFO "fsp_page_reg_write: WRITE PAGE REG\n"); +#endif + if (fsp_ps2_command(psmouse, NULL, 0x00f3) < 0) + return (-1); + + fsp_ps2_command(psmouse, NULL, 0x0038); + fsp_ps2_command(psmouse, NULL, 0x0088); + + if (fsp_ps2_command(psmouse, NULL, 0x00f3) < 0) + return (-1); + + if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { + fsp_ps2_command(psmouse, NULL, 0x0047); + } else { + if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) { + /* swapping is required */ + fsp_ps2_command(psmouse, NULL, 0x0044); + } else { + /* swapping isn't necessary */ + fsp_ps2_command(psmouse, NULL, 0x0033); + } + } + fsp_ps2_command(psmouse, NULL, v); + + return (0); +} + +static int +fsp_batch_write_reg(struct psmouse *psmouse, + const unsigned char *params, size_t size) +{ + int i, v; + + if (size == 0) + return (0); + + /* begin writing: enable register clock gating */ + fsp_reg_write_enable(psmouse, 1); + + for (i = v = 0; i < size; i += 2) { + if (fsp_reg_write(psmouse, params[i], params[i + 1]) != 0) + v = -1; + } + + /* complete writing: disable register clock gating */ + fsp_reg_write_enable(psmouse, 0); + + return (v); +} + +static int +fsp_device_id(struct psmouse *psmouse) +{ + int id; + + if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id)) + return (-1); + else + return (id); +} + +static int +fsp_get_version(struct psmouse *psmouse) +{ + int ver; + + if (fsp_reg_read(psmouse, FSP_REG_VERSION, &ver)) + return (-1); + else + return (ver); +} + +static int +fsp_get_revision(struct psmouse *psmouse) +{ + int rev; + + if (fsp_reg_read(psmouse, FSP_REG_REVISION, &rev)) + return (-1); + else + return (rev); +} + +static int +fsp_get_buttons(struct psmouse *psmouse) +{ + int buttons; + + if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS1, &buttons) == -1) + return (-1); + + switch (buttons & 0x30) { + case 0x30: + default: + /* Left/Middle/Right */ + return (0x02); + + case 0x20: + /* Left/Middle/Right & Scroll Up/Down */ + return (0x04); + + case 0x10: + /* Left/Middle/Right & Scroll Up/Down/Right/Left */ + return (0x06); + + case 0x00: + /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */ + return (0x16); + } +} + +/** enable on-pad command tag output */ +static int +fsp_opc_tag_enable(struct psmouse *psmouse, int en) +{ + int v, nv, res = 0; + + if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) { + printk(KERN_ERR "Unable get OPC state.\n"); + return (-1); + } + if (en) { + nv = v | FSP_BIT_EN_OPC_TAG; + } else { + nv = v & ~(FSP_BIT_EN_OPC_TAG); + } + /* only write if necessary */ + if (nv != v) { + fsp_reg_write_enable(psmouse, 1); + res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv); + fsp_reg_write_enable(psmouse, 0); + } + if (res != 0) { + printk(KERN_ERR "Unable to enable OPC tag.\n"); + } + return (res); +} + +/** + * set packet format based on the number of buttons current device has + */ +static int +fsp_set_packet_format(struct psmouse *psmouse) +{ + struct fsp_data *ad = psmouse->private; + struct ps2dev *ps2dev = &psmouse->ps2dev; + unsigned char param[2]; + int val; + + switch (ad->buttons) { + case 0x02: + /* Left/Middle/Right */ + case 0x04: + /* Left/Middle/Right & Scroll Up/Down */ + case 0x16: + /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */ + + /* + * standard procedure to enter FSP Intellimouse mode + * (scrolling wheel, 4th and 5th buttons) + */ + param[0] = 200; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + param[0] = 200; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + param[0] = 80; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); + if (param[0] != 0x04) { + printk(KERN_ERR "Unable to enable 4 bytes packet.\n"); + psmouse->pktsize = 3; + return (-1); + } + psmouse->pktsize = 4; + break; + case 0x06: + /* Left/Middle/Right & Scroll Up/Down/Right/Left */ + fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val); + val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8); + val |= FSP_BIT_EN_MSID6; + if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) { + printk(KERN_ERR "Unable to enable MSID6 mode.\n"); + return (-1); + } + psmouse->pktsize = 4; + break; + default: + printk(KERN_ERR "Unknown number of buttons.\n"); + break; + } + /* + * enable OPC tags such that driver can tell the difference between + * on-pad and real button click + */ + return fsp_opc_tag_enable(psmouse, 1); +} + +/* + * return 0 if the pad is placed in 180 degree + */ +int +fsp_get_degree(struct psmouse *psmouse) +{ + int degree; + + if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS1, °ree)) + return (-1); + else + return (degree & FSP_BIT_NO_ROTATION) ? 1 : 0; +} + +static int +fsp_onpad_vscr(struct psmouse *psmouse, int enable) +{ + struct fsp_data *ad = psmouse->private; + struct fsp_hw_state *state = &ad->hw_state; + int val; + + if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val)) + return (-1); + + state->onpad_vscroll = (enable == 0) ? 0 : 1; + + if (enable) + val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE); + else + val &= (0xff ^ FSP_BIT_FIX_VSCR); + + if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val)) + return (-1); + + return (0); +} + +static int +fsp_onpad_hscr(struct psmouse *psmouse, int enable) +{ + struct fsp_data *ad = psmouse->private; + struct fsp_hw_state *state = &ad->hw_state; + int val, v2; + + if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val)) + return (-1); + + if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2)) + return (-1); + + state->onpad_hscroll = (enable == 0) ? 0 : 1; + + if (enable) { + val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE); + v2 |= FSP_BIT_EN_MSID6; + } else { + val &= (0xff ^ FSP_BIT_FIX_HSCR); + v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8); + } + + if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val)) + return (-1); + + /* reconfigure horizontal scrolling packet output */ + if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2)) + return (-1); + + return (0); +} + +static int +fsp_onpad_icon(struct psmouse *psmouse, int enable) +{ + struct fsp_data *ad = psmouse->private; + struct fsp_hw_state *state = &ad->hw_state; + int val; + +#ifdef notyet + /* switch to register page 1, where icon switch button registers are */ + fsp_reg_read(psmouse, FSP_REG_PAGE_CTRL, &val); + val |= 0x01; + if (fsp_reg_write(psmouse, FSP_REG_PAGE_CTRL, val)) + return (-1); + + fsp_reg_write_enable(psmouse, 1); + /* set position of icon switch button */ + /* + * XL XH + * YL+--------+ + * | sw_btn | POSITION UNIT IS IN 0.5 SCANLINE + * YH+--------+ + */ + if (fsp_reg_write(psmouse, FSP_REG_OPTZ_YHI, 0)) + val = -1; + if (fsp_reg_write(psmouse, FSP_REG_OPTZ_YLO, 6)) + val = -1; + if (fsp_reg_write(psmouse, FSP_REG_OPTZ_XHI, 0)) + val = -1; + if (fsp_reg_write(psmouse, FSP_REG_OPTZ_XLO, 6 | 0x80)) + val = -1; + fsp_reg_write_enable(psmouse, 0); + if (val == -1) + return (-1); + + /* switch back to register page 0 */ + fsp_reg_read(psmouse, FSP_REG_PAGE_CTRL, &val); + val &= ~0x01; + if (fsp_reg_write(psmouse, FSP_REG_PAGE_CTRL, val)) + return (-1); +#endif + /* enable icon switch button and absolute packet */ + fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val); + val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8); + + if (enable) { + val |= (FSP_BIT_EN_MSID8 | FSP_BIT_EN_PKT_G0); + state->onpad_icon = 1; + state->abs_pkt = 1; + } else { + state->onpad_icon = 0; + state->abs_pkt = 0; + } + + if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) + return (-1); + + return (0); +} + +/* + * It turns out that kernel provided sscanf() was not able to scan numbers + * in specified width; therefore, we ended up with rolling our own version + * of HEX string to integer helper. + */ +static int +hexstr2int(const char *str, int width) +{ + int i, val, res = 0; + + if (width > sizeof(int)) + return (res); + + for (i = 0; i < width; i++) { + const char *ptr = &str[i]; + + if (!isxdigit(*ptr)) + break; + + val = isdigit(*ptr) ? *ptr - '0' : toupper(*ptr)- 'A' + 10; + res = res * 16 + val; + } + return (res); +} + +static ssize_t +psmouse_attr_show_setreg(struct psmouse *psmouse, void *data, char *buf) +{ + /* do nothing */ + return (0); +} + +/* + * Write device specific initial parameters. + * + * ex: abcdc00d -- write 0xcd to register 0xab and 0x0d to 0xc0 + */ +static ssize_t +psmouse_attr_set_setreg(struct psmouse *psmouse, void *data, + const char *buf, size_t count) +{ + struct fsp_data *ad = psmouse->private; + int i, len, val; + + if ((count % 4) != 0) + return (-EINVAL); + + if ((len = (count >> 1)) >= sizeof(ad->init_params)) + return (-ENOMEM); + + for (i = 0; i < len; i += 2) { + val = hexstr2int(&buf[i << 1], 4); + ad->init_params[i] = (val >> 8) & 0xff; + ad->init_params[i + 1] = val & 0xff; + } + ad->init_params_len = len; + fsp_batch_write_reg(psmouse, ad->init_params, len); + + return (count); +} + +PSMOUSE_DEFINE_ATTR(setreg, S_IWUSR | S_IRUGO, NULL, + psmouse_attr_show_setreg, psmouse_attr_set_setreg); + +static ssize_t +psmouse_attr_show_getreg(struct psmouse *psmouse, void *data, char *buf) +{ + struct fsp_data *ad = psmouse->private; + + buf[0] = 0; + return sprintf(buf, "%04x\n", ad->last_reg_val); +} + +/* + * Read a register from device. + * + * ex: ab -- read content from register 0xab + */ +static ssize_t +psmouse_attr_set_getreg(struct psmouse *psmouse, void *data, const char *buf, + size_t count) +{ + struct fsp_data *ad = psmouse->private; + int reg, val; + + if (count != 2) + return (-EINVAL); + + reg = hexstr2int(buf, 2); + + if (fsp_reg_read(psmouse, reg, &val)) + return (-ENODEV); + + ad->last_reg_val = (reg << 8) | val; + + return (count); +} + +PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL, + psmouse_attr_show_getreg, psmouse_attr_set_getreg); + +static ssize_t +psmouse_attr_show_pagereg(struct psmouse *psmouse, void *data, char *buf) +{ + int val; + + buf[0] = 0; + + if (fsp_page_reg_read(psmouse, &val)) + return (-ENODEV); + + return sprintf(buf, "%02x\n", val); +} + +static ssize_t +psmouse_attr_set_pagereg(struct psmouse *psmouse, void *data, const char *buf, + size_t count) +{ + int val; + + if (count != 2) + return (-EINVAL); + + val = hexstr2int(buf, 2); + + if (fsp_page_reg_write(psmouse, val)) + return (-ENODEV); + + return (count); +} + +PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL, + psmouse_attr_show_pagereg, psmouse_attr_set_pagereg); + +static ssize_t +psmouse_attr_show_ps2(struct psmouse *psmouse, void *data, char *buf) +{ + struct fsp_data *ad = psmouse->private; + char tmp[2]; + int i, len; + + for (i = len = 0; i < ad->resp_cnt; i++) { + len += sprintf(tmp, "%02x", ad->resp[i]); + strcat(buf, tmp); + } + strcat(buf, "\n"); + return (len + 1); +} + +static ssize_t +psmouse_attr_set_ps2(struct psmouse *psmouse, void *data, const char *buf, + size_t count) +{ + struct fsp_data *ad = psmouse->private; + struct ps2dev *ps2dev = &psmouse->ps2dev; + int v; + + if (count != 4) + return (-EINVAL); + + v = hexstr2int(buf, 4); + + if (ps2_command(ps2dev, ad->resp, v) != -1) { + ad->resp_cnt = (v >> 8) & (FSP_RESP_PKT_MAXLEN - 1); + } else { + ad->resp_cnt = 0; + } + return (count); +} + +PSMOUSE_DEFINE_ATTR(ps2, S_IWUSR | S_IRUGO, NULL, + psmouse_attr_show_ps2, psmouse_attr_set_ps2); + +static ssize_t +psmouse_attr_show_vscroll(struct psmouse *psmouse, void *data, char *buf) +{ + struct fsp_data *ad = psmouse->private; + + return sprintf(buf, "%d\n", ad->hw_state.onpad_vscroll ? 1 : 0); +} + +static ssize_t +psmouse_attr_set_vscroll(struct psmouse *psmouse, void *data, const char *buf, + size_t count) +{ + struct fsp_data *ad = psmouse->private; + unsigned long val; + char *rest; + + val = simple_strtoul(buf, &rest, 10); + + if (*rest || (val > 1)) + return (-EINVAL); + + ad->hw_state.onpad_vscroll = val; + fsp_onpad_vscr(psmouse, val); + + return (count); +} + +PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO | S_IWUGO, NULL, + psmouse_attr_show_vscroll, psmouse_attr_set_vscroll); + +static ssize_t +psmouse_attr_show_hscroll(struct psmouse *psmouse, void *data, char *buf) +{ + struct fsp_data *ad = psmouse->private; + + return sprintf(buf, "%d\n", ad->hw_state.onpad_hscroll ? 1 : 0); +} + +static ssize_t +psmouse_attr_set_hscroll(struct psmouse *psmouse, void *data, const char *buf, + size_t count) +{ + struct fsp_data *ad = psmouse->private; + unsigned long val; + char *rest; + + val = simple_strtoul(buf, &rest, 10); + + if (*rest || (val > 1)) + return (-EINVAL); + + ad->hw_state.onpad_hscroll = val; + fsp_onpad_hscr(psmouse, val); + + return (count); +} + +PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO | S_IWUGO, NULL, + psmouse_attr_show_hscroll, psmouse_attr_set_hscroll); + +static ssize_t +psmouse_attr_show_onpadicon(struct psmouse *psmouse, void *data, char *buf) +{ + struct fsp_data *ad = psmouse->private; + + return sprintf(buf, "%d\n", ad->hw_state.onpad_icon ? 1 : 0); +} + +static ssize_t +psmouse_attr_set_onpadicon(struct psmouse *psmouse, void *data, + const char *buf, size_t count) +{ + struct fsp_data *ad = psmouse->private; + unsigned long val; + char *rest; + + val = simple_strtoul(buf, &rest, 10); + + if (*rest || (val > 1)) + return (-EINVAL); + + ad->hw_state.onpad_icon = val; + fsp_onpad_icon(psmouse, val); + + return (count); +} + +PSMOUSE_DEFINE_ATTR(onpadicon, S_IWUSR | S_IRUGO | S_IWUGO, NULL, + psmouse_attr_show_onpadicon, psmouse_attr_set_onpadicon); + +static ssize_t +psmouse_attr_show_pktfmt(struct psmouse *psmouse, void *data, char *buf) +{ + struct fsp_data *ad = psmouse->private; + + return sprintf(buf, "%d\n", ad->hw_state.pkt_fmt); +} + +static ssize_t +psmouse_attr_set_pktfmt(struct psmouse *psmouse, void *data, + const char *buf, size_t count) +{ + struct fsp_data *ad = psmouse->private; + unsigned long val; + char *rest; + + val = simple_strtoul(buf, &rest, 10); + + if (*rest || (val > 2)) + return (-EINVAL); + + ad->hw_state.pkt_fmt = val; + /* TODO need full G0/A0 abs. packet setup */ + + return (count); +} + +PSMOUSE_DEFINE_ATTR(pktfmt, S_IWUSR | S_IRUGO | S_IWUGO, NULL, + psmouse_attr_show_pktfmt, psmouse_attr_set_pktfmt); + +static ssize_t +psmouse_attr_show_flags(struct psmouse *psmouse, void *data, char *buf) +{ + struct fsp_data *ad = psmouse->private; + + return sprintf(buf, "%c%c%c%c%c%c\n", + ad->flags & FSPDRV_FLAG_OPICON_KEY ? 'K' : 'k', + ad->flags & FSPDRV_FLAG_OPICON_BTN ? 'B' : 'b', + ad->flags & FSPDRV_FLAG_REVERSE_X ? 'X' : 'x', + ad->flags & FSPDRV_FLAG_REVERSE_Y ? 'Y' : 'y', + ad->flags & FSPDRV_FLAG_AUTO_SWITCH ? 'A' : 'a', + ad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c'); +} + +static ssize_t +psmouse_attr_set_flags(struct psmouse *psmouse, void *data, + const char *buf, size_t count) +{ + struct fsp_data *ad = psmouse->private; + size_t i; + + for (i = 0; i < count; i++) { + switch (buf[i]) { + case 'B': + ad->flags |= FSPDRV_FLAG_OPICON_BTN; + break; + case 'b': + ad->flags &= ~FSPDRV_FLAG_OPICON_BTN; + break; + case 'K': + ad->flags |= FSPDRV_FLAG_OPICON_KEY; + break; + case 'k': + ad->flags &= ~FSPDRV_FLAG_OPICON_KEY; + break; + case 'X': + ad->flags |= FSPDRV_FLAG_REVERSE_X; + break; + case 'x': + ad->flags &= ~FSPDRV_FLAG_REVERSE_X; + break; + case 'Y': + ad->flags |= FSPDRV_FLAG_REVERSE_Y; + break; + case 'y': + ad->flags &= ~FSPDRV_FLAG_REVERSE_Y; + break; + case 'A': + ad->flags |= FSPDRV_FLAG_AUTO_SWITCH; + break; + case 'a': + ad->flags &= ~FSPDRV_FLAG_AUTO_SWITCH; + break; + case 'C': + ad->flags |= FSPDRV_FLAG_EN_OPC; + break; + case 'c': + ad->flags &= ~FSPDRV_FLAG_EN_OPC; + break; + case 'R': + case 'r': + /* hack: reset pad */ +#ifdef FSP_DEBUG + printk(KERN_INFO "Resetting FSP...\n"); +#endif + /* disable on-pad vertical scrolling */ + fsp_onpad_vscr(psmouse, 0); + /* disable on-pad horizontal scrolling */ + fsp_onpad_hscr(psmouse, 0); + + /* + * disable on-pad switching icon and absolute packet + * mode + */ + fsp_onpad_icon(psmouse, 0); + /* reload custom initial parameters */ + fsp_reset(psmouse); + /* re-initialise output packet format */ + fsp_set_packet_format(psmouse); + break; + default: + return (-EINVAL); + } + } + return (count); +} + +PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO | S_IWUGO, NULL, + psmouse_attr_show_flags, psmouse_attr_set_flags); + +static ssize_t +psmouse_attr_show_ver(struct psmouse *psmouse, void *data, char *buf) +{ + return sprintf(buf, "Sentelic FSP kernel module %d.%d.%d\n", + fsp_drv_ver[0], fsp_drv_ver[1], fsp_drv_ver[2]); +} + +static ssize_t +psmouse_attr_set_ver(struct psmouse *psmouse, void *data, + const char *buf, size_t count) +{ + /* do nothing */ + return (count); +} + +PSMOUSE_DEFINE_ATTR(ver, S_IRUSR | S_IRUGO, NULL, + psmouse_attr_show_ver, psmouse_attr_set_ver); + +static ssize_t +psmouse_attr_show_accel(struct psmouse *psmouse, void *data, char *buf) +{ + struct fsp_data *ad = psmouse->private; + + return sprintf(buf, "%d %d %d\n", + ad->accel_num, ad->accel_denom, ad->accel_threshold); +} + +static ssize_t +psmouse_attr_set_accel(struct psmouse *psmouse, void *data, + const char *buf, size_t count) +{ + struct fsp_data *ad = psmouse->private; + + sscanf(buf, "%d %d %d", + &ad->accel_num, &ad->accel_denom, &ad->accel_threshold); + + /* sanity check */ + if (ad->accel_num <= 0) + ad->accel_num = DEFAULT_ACCEL_NUM; + + /* prevent dividing by zero */ + if (ad->accel_denom <= 0) + ad->accel_denom = DEFAULT_ACCEL_DENOM; + + if (ad->accel_threshold <= 0) + ad->accel_threshold = DEFAULT_ACCEL_THRESHOLD; + + return (count); +} + +PSMOUSE_DEFINE_ATTR(accel, S_IWUSR | S_IRUGO | S_IWUGO, NULL, + psmouse_attr_show_accel, psmouse_attr_set_accel); + +int +fsp_reset(struct psmouse *psmouse) +{ + /* TODO: reset initial parameters */ + return (0); +} + +static int +fsp_reconnect(struct psmouse *psmouse) +{ + int version; + + if (fsp_detect(psmouse, 0) < 0) + return (-1); + + if ((version = fsp_get_version(psmouse)) < 0) + return (-1); + + fsp_reset(psmouse); + + return (0); +} + +static void +fsp_remove_sysfs(struct psmouse *psmouse) +{ + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_setreg.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_getreg.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_page.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_ps2.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_vscroll.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_hscroll.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_onpadicon.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_pktfmt.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_flags.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_ver.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_accel.dattr); +} + +static void +fsp_disconnect(struct psmouse *psmouse) +{ + fsp_remove_sysfs(psmouse); + fsp_opc_tag_enable(psmouse, 0); + fsp_reset(psmouse); + kfree(psmouse->private); +} + +int +fsp_detect(struct psmouse *psmouse, int set_properties) +{ + int rc; + + if (fsp_device_id(psmouse) != 0x01) + return (-1); + + if (set_properties) { + psmouse->vendor = "Sentelic"; + psmouse->name = "FingerSensingPad"; + + /* + * register sysfs callbacks for userland program to set + * initial parameters + */ + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_setreg.dattr); + if (rc) + goto sysfs_creation_failed; + + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_getreg.dattr); + if (rc) + goto sysfs_creation_failed; + + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_page.dattr); + if (rc) + goto sysfs_creation_failed; + + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_ps2.dattr); + if (rc) + goto sysfs_creation_failed; + + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_vscroll.dattr); + if (rc) + goto sysfs_creation_failed; + + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_hscroll.dattr); + if (rc) + goto sysfs_creation_failed; + + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_onpadicon.dattr); + if (rc) + goto sysfs_creation_failed; + + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_pktfmt.dattr); + if (rc) + goto sysfs_creation_failed; + + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_flags.dattr); + if (rc) + goto sysfs_creation_failed; + + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_ver.dattr); + if (rc) + goto sysfs_creation_failed; + + rc = device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_accel.dattr); + if (rc) + goto sysfs_creation_failed; + } + return (0); +sysfs_creation_failed: + fsp_remove_sysfs(psmouse); + printk(KERN_ERR "failed to create sysfs node(%d)", rc); + return (-1); +} + +static void +fsp_set_input_params(struct psmouse *psmouse) +{ + struct fsp_data *ad = psmouse->private; + struct fsp_hw_state *state = &ad->hw_state; + + if (state->abs_pkt == 0) { + set_bit(BTN_MIDDLE, psmouse->dev->keybit); + set_bit(REL_WHEEL, psmouse->dev->relbit); + set_bit(REL_HWHEEL, psmouse->dev->relbit); + + set_bit(EV_REL, psmouse->dev->evbit); + set_bit(REL_X, psmouse->dev->relbit); + set_bit(REL_Y, psmouse->dev->relbit); + + set_bit(BTN_BACK, psmouse->dev->keybit); + set_bit(BTN_FORWARD, psmouse->dev->keybit); + + clear_bit(EV_ABS, psmouse->dev->evbit); + clear_bit(BTN_SIDE, psmouse->dev->keybit); + clear_bit(BTN_EXTRA, psmouse->dev->keybit); + } else { + /* enable absolute packet mode */ + set_bit(EV_ABS, psmouse->dev->evbit); + + input_set_abs_params(psmouse->dev, ABS_X, + 0, 1023, 0, 0); + input_set_abs_params(psmouse->dev, ABS_Y, + 0, 767, 0, 0); + + /* no more relative coordinates */ + clear_bit(EV_REL, psmouse->dev->evbit); + clear_bit(REL_X, psmouse->dev->relbit); + clear_bit(REL_Y, psmouse->dev->relbit); + } +} + +static psmouse_ret_t +fsp_process_byte(struct psmouse *psmouse +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +, struct pt_regs *regs +#endif +) +{ + struct input_dev *dev = psmouse->dev; + struct fsp_data *ad = psmouse->private; + unsigned char *packet = psmouse->packet; + unsigned char button_status = 0, lscroll, rscroll; +#ifdef FSP_DEBUG + unsigned int jiffies_msec; +#endif + static unsigned short prev_abs_x, prev_abs_y; + unsigned short abs_x, abs_y; + int rel_x, rel_y; + + if (psmouse->pktcnt < 4) + return (PSMOUSE_GOOD_DATA); + + if (psmouse->ps2dev.flags != 0) { + /* + * XXX need to find the root cause that makes commanding + * packet leaking to this function. + * + * Perhaps our own version of ps2_command() is out of date? + */ + return (PSMOUSE_GOOD_DATA); + } + + /* + * Full packet accumulated, process it + */ + lscroll = rscroll = 0; + + switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { + case FSP_PKT_TYPE_ABS: + abs_x = (packet[1] << 2) | ((packet[3] >> 2) & 0x03); + abs_y = (packet[2] << 2) | (packet[3] & 0x03); + + if (abs_x && abs_y) { + /* no X/Y directional reversal when finger is up */ + if (ad->flags & FSPDRV_FLAG_REVERSE_X) + abs_x = 1023 - abs_x; + if (ad->flags & FSPDRV_FLAG_REVERSE_Y) + abs_y = 767 - abs_y; + prev_abs_x = abs_x; + prev_abs_y = abs_y; + } + if (ad->flags & (FSPDRV_FLAG_OPICON_BTN | FSPDRV_FLAG_OPICON_KEY)) { + /* do nothing */ + } else { + input_report_key(dev, BTN_LEFT, packet[0] & 1); + input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); + input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); +#if 0 + /* vscroll down */ + input_report_key(dev, BTN_BACK, (packet[3] >> 5) & 1); + /* vscroll up */ + input_report_key(dev, BTN_FORWARD, (packet[3] >> 4) & 1); + /* rscroll */ + input_report_key(dev, BTN_RIGHT, (packet[3] >> 7) & 1); + /* lscroll */ + input_report_key(dev, BTN_LEFT, (packet[3] >> 6) & 1); +#endif + } + input_report_abs(dev, ABS_X, prev_abs_x); + input_report_abs(dev, ABS_Y, prev_abs_y); + break; + case FSP_PKT_TYPE_NORMAL_OPC: + /* on-pad click, filter it if necessary */ + if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC) { + packet[0] &= ~BIT(0); + } + /* fall through */ + case FSP_PKT_TYPE_NORMAL: + /* normal packet */ + /* special packet data translation from on-pad packets */ + if (packet[3] != 0) { + if (packet[3] & BIT(0)) { + button_status |= 0x01; /* wheel down */ + } + if (packet[3] & BIT(1)) { + button_status |= 0x0f; /* wheel up */ + } + if (packet[3] & BIT(2)) { + button_status |= BIT(5);/* horizontal left */ + } + if (packet[3] & BIT(3)) { + button_status |= BIT(4);/* horizontal right */ + } + /* push back to packet queue */ + if (button_status != 0) + packet[3] = button_status; + rscroll = (packet[3] >> 4) & 1; + lscroll = (packet[3] >> 5) & 1; + } + /* + * Processing wheel up/down and extra button events + */ + input_report_rel(dev, REL_WHEEL, (int)(packet[3] & 8) - (int)(packet[3] & 7)); + input_report_rel(dev, REL_HWHEEL, lscroll - rscroll); + input_report_key(dev, BTN_BACK, lscroll); + input_report_key(dev, BTN_FORWARD, rscroll); + + /* + * Generic PS/2 Mouse + */ + input_report_key(dev, BTN_LEFT, packet[0] & 1); + input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); + input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); + + /* perform acceleration */ + rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0; + rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0; + + if (abs(rel_x) > ad->accel_threshold) { + rel_x = rel_x * ad->accel_num / ad->accel_denom; + } + if (abs(rel_y) > ad->accel_threshold) { + rel_y = rel_y * ad->accel_num / ad->accel_denom; + } + input_report_rel(dev, REL_X, rel_x); + input_report_rel(dev, REL_Y, rel_y); + break; + } + + input_sync(dev); + +#ifdef FSP_DEBUG + ps2_packet_cnt++; + jiffies_msec = jiffies_to_msecs(jiffies); + printk(KERN_INFO "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n", jiffies_msec, packet[0], packet[1], packet[2], packet[3]); + + if (jiffies_msec - ps2_last_second > 1000) { + printk(KERN_INFO "PS/2 packets/sec = %d\n", ps2_packet_cnt); + ps2_packet_cnt = 0; + ps2_last_second = jiffies_msec; + } +#endif + return (PSMOUSE_FULL_PACKET); +} + +int +fsp_init(struct psmouse *psmouse) +{ + struct fsp_data *priv; + int ver; + + if ((ver = fsp_get_version(psmouse)) < 0) + return (-1); + + if (!(priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL))) + return (-ENOMEM); + + psmouse->private = priv; + + priv->ver = ver; + priv->rev = fsp_get_revision(psmouse); + priv->buttons = fsp_get_buttons(psmouse); + + /* enable on-pad click by default */ + priv->flags |= FSPDRV_FLAG_EN_OPC; + + switch (priv->buttons) { + case 0x06: + priv->hw_state.btn_fbbb = 0; + priv->hw_state.btn_slsr = 1; + break; + case 0x16: + priv->hw_state.btn_fbbb = 1; + priv->hw_state.btn_slsr = 0; + break; + default: + priv->hw_state.btn_fbbb = 0; + priv->hw_state.btn_slsr = 0; + break; + } + psmouse->protocol_handler = fsp_process_byte; + psmouse->disconnect = fsp_disconnect; + psmouse->reconnect = fsp_reconnect; + + /* report hardware information */ + printk(KERN_INFO "Finger Sensing Pad, hw: %d.%d.%d, sw: %d.%d.%d, buttons: %d\n", + (priv->ver >> 4), (priv->ver & 0x0F), priv->rev, + fsp_drv_ver[0], fsp_drv_ver[1], fsp_drv_ver[2], + priv->buttons & 7); + + /* set default acceleration parameters */ + priv->accel_num = DEFAULT_ACCEL_NUM; + priv->accel_denom = DEFAULT_ACCEL_DENOM; + priv->accel_threshold = DEFAULT_ACCEL_THRESHOLD; + + /* set default packet output based on number of buttons we found */ + fsp_set_packet_format(psmouse); + + /* disable on-pad vertical scrolling */ + //fsp_onpad_vscr(psmouse, 0); + + /* disable on-pad horizontal scrolling */ + fsp_onpad_hscr(psmouse, 0); + + /* disable on-pad switching icon and absolute packet mode */ + fsp_onpad_icon(psmouse, 0); + + /* set various supported input event bits */ + fsp_set_input_params(psmouse); + + return (0); +} diff --git a/drivers/input/mouse/sentelic.h b/drivers/input/mouse/sentelic.h new file mode 100644 index 0000000..8fcaa40 --- /dev/null +++ b/drivers/input/mouse/sentelic.h @@ -0,0 +1,136 @@ +/*- + * Finger Sensing Pad PS/2 mouse driver. + * + * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. + * Copyright (C) 2005-2008 Tai-hwa Liang, Sentelic Corporation. + * + * 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. + * + * $Id: sentelic.h 28700 2008-10-16 07:23:43Z avatar $ + */ + +#ifndef __SENTELIC_H__ +#define __SENTELIC_H__ + +#if defined(__KERNEL__) +extern int fsp_detect(struct psmouse *psmouse, int set_properties); +extern int fsp_init(struct psmouse *psmouse); +extern int fsp_reset(struct psmouse *psmouse); +#endif + +/* Finger-sensing Pad information registers */ +#define FSP_REG_DEVICE_ID 0x00 +#define FSP_REG_VERSION 0x01 +#define FSP_REG_REVISION 0x04 +#define FSP_REG_TMOD_STATUS1 0x0B +#define FSP_BIT_NO_ROTATION BIT(3) +#define FSP_REG_PAGE_CTRL 0x0F + +/* Finger-sensing Pad control registers */ +#define FSP_REG_SYSCTL1 0x10 +#define FSP_BIT_EN_REG_CLK BIT(5) +#define FSP_REG_OPC_QDOWN 0x31 +#define FSP_BIT_EN_OPC_TAG BIT(7) +#define FSP_REG_OPTZ_XLO 0x34 +#define FSP_REG_OPTZ_XHI 0x35 +#define FSP_REG_OPTZ_YLO 0x36 +#define FSP_REG_OPTZ_YHI 0x37 +#define FSP_REG_SYSCTL5 0x40 +#define FSP_BIT_90_DEGREE BIT(0) +#define FSP_BIT_EN_MSID6 BIT(1) +#define FSP_BIT_EN_MSID7 BIT(2) +#define FSP_BIT_EN_MSID8 BIT(3) +#define FSP_BIT_EN_AUTO_MSID8 BIT(5) +#define FSP_BIT_EN_PKT_G0 BIT(6) + +#define FSP_REG_ONPAD_CTL 0x43 +#define FSP_BIT_ONPAD_ENABLE BIT(0) +#define FSP_BIT_ONPAD_FBBB BIT(1) +#define FSP_BIT_FIX_VSCR BIT(3) +#define FSP_BIT_FIX_HSCR BIT(5) +#define FSP_BIT_DRAG_LOCK BIT(6) + +/* Finger-sensing Pad packet formating related definitions */ + +/* absolute packet type */ +#define FSP_PKT_TYPE_NORMAL (0x00) +#define FSP_PKT_TYPE_ABS (0x01) +#define FSP_PKT_TYPE_NOTIFY (0x02) +#define FSP_PKT_TYPE_NORMAL_OPC (0x03) +#define FSP_PKT_TYPE_SHIFT (6) + +struct fsp_hw_state +{ + unsigned char onpad_vscroll:1,/* On-pad vertical scroll zone */ + onpad_hscroll:1,/* On-pad horizontal scroll zone */ + onpad_icon:1, /* On-pad icons */ + btn_fbbb:1, /* Forward/backward button */ + btn_slsr:1, /* Scroll left/right button */ + abs_pkt:1, /* absolute packet mode */ + pkt_fmt:2; /* packet format */ + unsigned int reg_val; /* used by reg_write sysctl */ +}; + +struct fsp_data +{ + unsigned int flags; +#define FSPDRV_FLAG_CMD (0x010) /* The command bit of flags indicates the special FSP PS/2 command is sent. */ +#define FSPDRV_FLAG_RESP (0x020) /* The response bit of flags indicates the special FSP PS/2 comamnd is sent and response is received. */ +#define FSPDRV_FLAG_OPICON_BTN (0x040) /* Output on-pad icons as BTN events */ +#define FSPDRV_FLAG_OPICON_KEY (0x080) /* Output on-pad icons as KEY events */ +#define FSPDRV_FLAG_REVERSE_X (0x100) /* reverse X direction */ +#define FSPDRV_FLAG_REVERSE_Y (0x200) /* reverse Y direction */ +#define FSPDRV_FLAG_AUTO_SWITCH (0x400) /* software on-pad icon auto switch */ +#define FSPDRV_FLAG_EN_OPC (0x800) /* enable on-pad clicking */ +#define FSP_RESP_PKT_MAXLEN (8) /* The max response packet size. */ + unsigned char cmd; /* The buffer used to store the sending PS/2 command */ + unsigned char resp[FSP_RESP_PKT_MAXLEN]; /* The buffer used to store the response of PS/2 command */ + int resp_cnt; /* The command count in resp buffer */ + unsigned char buttons; /* Number of buttons */ + unsigned char ver; /* hardware version */ + unsigned char rev; /* hardware revison */ + unsigned int mode; /* device mode */ +#define FSPDRV_MODE_BTN_RIGHT BIT(0) +#define FSPDRV_MODE_BTN_MIDDLE BIT(1) +#define FSPDRV_MODE_BTN_LEFT BIT(2) +#define FSPDRV_MODE_BTN_SCRD BIT(3) +#define FSPDRV_MODE_BTN_SCRU BIT(4) +#define FSPDRV_MODE_BTN_SCRL BIT(5) +#define FSPDRV_MODE_BTN_SCRR BIT(6) +#define FSPDRV_MODE_BTN_FB BIT(7) +#define FSPDRV_MODE_BTN_BB BIT(8) + unsigned char button_status; + unsigned int last_reg_val; + +/** default acceleration numerator */ +#define DEFAULT_ACCEL_NUM (2) + /** numerator for the acceleration multiplier */ + int accel_num; +/** default acceleration denominator */ +#define DEFAULT_ACCEL_DENOM (1) + /** denominator for the acceleration multiplier */ + int accel_denom; +/** default acceleration threshold */ +#define DEFAULT_ACCEL_THRESHOLD (4) + + /** acceleration threshold */ + int accel_threshold; +#define FSPDRV_SET_REG_BUF_LEN (256) + unsigned char init_params[FSPDRV_SET_REG_BUF_LEN]; + size_t init_params_len; + struct fsp_hw_state hw_state; +}; + +#endif /* !__SENTELIC_H__ */ diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 170f71e..505c0a8 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -143,7 +143,7 @@ static int i8042_wait_write(void) * of the i8042 down the toilet. */ -static int i8042_flush(void) +int i8042_flush(void) { unsigned long flags; unsigned char data, str; @@ -716,15 +716,27 @@ static int i8042_controller_selftest(void) if (!i8042_reset) return 0; + if (1) { + unsigned char ctr; + ctr |= I8042_CTR_KBDDIS; + ctr &= ~I8042_CTR_KBDINT; + + printk("Disable kbd before selftest\n"); + if (i8042_command(&ctr, I8042_CMD_CTL_WCTR)) { + printk(KERN_ERR "i8042.c: Failed to disable KBD port.\n"); + return -EIO; + } + } + if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); - return -ENODEV; + //return -ENODEV; } if (param != I8042_RET_CTL_TEST) { printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", param, I8042_RET_CTL_TEST); - return -EIO; + //return -EIO; } return 0; @@ -746,7 +758,7 @@ static int i8042_controller_init(void) if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) { printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n"); - return -EIO; + //return -EIO; } i8042_initial_ctr = i8042_ctr; @@ -795,7 +807,7 @@ static int i8042_controller_init(void) if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n"); - return -EIO; + //return -EIO; } return 0; @@ -956,7 +968,7 @@ static int i8042_resume(struct platform_device *dev) msleep(50); if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { printk(KERN_ERR "i8042: CTR write retry failed\n"); - return -EIO; + //return -EIO; } } @@ -1181,6 +1193,7 @@ static int __devinit i8042_probe(struct platform_device *dev) return error; error = i8042_controller_init(); + error = 0; //FIXME if (error) return error; @@ -1192,13 +1205,13 @@ static int __devinit i8042_probe(struct platform_device *dev) if (!i8042_noaux) { error = i8042_setup_aux(); if (error && error != -ENODEV && error != -EBUSY) - goto out_fail; + ;//goto out_fail; //FIXME } if (!i8042_nokbd) { error = i8042_setup_kbd(); if (error) - goto out_fail; + ;//goto out_fail; //FIXME } /* * Ok, everything is ready, let's register all serio ports diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index bafe340..0b9dd1a 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -634,6 +634,7 @@ struct uvc_device { /* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep; struct urb *int_urb; + __u32 padding[7]; __u8 status[16]; struct input_dev *input; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index a726f3b..bbc459a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -475,4 +475,6 @@ config SGI_GRU_DEBUG This option enables addition debugging code for the SGI GRU driver. If you are unsure, say N. +source drivers/misc/loongson/Kconfig + endif # MISC_DEVICES diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index c6c13f6..e5e29db 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -30,3 +30,4 @@ obj-$(CONFIG_KGDB_TESTS) += kgdbts.o obj-$(CONFIG_SGI_XP) += sgi-xp/ obj-$(CONFIG_SGI_GRU) += sgi-gru/ obj-$(CONFIG_HP_ILO) += hpilo.o +obj-$(CONFIG_CPU_LOONGSON2) += loongson/ diff --git a/drivers/misc/loongson/Kconfig b/drivers/misc/loongson/Kconfig new file mode 100644 index 0000000..14be4a7 --- /dev/null +++ b/drivers/misc/loongson/Kconfig @@ -0,0 +1,60 @@ +# +# Yeeloong various drivers +# +menuconfig LOONGSON2_PLATFROM_SUPPORT + bool "Loongson Platfrom Drivers Support" + depends on CPU_LOONGSON2 + default y + help + Say Y here to enable support various drivers on the loongson2 platfrom + +if LOONGSON2_PLATFROM_SUPPORT + +config EC_COMMON_OPERATION + bool "Yeeloong laptop EC common operation support" + depends on LEMOTE_2FNOTEBOOK + default y + help + Suspend code needs these operations, so buildin the kernel. + Say Y here to enable it + + +config EC_ROM_UPDATE_DRIVER + tristate "EC update driver" + depends on EC_COMMON_OPERATION + default m + help + Say Y here to enable support ec rom update driver + +config EC_SCI_DRIVER + tristate "EC SCI driver" + depends on EC_COMMON_OPERATION + default m + help + Say Y here to support ec sci event driver + +config LAPTOP_YEELOONG + tristate "Yeeloong laptop drivers" + depends on EC_COMMON_OPERATION + select BACKLIGHT_CLASS_DEVICE + select HWMON + select POWER_SUPPLY + select THERMAL + select VIDEO_OUTPUT_CONTROL + default m + help + Include backlight control,fan speed set,hardmare monitor, input event, + battery status and so on. Say Y or M here to enable it + +config BIOS_DRIVER + tristate "BIOS update driver" + select MTD + default m + help + Update yeeloong laptop BIOS driver, enable it to say M or Y +config IO_MSR_DEBUG_DRIVER + tristate "IO_MSR_DEBUG_DRIVER" + default n + help + Debug system to use wrsmr and rdmsr which used to access the CS5536. +endif #LOONGSON2_PLATFROM_SUPPORT diff --git a/drivers/misc/loongson/Makefile b/drivers/misc/loongson/Makefile new file mode 100644 index 0000000..4f01888 --- /dev/null +++ b/drivers/misc/loongson/Makefile @@ -0,0 +1,11 @@ + +# Makefile for yeeloong laptop +obj- = yeeloong.o #built-in.o + +obj-$(CONFIG_EC_SCI_DRIVER) += ec_scid.o +ec_scid-objs := ec_sci.o +obj-$(CONFIG_EC_COMMON_OPERATION) += ec_core.o +obj-$(CONFIG_EC_ROM_UPDATE_DRIVER) += ec_rom.o +obj-$(CONFIG_LAPTOP_YEELOONG) += yeeloong_laptop.o +obj-$(CONFIG_BIOS_DRIVER) += pmon_flash.o +obj-$(CONFIG_IO_MSR_DEBUG_DRIVER) += io_msr_debug.o diff --git a/drivers/misc/loongson/ec.h b/drivers/misc/loongson/ec.h new file mode 100644 index 0000000..8a17635 --- /dev/null +++ b/drivers/misc/loongson/ec.h @@ -0,0 +1,246 @@ +/* + * EC(Embedded Controller) KB3310B misc device driver header for Linux + * Author : liujl + * Date : 2008-03-14 + * + * EC relative header file. All the EC registers should be defined here. + */ + +/*****************************************************************/ + +#include +#include +#include +#include +#include + +#define VERSION "1.38t4_brightness" + +/* + * The following registers are determined by the EC index configuration. + * 1, fill the PORT_HIGH as EC register high part. + * 2, fill the PORT_LOW as EC register low part. + * 3, fill the PORT_DATA as EC register write data or get the data from it. + */ +#define EC_IO_PORT_HIGH 0x0381 +#define EC_IO_PORT_LOW 0x0382 +#define EC_IO_PORT_DATA 0x0383 + +/* ec registers range */ +#define EC_MAX_REGADDR 0xFFFF +#define EC_MIN_REGADDR 0xF000 +//#define EC_RAM_ADDR 0xF400 +#define EC_RAM_ADDR 0xF800 + +/**********************************************************************/ + +/* temperature & fan registers */ +#define REG_TEMPERATURE_VALUE 0xF458 // current temperature value +#define REG_FAN_CONTROL 0xF4D2 // fan control +#define BIT_FAN_CONTROL_ON (1 << 0) +#define BIT_FAN_CONTROL_OFF (0 << 0) +#define REG_FAN_STATUS 0xF4DA // fan status +#define BIT_FAN_STATUS_ON (1 << 0) +#define BIT_FAN_STATUS_OFF (0 << 0) +#define REG_FAN_SPEED_HIGH 0xFE22 // fan speed high byte +#define REG_FAN_SPEED_LOW 0xFE23 // fan speed low byte +#define REG_FAN_SPEED_LEVEL 0xF4E4 // fan speed level, from 1 to 5 + +/* battery registers */ +#define REG_BAT_DESIGN_CAP_HIGH 0xF77D // design capacity high byte +#define REG_BAT_DESIGN_CAP_LOW 0xF77E // design capacity low byte +#define REG_BAT_FULLCHG_CAP_HIGH 0xF780 // full charged capacity high byte +#define REG_BAT_FULLCHG_CAP_LOW 0xF781 // full charged capacity low byte +#define REG_BAT_DESIGN_VOL_HIGH 0xF782 // design voltage high byte +#define REG_BAT_DESIGN_VOL_LOW 0xF783 // design voltage low byte +#define REG_BAT_CURRENT_HIGH 0xF784 // battery in/out current high byte +#define REG_BAT_CURRENT_LOW 0xF785 // battery in/out current low byte +#define REG_BAT_VOLTAGE_HIGH 0xF786 // battery current voltage high byte +#define REG_BAT_VOLTAGE_LOW 0xF787 // battery current voltage low byte +#define REG_BAT_TEMPERATURE_HIGH 0xF788 // battery current temperature high byte +#define REG_BAT_TEMPERATURE_LOW 0xF789 // battery current temperature low byte +#define REG_BAT_RELATIVE_CAP_HIGH 0xF492 // relative capacity high byte +#define REG_BAT_RELATIVE_CAP_LOW 0xF493 // relative capacity low byte +#define REG_BAT_VENDOR 0xF4C4 // battery vendor number +#define FLAG_BAT_VENDOR_SANYO 0x01 +#define FLAG_BAT_VENDOR_SIMPLO 0x02 +#define REG_BAT_CELL_COUNT 0xF4C6 // how many cells in one battery +#define FLAG_BAT_CELL_3S1P 0x03 +#define FLAG_BAT_CELL_3S2P 0x06 +#define REG_BAT_CHARGE 0xF4A2 // macroscope battery charging +#define FLAG_BAT_CHARGE_DISCHARGE 0x01 +#define FLAG_BAT_CHARGE_CHARGE 0x02 +#define FLAG_BAT_CHARGE_ACPOWER 0x00 +#define REG_BAT_STATUS 0xF4B0 +#define BIT_BAT_STATUS_LOW (1 << 5) +#define BIT_BAT_STATUS_DESTROY (1 << 2) +#define BIT_BAT_STATUS_FULL (1 << 1) +#define BIT_BAT_STATUS_IN (1 << 0) +#define REG_BAT_CHARGE_STATUS 0xF4B1 +#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2) // over temperature +#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1) // pre-charge the battery +#define REG_BAT_STATE 0xF482 +#define BIT_BAT_STATE_CHARGING (1 << 1) +#define BIT_BAT_STATE_DISCHARGING (1 << 0) +#define REG_BAT_POWER 0xF440 +#define BIT_BAT_POWER_S3 (1 << 2) // enter s3 standby mode +#define BIT_BAT_POWER_ON (1 << 1) // system is on +#define BIT_BAT_POWER_ACIN (1 << 0) // adapter is inserted + +/* other registers */ +#define REG_AUDIO_MUTE 0xF4E7 // audio mute : rd/wr +#define BIT_AUDIO_MUTE_ON (1 << 0) +#define BIT_AUDIO_MUTE_OFF (0 << 0) +#define REG_AUDIO_BEEP 0xF4D0 // audio beep and reset : rd/wr +#define BIT_AUDIO_BEEP_ON (1 << 0) +#define BIT_AUDIO_BEEP_OFF (0 << 0) +#define REG_USB0_FLAG 0xF461 // usb0 port power or not : rd/wr +#define BIT_USB0_FLAG_ON (1 << 0) +#define BIT_USB0_FLAG_OFF (0 << 0) +#define REG_USB1_FLAG 0xF462 // usb1 port power or not : rd/wr +#define BIT_USB1_FLAG_ON (1 << 0) +#define BIT_USB1_FLAG_OFF (0 << 0) +#define REG_USB2_FLAG 0xF463 // usb2 port power or not : rd/wr +#define BIT_USB2_FLAG_ON (1 << 0) +#define BIT_USB2_FLAG_OFF (0 << 0) +#define REG_CRT_DETECT 0xF4AD // detected CRT exist or not +#define BIT_CRT_DETECT_PLUG (1 << 0) +#define BIT_CRT_DETECT_UNPLUG (0 << 0) +#define REG_LID_DETECT 0xF4BD // detected LID is on or not +#define BIT_LID_DETECT_ON (1 << 0) // 1:LID open (availability) +#define BIT_LID_DETECT_OFF (0 << 0) // 0:LID close(invalidation) +#define REG_RESET 0xF4EC // reset the machine auto-clear : rd/wr +#define BIT_RESET_ON (1 << 0) +#define BIT_RESET_OFF (0 << 0) +#define REG_LED 0xF4C8 // light the led : rd/wr +#define BIT_LED_RED_POWER (1 << 0) +#define BIT_LED_ORANGE_POWER (1 << 1) +#define BIT_LED_GREEN_CHARGE (1 << 2) +#define BIT_LED_RED_CHARGE (1 << 3) +#define BIT_LED_NUMLOCK (1 << 4) +#define REG_LED_TEST 0xF4C2 // test led mode, all led on or off +#define BIT_LED_TEST_IN (1 << 0) +#define BIT_LED_TEST_OUT (0 << 0) +#define REG_DISPLAY_BRIGHTNESS 0xF4F5 //9 stages LCD backlight brightness adjust +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_0 0 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_1 1 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_2 2 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_3 3 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_4 4 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_5 5 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_6 6 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_7 7 +#define FLAG_DISPLAY_BRIGHTNESS_LEVEL_8 8 +#define REG_CAMERA_STATUS 0xF46A //camera is in ON/OFF status. +#define BIT_CAMERA_STATUS_ON (1 << 0) +#define BIT_CAMERA_STATUS_OFF (0 << 0) +#define REG_CAMERA_CONTROL 0xF7B7 //control camera to ON/OFF. +#define BIT_CAMERA_CONTROL_OFF (1 << 1) +#define BIT_CAMERA_CONTROL_ON (1 << 1) +#define REG_AUDIO_VOLUME 0xF46C //The register to show volume level +#define FLAG_AUDIO_VOLUME_LEVEL_0 0 +#define FLAG_AUDIO_VOLUME_LEVEL_1 1 +#define FLAG_AUDIO_VOLUME_LEVEL_2 2 +#define FLAG_AUDIO_VOLUME_LEVEL_3 3 +#define FLAG_AUDIO_VOLUME_LEVEL_4 4 +#define FLAG_AUDIO_VOLUME_LEVEL_5 5 +#define FLAG_AUDIO_VOLUME_LEVEL_6 6 +#define FLAG_AUDIO_VOLUME_LEVEL_7 7 +#define FLAG_AUDIO_VOLUME_LEVEL_8 8 +#define FLAG_AUDIO_VOLUME_LEVEL_9 9 +#define FLAG_AUDIO_VOLUME_LEVEL_10 0x0A +#define REG_WLAN_STATUS 0xF4FA //Wlan Status +#define BIT_WLAN_STATUS_ON (1 << 0) +#define BIT_WLAN_STATUS_OFF (0 << 0) +#define REG_DISPLAY_LCD 0xF79F //Black screen Status +#define BIT_DISPLAY_LCD_ON (1 << 0) +#define BIT_DISPLAY_LCD_OFF (0 << 0) +#define REG_BACKLIGHT_CTRL 0xF7BD //LCD backlight control: off/restore +#define BIT_BACKLIGHT_ON (1 << 0) +#define BIT_BACKLIGHT_OFF (0 << 0) + +/***********************************************************/ + +/* SCI Event Number from EC */ +#define SCI_EVENT_NUM_LID 0x23 // press the lid or not +#define SCI_EVENT_NUM_DISPLAY_TOGGLE 0x24 // Fn+F3 for display switch +#define SCI_EVENT_NUM_SLEEP 0x25 // Fn+F1 for entering sleep mode +#define SCI_EVENT_NUM_OVERTEMP 0x26 // Over-temperature happened +#define SCI_EVENT_NUM_CRT_DETECT 0x27 // CRT is connected +#define SCI_EVENT_NUM_CAMERA 0x28 // Camera is on or off +#define SCI_EVENT_NUM_USB_OC2 0x29 // USB2 Over Current occurred +#define SCI_EVENT_NUM_USB_OC0 0x2A // USB0 Over Current occurred +#define SCI_EVENT_NUM_AC_BAT 0x2E // ac & battery relative issue +#define BIT_AC_BAT_BAT_IN 0 +#define BIT_AC_BAT_AC_IN 1 +#define BIT_AC_BAT_INIT_CAP 2 +#define BIT_AC_BAT_CHARGE_MODE 3 +#define BIT_AC_BAT_STOP_CHARGE 4 +#define BIT_AC_BAT_BAT_LOW 5 +#define BIT_AC_BAT_BAT_FULL 6 +#define SCI_EVENT_NUM_DISPLAY_BRIGHTNESS 0x2D // LCD backlight brightness adjust +#define SCI_EVENT_NUM_AUDIO_VOLUME 0x2F // Volume adjust +#define SCI_EVENT_NUM_WLAN 0x30 // Wlan is on or off +#define SCI_EVENT_NUM_AUDIO_MUTE 0x2C // Mute is on or off +#define SCI_EVENT_NUM_BLACK_SCREEN 0x2B // Black screen is on or off + +#define SCI_INDEX_LID 0x00 +#define SCI_INDEX_DISPLAY_TOGGLE 0x01 +#define SCI_INDEX_SLEEP 0x02 +#define SCI_INDEX_OVERTEMP 0x03 +#define SCI_INDEX_CRT_DETECT 0x04 +#define SCI_INDEX_CAMERA 0x05 +#define SCI_INDEX_USB_OC2 0x06 +#define SCI_INDEX_USB_OC0 0x07 +#define SCI_INDEX_AC_BAT 0x08 +#define SCI_INDEX_DISPLAY_BRIGHTNESS_INC 0x09 +#define SCI_INDEX_DISPLAY_BRIGHTNESS_DEC 0x0A +#define SCI_INDEX_AUDIO_VOLUME_INC 0x0B +#define SCI_INDEX_AUDIO_VOLUME_DEC 0x0C +#define SCI_INDEX_WLAN 0x0D +#define SCI_INDEX_AUDIO_MUTE 0x0E +#define SCI_INDEX_BLACK_SCREEN 0x0F + +#define SCI_MAX_EVENT_COUNT 0x10 + +/* EC access port for sci communication */ +#define EC_CMD_PORT 0x66 +#define EC_STS_PORT 0x66 +#define EC_DAT_PORT 0x62 +#define CMD_INIT_IDLE_MODE 0xdd +#define CMD_EXIT_IDLE_MODE 0xdf +#define CMD_INIT_RESET_MODE 0xd8 +#define CMD_REBOOT_SYSTEM 0x8c +#define CMD_GET_EVENT_NUM 0x84 +#define CMD_PROGRAM_PIECE 0xda + + +/**********************************************************************/ +//#define DEBUG_PRINTK + +#ifdef DEBUG_PRINTK +#define PRINTK_DBG(args...) printk(args) +#else +#define PRINTK_DBG(args...) +#endif + +extern void _rdmsr(u32 addr, u32 *hi, u32 *lo); +extern void _wrmsr(u32 addr, u32 hi, u32 lo); +typedef int (*ec_handler)(void); +/****************************************************************/ +#if CONFIG_EC_COMMON_OPERATION +/* the general ec index-io port read action */ +extern unsigned char ec_read(unsigned short addr); +/* the general ec index-io port write action */ +extern void ec_write(unsigned short addr, unsigned char val); +/* query sequence of 62/66 port access routine */ +extern int ec_query_seq(unsigned char cmd); +extern int sci_get_event_num(void); +extern void ec_handler_install(int event_nu, ec_handler irq_handler); +extern void ec_handler_uninstall(int event_nu); +#else +static inline unsigned char ec_read(unsigned short addr){} +static inline void ec_write(unsigned short addr, unsigned char varl){} +//static inline int ec_query_seq(unsigned char cmd){} +//static inline int sci_get_event_num(void){} +#endif diff --git a/drivers/misc/loongson/ec_core.c b/drivers/misc/loongson/ec_core.c new file mode 100644 index 0000000..702617e --- /dev/null +++ b/drivers/misc/loongson/ec_core.c @@ -0,0 +1,131 @@ +/****************************************************************** + * EC chip common operations: + * ec_read(), ec_write(), ec_query_seq(), sci_get_event_num() + * Copy from the ec_misc.c and ec_sci.c + ******************************************************************/ + +#include +#include + +#include "ec.h" +#include "ec_rom.h" +/*******************************************************************/ + +/* this spinlock is dedicated for ec_read & ec_write function */ +DEFINE_SPINLOCK(index_access_lock); +/* this spinlock is dedicated for 62&66 ports access */ +DEFINE_SPINLOCK(port_access_lock); + +/*******************************************************************/ + +/* read a byte from EC registers throught index-io */ +unsigned char ec_read(unsigned short addr) +{ + unsigned char value; + unsigned long flags; + + spin_lock_irqsave(&index_access_lock, flags); + outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); + outb((addr & 0x00ff), EC_IO_PORT_LOW); + value = inb(EC_IO_PORT_DATA); + spin_unlock_irqrestore(&index_access_lock, flags); + + return value; +} +EXPORT_SYMBOL_GPL(ec_read); + +/* write a byte to EC registers throught index-io */ +void ec_write(unsigned short addr, unsigned char val) +{ + unsigned long flags; + + spin_lock_irqsave(&index_access_lock, flags); + outb( (addr & 0xff00) >> 8, EC_IO_PORT_HIGH ); + outb( (addr & 0x00ff), EC_IO_PORT_LOW ); + outb( val, EC_IO_PORT_DATA ); + inb( EC_IO_PORT_DATA ); // flush the write action + spin_unlock_irqrestore(&index_access_lock, flags); + + return; +} +EXPORT_SYMBOL_GPL(ec_write); + +/* + * ec_query_seq + * this function is used for ec command writing and the corresponding status query + */ +int ec_query_seq(unsigned char cmd) +{ + int timeout; + unsigned char status; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&port_access_lock, flags); + + /* make chip goto reset mode */ + udelay(EC_REG_DELAY); + outb(cmd, EC_CMD_PORT); + udelay(EC_REG_DELAY); + + /* check if the command is received by ec */ + timeout = EC_CMD_TIMEOUT; + status = inb(EC_STS_PORT); + while(timeout--){ + if(status & (1 << 1)){ + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + continue; + } + break; + } + + if(timeout <= 0){ + printk(KERN_ERR "EC QUERY SEQ : deadable error : timeout...\n"); + ret = -EINVAL; + }else{ + PRINTK_DBG(KERN_INFO "(%x/%d)ec issued command %x status : 0x%x\n", timeout, EC_CMD_TIMEOUT - timeout, cmd, status); + } + + spin_unlock_irqrestore(&port_access_lock, flags); + + return ret; +} + +EXPORT_SYMBOL_GPL(ec_query_seq); + + +/* + * sci_get_event_num : + * get sci event number from ec + * NOTE : this routine must follow the sci_query_event_num + * function in the interrupt + */ +int sci_get_event_num(void) +{ + int timeout = 100; + unsigned char value; + unsigned char status; + + udelay(EC_REG_DELAY); + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + while(timeout--){ + if(!(status & (1 << 0))){ + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + continue; + } + break; + } + if(timeout <= 0){ + PRINTK_DBG("fixup sci : get event number timeout.\n"); + return -EINVAL; + } + value = inb(EC_DAT_PORT); + udelay(EC_REG_DELAY); + + return value; +} + +EXPORT_SYMBOL(sci_get_event_num); diff --git a/drivers/misc/loongson/ec_rom.c b/drivers/misc/loongson/ec_rom.c new file mode 100644 index 0000000..213a312 --- /dev/null +++ b/drivers/misc/loongson/ec_rom.c @@ -0,0 +1,837 @@ +/* + * EC(Embedded Controller) KB3310B misc device driver on Linux + * Author : liujl + * Date : 2008-04-20 + * + * NOTE : + * 1, The EC resources accessing and programming are supported. + */ + +/*******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ec.h" +#include "ec_rom.h" + +/*******************************************************************/ +/* open for using rom protection action */ +#define EC_ROM_PROTECTION + +/* information used for programming */ +struct ec_info ecinfo; +/************************************************************************/ + +/* enable the chip reset mode */ +static int ec_init_reset_mode(void) +{ + int timeout; + unsigned char status = 0; + int ret = 0; + + /* make chip goto reset mode */ + ret = ec_query_seq(CMD_INIT_RESET_MODE); + if(ret < 0){ + printk(KERN_ERR "ec init reset mode failed.\n"); + goto out; + } + + /* make the action take active */ + timeout = EC_CMD_TIMEOUT; + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE; + while(timeout--){ + if(status){ + udelay(EC_REG_DELAY); + break; + } + status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE; + udelay(EC_REG_DELAY); + } + if(timeout <= 0){ + printk(KERN_ERR "ec rom fixup : can't check reset status.\n"); + ret = -EINVAL; + }else{ + PRINTK_DBG(KERN_INFO "(%d/%d)reset 0xf710 : 0x%x\n", timeout, EC_CMD_TIMEOUT - timeout, status); + } + + /* set MCU to reset mode */ + udelay(EC_REG_DELAY); + status = ec_read(REG_PXCFG); + status |= (1 << 0); + ec_write(REG_PXCFG, status); + udelay(EC_REG_DELAY); + + /* disable FWH/LPC */ + udelay(EC_REG_DELAY); + status = ec_read(REG_LPCCFG); + status &= ~(1 << 7); + ec_write(REG_LPCCFG, status); + udelay(EC_REG_DELAY); + + PRINTK_DBG(KERN_INFO "entering reset mode ok..............\n"); + +out : + return ret; +} + +/* make ec exit from reset mode */ +static void ec_exit_reset_mode(void) +{ + unsigned char regval; + + udelay(EC_REG_DELAY); + regval = ec_read(REG_LPCCFG); + regval |= (1 << 7); + ec_write(REG_LPCCFG, regval); + regval = ec_read(REG_PXCFG); + regval &= ~(1 << 0); + ec_write(REG_PXCFG, regval); + PRINTK_DBG(KERN_INFO "exit reset mode ok..................\n"); + + return; +} +/* make ec disable WDD */ +static void ec_disable_WDD(void) +{ + unsigned char status; + + udelay(EC_REG_DELAY); + status = ec_read(REG_WDTCFG); + ec_write(REG_WDTPF, 0x03); + ec_write(REG_WDTCFG, (status&0x80)|0x48); + PRINTK_DBG(KERN_INFO "Disable WDD ok..................\n"); + + return; +} + +/* make ec enable WDD */ +static void ec_enable_WDD(void) +{ + unsigned char status; + + udelay(EC_REG_DELAY); + status = ec_read(REG_WDTCFG); + ec_write(REG_WDT, 0x28); //set WDT 5sec(0x28) + ec_write(REG_WDTCFG, (status&0x80)|0x03); + PRINTK_DBG(KERN_INFO "Enable WDD ok..................\n"); + + return; +} + +#if 0 +/* re-power the whole system for new ec firmware working correctly. */ +static void ec_reboot_system(void) +{ + ec_query_seq(CMD_REBOOT_SYSTEM); + printk(KERN_INFO "reboot system...................\n"); +} +#endif + +/* make ec goto idle mode */ +static int ec_init_idle_mode(void) +{ + int timeout; + unsigned char status = 0; + int ret = 0; + + ec_query_seq(CMD_INIT_IDLE_MODE); + + /* make the action take active */ + timeout = EC_CMD_TIMEOUT; + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE; + while(timeout--){ + if(status){ + udelay(EC_REG_DELAY); + break; + } + status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE; + udelay(EC_REG_DELAY); + } + if(timeout <= 0){ + printk(KERN_ERR "ec rom fixup : can't check out the status.\n"); + ret = -EINVAL; + }else{ + PRINTK_DBG(KERN_INFO "(%d/%d)0xf710 : 0x%x\n", timeout, EC_CMD_TIMEOUT - timeout, ec_read(REG_POWER_MODE)); + } + + PRINTK_DBG(KERN_INFO "entering idle mode ok...................\n"); + + return ret; +} + +/* make ec exit from idle mode */ +static int ec_exit_idle_mode(void) +{ + + ec_query_seq(CMD_EXIT_IDLE_MODE); + + PRINTK_DBG(KERN_INFO "exit idle mode ok...................\n"); + + return 0; +} + +/**********************************************************************/ + +static int ec_instruction_cycle(void) +{ + unsigned long timeout; + int ret = 0; + + timeout = EC_FLASH_TIMEOUT; + while(timeout-- >= 0){ + if( !(ec_read(REG_XBISPICFG) & SPICFG_SPI_BUSY) ) + break; + } + if(timeout <= 0){ + printk(KERN_ERR "EC_INSTRUCTION_CYCLE : timeout for check flag.\n"); + ret = -EINVAL; + goto out; + } + +out : + return ret; +} + +/* To see if the ec is in busy state or not. */ +static inline int ec_flash_busy(unsigned long timeout) +{ + /* assurance the first command be going to rom */ + if( ec_instruction_cycle() < 0 ){ + return EC_STATE_BUSY; + } + +#if 1 + timeout = timeout / EC_MAX_DELAY_UNIT; + while(timeout-- > 0){ + /* check the rom's status of busy flag */ + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS); + if( ec_instruction_cycle() < 0 ){ + return EC_STATE_BUSY; + } + if((ec_read(REG_XBISPIDAT) & 0x01) == 0x00){ + return EC_STATE_IDLE; + } + udelay(EC_MAX_DELAY_UNIT); + } + if( timeout <= 0 ){ + printk(KERN_ERR "EC_FLASH_BUSY : timeout for check rom flag.\n"); + return EC_STATE_BUSY; + } +#else + /* check the rom's status of busy flag */ + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS); + if( ec_instruction_cycle() < 0 ){ + return EC_STATE_BUSY; + } + + timeout = timeout / EC_MAX_DELAY_UNIT; + while(timeout-- > 0){ + if((ec_read(REG_XBISPIDAT) & 0x01) == 0x00){ + return EC_STATE_IDLE; + } + udelay(EC_MAX_DELAY_UNIT); + } + if( timeout <= 0 ){ + printk(KERN_ERR "EC_FLASH_BUSY : timeout for check rom flag.\n"); + return EC_STATE_BUSY; + } +#endif + + return EC_STATE_IDLE; +} + +static int rom_instruction_cycle(unsigned char cmd) +{ + unsigned long timeout = 0; + + switch(cmd){ + case SPICMD_READ_STATUS : + case SPICMD_WRITE_ENABLE : + case SPICMD_WRITE_DISABLE : + case SPICMD_READ_BYTE : + case SPICMD_HIGH_SPEED_READ : + timeout = 0; + break; + case SPICMD_WRITE_STATUS : + timeout = 300 * 1000; + break; + case SPICMD_BYTE_PROGRAM : + timeout = 5 * 1000; + break; + case SPICMD_SST_SEC_ERASE : + case SPICMD_SEC_ERASE : + timeout = 1000 * 1000; + break; + case SPICMD_SST_BLK_ERASE : + case SPICMD_BLK_ERASE : + timeout = 3 * 1000 * 1000; + break; + case SPICMD_SST_CHIP_ERASE : + case SPICMD_CHIP_ERASE : + timeout = 20 * 1000 * 1000; + break; + default : + timeout = EC_SPICMD_STANDARD_TIMEOUT; + } + if(timeout == 0){ + return ec_instruction_cycle(); + } + if(timeout < EC_SPICMD_STANDARD_TIMEOUT) + timeout = EC_SPICMD_STANDARD_TIMEOUT; + + return ec_flash_busy(timeout); +} + +/* delay for start/stop action */ +static void delay_spi(int n) +{ + while(n--) + inb(EC_IO_PORT_HIGH); +} + +/* start the action to spi rom function */ +static void ec_start_spi(void) +{ + unsigned char val; + + delay_spi(SPI_FINISH_WAIT_TIME); + val = ec_read(REG_XBISPICFG) | SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK; + ec_write(REG_XBISPICFG, val); + delay_spi(SPI_FINISH_WAIT_TIME); +} + +/* stop the action to spi rom function */ +static void ec_stop_spi(void) +{ + unsigned char val; + + delay_spi(SPI_FINISH_WAIT_TIME); + val = ec_read(REG_XBISPICFG) & (~(SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK)); + ec_write(REG_XBISPICFG, val); + delay_spi(SPI_FINISH_WAIT_TIME); +} + +/* read one byte from xbi interface */ +static int ec_read_byte(unsigned int addr, unsigned char *byte) +{ + int ret = 0; + + /* enable spicmd writing. */ + ec_start_spi(); + + /* enable write spi flash */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE); + if(rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_READ_BYTE : SPICMD_WRITE_ENABLE failed.\n"); + ret = -EINVAL; + goto out; + } + + /* write the address */ + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16); + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8); + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0); + /* start action */ + ec_write(REG_XBISPICMD, SPICMD_HIGH_SPEED_READ); + if(rom_instruction_cycle(SPICMD_HIGH_SPEED_READ) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_READ_BYTE : SPICMD_HIGH_SPEED_READ failed.\n"); + ret = -EINVAL; + goto out; + } + + *byte = ec_read(REG_XBISPIDAT); + +out : + /* disable spicmd writing. */ + ec_stop_spi(); + + return ret; +} + +/* write one byte to ec rom */ +static int ec_write_byte(unsigned int addr, unsigned char byte) +{ + int ret = 0; + + /* enable spicmd writing. */ + ec_start_spi(); + + /* enable write spi flash */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE); + if(rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_WRITE_BYTE : SPICMD_WRITE_ENABLE failed.\n"); + ret = -EINVAL; + goto out; + } + + /* write the address */ + ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16); + ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8); + ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0); + ec_write(REG_XBISPIDAT, byte); + /* start action */ + ec_write(REG_XBISPICMD, SPICMD_BYTE_PROGRAM); + if(rom_instruction_cycle(SPICMD_BYTE_PROGRAM) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_WRITE_BYTE : SPICMD_BYTE_PROGRAM failed.\n"); + ret = -EINVAL; + goto out; + } + +out : + /* disable spicmd writing. */ + ec_stop_spi(); + + return ret; +} + +/* unprotect SPI ROM */ +/* EC_ROM_unprotect function code */ +static int EC_ROM_unprotect(void) +{ + unsigned char status; + + /* enable write spi flash */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE); + if(rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n"); + return 1; + } + + /* unprotect the status register of rom */ + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS); + if(rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_READ_STATUS failed.\n"); + return 1; + } + status = ec_read(REG_XBISPIDAT); + ec_write(REG_XBISPIDAT, status & 0x02); + if(ec_instruction_cycle() < 0){ + printk(KERN_ERR "EC_UNIT_ERASE : write status value failed.\n"); + return 1; + } + + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS); + if(rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_WRITE_STATUS failed.\n"); + return 1; + } + + /* enable write spi flash */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE); + if(rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n"); + return 1; + } + + return 0; +} + +/* erase one block or chip or sector as needed */ +static int ec_unit_erase(unsigned char erase_cmd, unsigned int addr) +{ + unsigned char status; + int ret = 0, i = 0; + int unprotect_count = 3; + int check_flag =0; + + /* enable spicmd writing. */ + ec_start_spi(); + +#ifdef EC_ROM_PROTECTION + /* added for re-check SPICMD_READ_STATUS */ + while(unprotect_count-- > 0){ + if(EC_ROM_unprotect()){ + ret = -EINVAL; + goto out; + } + + for(i = 0; i < ((2 - unprotect_count) * 100 + 10); i++) //first time:500ms --> 5.5sec -->10.5sec + udelay(50000); + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS); + if(rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n"); + } else { + status = ec_read(REG_XBISPIDAT); + PRINTK_DBG(KERN_INFO "Read unprotect status : 0x%x\n", status); + if((status & 0x1C) == 0x00){ + PRINTK_DBG(KERN_INFO "Read unprotect status OK1 : 0x%x\n", status & 0x1C); + check_flag = 1; + break; + } + } + } + + if(!check_flag){ + printk(KERN_INFO "SPI ROM unprotect fail.\n"); + return 1; + } +#endif + + /* block address fill */ + if(erase_cmd == SPICMD_BLK_ERASE){ + ec_write(REG_XBISPIA2, (addr & 0x00ff0000) >> 16); + ec_write(REG_XBISPIA1, (addr & 0x0000ff00) >> 8); + ec_write(REG_XBISPIA0, (addr & 0x000000ff) >> 0); + } + + /* erase the whole chip first */ + ec_write(REG_XBISPICMD, erase_cmd); + if(rom_instruction_cycle(erase_cmd) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_UNIT_ERASE : erase failed.\n"); + ret = -EINVAL; + goto out; + } + +out : + /* disable spicmd writing. */ + ec_stop_spi(); + + return ret; +} + +/* update the whole rom content with H/W mode + * PLEASE USING ec_unit_erase() FIRSTLY + */ +static int ec_program_rom(struct ec_info *info, int flag) +{ + unsigned int addr = 0; + unsigned long size = 0; + unsigned char *ptr = NULL; + unsigned char data; + unsigned char val = 0; + int ret = 0; + int i, j; + unsigned char status; + + /* modify for program serial No, set IE_START_ADDR and use idle mode, disable WDD */ + if (flag == PROGRAM_FLAG_ROM) { + ret = ec_init_reset_mode(); + addr = info->start_addr + EC_START_ADDR; + PRINTK_DBG(KERN_INFO "PROGRAM_FLAG_ROM..............\n"); + } else if (flag == PROGRAM_FLAG_IE) { + ret = ec_init_idle_mode(); + ec_disable_WDD(); + //addr = info->start_addr + IE_START_ADDR; //huangw 09-09-11 + addr = info->start_addr; + PRINTK_DBG(KERN_INFO "PROGRAM_FLAG_IE..............\n"); + } else { + return 0; + } + + if(ret < 0){ + if (flag == PROGRAM_FLAG_IE) + ec_enable_WDD(); + return ret; + } + + size = info->size; + ptr = info->buf; + PRINTK_DBG(KERN_INFO "starting update ec ROM..............\n"); + + ret = ec_unit_erase(SPICMD_BLK_ERASE, addr); + if(ret){ + printk(KERN_ERR "program ec : erase block failed.\n"); + goto out; + } + PRINTK_DBG(KERN_ERR "program ec : erase block OK.\n"); + + i = 0; + while(i < size){ + data = *(ptr + i); + ec_write_byte(addr, data); + ec_read_byte(addr, &val); + if(val != data){ + ec_write_byte(addr, data); + ec_read_byte(addr, &val); + if(val != data){ + printk("EC : Second flash program failed at:\t"); + printk("addr : 0x%x, source : 0x%x, dest: 0x%x\n", addr, data, val); + printk("This should not happened... STOP\n"); + break; + } + } + i++; + addr++; + } + +#ifdef EC_ROM_PROTECTION + /* we should start spi access firstly */ + ec_start_spi(); + + /* enable write spi flash */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE); + if(rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_PROGRAM_ROM : SPICMD_WRITE_ENABLE failed.\n"); + goto out1; + } + + /* protect the status register of rom */ + ec_write(REG_XBISPICMD, SPICMD_READ_STATUS); + if(rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n"); + goto out1; + } + status = ec_read(REG_XBISPIDAT); + + ec_write(REG_XBISPIDAT, status | 0x1C); + if(ec_instruction_cycle() < 0){ + printk(KERN_ERR "EC_PROGRAM_ROM : write status value failed.\n"); + goto out1; + } + + ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS); + if(rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_PROGRAM_ROM : SPICMD_WRITE_STATUS failed.\n"); + goto out1; + } +#endif + + /* disable the write action to spi rom */ + ec_write(REG_XBISPICMD, SPICMD_WRITE_DISABLE); + if(rom_instruction_cycle(SPICMD_WRITE_DISABLE) == EC_STATE_BUSY){ + printk(KERN_ERR "EC_PROGRAM_ROM : SPICMD_WRITE_DISABLE failed.\n"); + goto out1; + } + +out1: + /* we should stop spi access firstly */ + ec_stop_spi(); +out: + /* for security */ + for(j = 0; j < 2000; j++) + udelay(1000); + + /* modify for program serial No, after program No exit idle mode and enable WDD */ + if (flag == PROGRAM_FLAG_ROM) { + /* exit from the reset mode */ + ec_exit_reset_mode(); + } else { + /* ec exit from idle mode */ + ret = ec_exit_idle_mode(); + ec_enable_WDD(); + if(ret < 0){ + return ret; + } + } + + return 0; +} + +/******************************************************************************/ + +/* ioctl */ +static int misc_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) +{ + void __user *ptr = (void __user *)arg; + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data); + int ret = 0; + + switch (cmd) { + case IOCTL_RDREG : + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg)); + if(ret){ + printk(KERN_ERR "reg read : copy from user error.\n"); + return -EFAULT; + } + if( (ecreg->addr > EC_MAX_REGADDR) || (ecreg->addr < EC_MIN_REGADDR) ){ + printk(KERN_ERR "reg read : out of register address range.\n"); + return -EINVAL; + } + ecreg->val = ec_read(ecreg->addr); + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg)); + if(ret){ + printk(KERN_ERR "reg read : copy to user error.\n"); + return -EFAULT; + } + break; + case IOCTL_WRREG : + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg)); + if(ret){ + printk(KERN_ERR "reg write : copy from user error.\n"); + return -EFAULT; + } + if( (ecreg->addr > EC_MAX_REGADDR) || (ecreg->addr < EC_MIN_REGADDR) ){ + printk(KERN_ERR "reg write : out of register address range.\n"); + return -EINVAL; + } + ec_write(ecreg->addr, ecreg->val); + break; + case IOCTL_READ_EC : + ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg)); + if(ret){ + printk(KERN_ERR "spi read : copy from user error.\n"); + return -EFAULT; + } + if( (ecreg->addr > EC_RAM_ADDR) && (ecreg->addr < EC_MAX_REGADDR) ){ + printk(KERN_ERR "spi read : out of register address range.\n"); + return -EINVAL; + } + ec_read_byte(ecreg->addr, &(ecreg->val)); + ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg)); + if(ret){ + printk(KERN_ERR "spi read : copy to user error.\n"); + return -EFAULT; + } + break; + case IOCTL_PROGRAM_IE : + if( get_user((ecinfo.start_addr), (u32 *)ptr) ){ + printk(KERN_ERR "program ie : get user start_addr error.\n"); + return -EFAULT; + } + ecinfo.size = EC_CONTENT_MAX_SIZE; + + ecinfo.buf = (u8 *)kmalloc(ecinfo.size, GFP_KERNEL); + if(ecinfo.buf == NULL){ + printk(KERN_ERR "program ie : kmalloc failed.\n"); + return -ENOMEM; + } + + ret = copy_from_user(ecinfo.buf, (u8 *)ptr + 4, ecinfo.size); + if(ret){ + printk(KERN_ERR "program ie : copy from user error.\n"); + kfree(ecinfo.buf); + ecinfo.buf = NULL; + return -EFAULT; + } + + if(ecinfo.start_addr == RESVEC_START_ADDR){ + printk("start address : 0x%x\n", ecinfo.start_addr); + printk("sum size : 0x%x\n", ecinfo.size); + printk("backup ec ver : %c%c%c%c%c%c\n", ecinfo.buf[0xFFFA], ecinfo.buf[0xFFFB], ecinfo.buf[0xFFFC], + ecinfo.buf[0xFFFD], ecinfo.buf[0xFFFE], ecinfo.buf[0xFFFF]); + printk("backup ec size: 0x%x%x%x%x\n", ecinfo.buf[0xFFF9], ecinfo.buf[0xFFF8], + ecinfo.buf[0xFFF7], ecinfo.buf[0xFFF6]); + } + + /* use ec_program_rom to write serial No */ + ec_program_rom(&ecinfo, PROGRAM_FLAG_IE); + + kfree(ecinfo.buf); + ecinfo.buf = NULL; + break; + case IOCTL_PROGRAM_EC : + ecinfo.start_addr = EC_START_ADDR; + if(get_user( (ecinfo.size), (u32 *)ptr) ){ + printk(KERN_ERR "program ec : get user error.\n"); + return -EFAULT; + } + if( (ecinfo.size) > EC_CONTENT_MAX_SIZE ){ + printk(KERN_ERR "program ec : size out of limited.\n"); + return -EINVAL; + } + ecinfo.buf = (u8 *)kmalloc(ecinfo.size, GFP_KERNEL); + if(ecinfo.buf == NULL){ + printk(KERN_ERR "program ec : kmalloc failed.\n"); + return -ENOMEM; + } + ret = copy_from_user(ecinfo.buf, ((u8 *)ptr + 4), ecinfo.size); + if(ret){ + printk(KERN_ERR "program ec : copy from user error.\n"); + kfree(ecinfo.buf); + ecinfo.buf = NULL; + return -EFAULT; + } + + ec_program_rom(&ecinfo, PROGRAM_FLAG_ROM); + + kfree(ecinfo.buf); + ecinfo.buf = NULL; + break; + + default : + break; + } + + return 0; +} + +static long misc_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return misc_ioctl(file->f_dentry->d_inode, file, cmd, arg); +} + +static int misc_open(struct inode * inode, struct file * filp) +{ + struct ec_reg *ecreg = NULL; + ecreg = kmalloc(sizeof(struct ec_reg), GFP_KERNEL); + if (ecreg) { + filp->private_data = ecreg; + } + + return ecreg ? 0 : -ENOMEM; +} + +static int misc_release(struct inode * inode, struct file * filp) +{ + struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data); + + filp->private_data = NULL; + kfree(ecreg); + + return 0; +} + +static struct file_operations ecmisc_fops = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) + .owner = THIS_MODULE, +#endif + .open = misc_open, + .release = misc_release, + .read = NULL, + .write = NULL, +#ifdef CONFIG_64BIT + .compat_ioctl = misc_compat_ioctl, +#else + .ioctl = misc_ioctl, +#endif +}; + +/*********************************************************/ + +static struct miscdevice ecmisc_device = { + .minor = ECMISC_MINOR_DEV, + .name = EC_MISC_DEV, + .fops = &ecmisc_fops +}; + +static int __init ecmisc_init(void) +{ + int ret; + + printk(KERN_INFO "EC misc device init.\n"); + ret = misc_register(&ecmisc_device); + + return ret; +} + +static void __exit ecmisc_exit(void) +{ + printk(KERN_INFO "EC misc device exit.\n"); + misc_deregister(&ecmisc_device); +} + +module_init(ecmisc_init); +module_exit(ecmisc_exit); + +MODULE_AUTHOR("liujl "); +MODULE_DESCRIPTION("KB3310 resources misc Management"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/loongson/ec_rom.h b/drivers/misc/loongson/ec_rom.h new file mode 100644 index 0000000..51c404f --- /dev/null +++ b/drivers/misc/loongson/ec_rom.h @@ -0,0 +1,190 @@ +/* + * EC(Embedded Controller) KB3310B Misc device driver header file in linux + * Author : liujl + * Date : 2008-04-20 + * + * NOTE : + * 1, The application layer for reading, writing ec registers and code + * program are supported. + */ + +/***********************************************************/ +/* ec delay time 500us for register and status access */ +#define EC_REG_DELAY 500 //unit : us + +/* version burned address */ +#define VER_ADDR 0xf7a1 +#define VER_MAX_SIZE 7 +#define EC_ROM_MAX_SIZE 0x10000 + +/* ec internal register */ +#define REG_POWER_MODE 0xF710 +#define FLAG_NORMAL_MODE 0x00 +#define FLAG_IDLE_MODE 0x01 +#define FLAG_RESET_MODE 0x02 + +/* ec update program flag */ +#define PROGRAM_FLAG_NONE 0x00 +#define PROGRAM_FLAG_IE 0x01 +#define PROGRAM_FLAG_ROM 0x02 + +/* XBI relative registers */ +#define REG_XBISEG0 0xFEA0 +#define REG_XBISEG1 0xFEA1 +#define REG_XBIRSV2 0xFEA2 +#define REG_XBIRSV3 0xFEA3 +#define REG_XBIRSV4 0xFEA4 +#define REG_XBICFG 0xFEA5 +#define REG_XBICS 0xFEA6 +#define REG_XBIWE 0xFEA7 +#define REG_XBISPIA0 0xFEA8 +#define REG_XBISPIA1 0xFEA9 +#define REG_XBISPIA2 0xFEAA +#define REG_XBISPIDAT 0xFEAB +#define REG_XBISPICMD 0xFEAC +#define REG_XBISPICFG 0xFEAD +#define REG_XBISPIDATR 0xFEAE +#define REG_XBISPICFG2 0xFEAF + +/* commands definition for REG_XBISPICMD */ +#define SPICMD_WRITE_STATUS 0x01 +#define SPICMD_BYTE_PROGRAM 0x02 +#define SPICMD_READ_BYTE 0x03 +#define SPICMD_WRITE_DISABLE 0x04 +#define SPICMD_READ_STATUS 0x05 +#define SPICMD_WRITE_ENABLE 0x06 +#define SPICMD_HIGH_SPEED_READ 0x0B +#define SPICMD_POWER_DOWN 0xB9 +#define SPICMD_SST_EWSR 0x50 +#define SPICMD_SST_SEC_ERASE 0x20 +#define SPICMD_SST_BLK_ERASE 0x52 +#define SPICMD_SST_CHIP_ERASE 0x60 +#define SPICMD_FRDO 0x3B +#define SPICMD_SEC_ERASE 0xD7 +#define SPICMD_BLK_ERASE 0xD8 +#define SPICMD_CHIP_ERASE 0xC7 + +/* bits definition for REG_XBISPICFG */ +#define SPICFG_AUTO_CHECK 0x01 +#define SPICFG_SPI_BUSY 0x02 +#define SPICFG_DUMMY_READ 0x04 +#define SPICFG_EN_SPICMD 0x08 +#define SPICFG_LOW_SPICS 0x10 +#define SPICFG_EN_SHORT_READ 0x20 +#define SPICFG_EN_OFFSET_READ 0x40 +#define SPICFG_EN_FAST_READ 0x80 + +/* SMBUS relative register block according to the EC datasheet. */ +#define REG_SMBTCRC 0xff92 +#define REG_SMBPIN 0xff93 +#define REG_SMBCFG 0xff94 +#define REG_SMBEN 0xff95 +#define REG_SMBPF 0xff96 +#define REG_SMBRCRC 0xff97 +#define REG_SMBPRTCL 0xff98 +#define REG_SMBSTS 0xff99 +#define REG_SMBADR 0xff9a +#define REG_SMBCMD 0xff9b +#define REG_SMBDAT_START 0xff9c +#define REG_SMBDAT_END 0xffa3 +#define SMBDAT_SIZE 8 +#define REG_SMBRSA 0xffa4 +#define REG_SMBCNT 0xffbc +#define REG_SMBAADR 0xffbd +#define REG_SMBADAT0 0xffbe +#define REG_SMBADAT1 0xffbf + +/* watchdog timer registers */ +#define REG_WDTCFG 0xfe80 +#define REG_WDTPF 0xfe81 +#define REG_WDT 0xfe82 + +/* lpc configure register */ +#define REG_LPCCFG 0xfe95 + +/* 8051 reg */ +#define REG_PXCFG 0xff14 + +/* Fan register in KB3310 */ +#define REG_ECFAN_SPEED_LEVEL 0xf4e4 +#define REG_ECFAN_SWITCH 0xf4d2 + +/*************************************************************/ +/* the ec flash rom id number */ +#define EC_ROM_PRODUCT_ID_SPANSION 0x01 +#define EC_ROM_PRODUCT_ID_MXIC 0xC2 +#define EC_ROM_PRODUCT_ID_AMIC 0x37 +#define EC_ROM_PRODUCT_ID_EONIC 0x1C + +/**************************************************************/ + +/* Ec misc device name */ +#define EC_MISC_DEV "ec_misc" + +/* Ec misc device minor number */ +#define ECMISC_MINOR_DEV MISC_DYNAMIC_MINOR + +#define EC_IOC_MAGIC 'E' +/* misc ioctl operations */ +#define IOCTL_RDREG _IOR(EC_IOC_MAGIC, 1, int) +#define IOCTL_WRREG _IOW(EC_IOC_MAGIC, 2, int) +#define IOCTL_READ_EC _IOR(EC_IOC_MAGIC, 3, int) +#define IOCTL_PROGRAM_IE _IOW(EC_IOC_MAGIC, 4, int) +#define IOCTL_PROGRAM_EC _IOW(EC_IOC_MAGIC, 5, int) + +/* start address for programming of EC content or IE */ +#define EC_START_ADDR 0x00000000 // ec running code start address +#define IE_START_ADDR 0x00020000 // ec information element storing address +#define RESVEC_START_ADDR 0x00010000 // ec reserve firmware code storing address + +/* EC state */ +#define EC_STATE_IDLE 0x00 // ec in idle state +#define EC_STATE_BUSY 0x01 // ec in busy state + +/* timeout value for programming */ +#define EC_FLASH_TIMEOUT 0x1000 // ec program timeout +#define EC_CMD_TIMEOUT 0x1000 // command checkout timeout including cmd to port or state flag check +#define EC_SPICMD_STANDARD_TIMEOUT (4 * 1000) // unit : us +#define EC_MAX_DELAY_UNIT (10) // every time for polling +#define SPI_FINISH_WAIT_TIME 10 +/* EC content max size */ +#define EC_CONTENT_MAX_SIZE (64 * 1024) +#define IE_CONTENT_MAX_SIZE (0x100000 - IE_START_ADDR) + +/* + * piece structure : + * ------------------------------ + * | 1byte | 3 bytes | 28 bytes | + * | flag | addr | data | + * ------------------------------ + * flag : + * bit0 : '1' for first piece, '0' for other + * addr : + * address for EC to burn the data to(rom address) + * data : + * data which we should burn to the ec rom + * + * NOTE : so far max size should be 256bytes, or we should change the address-1 value. + * piece is used for IE program + */ +#define PIECE_SIZE (32 - 1 - 3) +#define FIRST_PIECE_YES 1 +#define FIRST_PIECE_NO 0 +#define PIECE_STATUS_REG 0xF77C // piece program status reg from ec firmware +#define PIECE_STATUS_PROGRAM_DONE 0x80 // piece program status reg done flag +#define PIECE_STATUS_PROGRAM_ERROR 0x40 // piece program status reg error flag +#define PIECE_START_ADDR 0xF800 // 32bytes should be stored here + +/* the register operation access struct */ +struct ec_reg { + u32 addr; /* the address of kb3310 registers */ + u8 val; /* the register value */ +}; + +struct ec_info { + u32 start_addr; + u32 size; + u8 *buf; +}; + + diff --git a/drivers/misc/loongson/ec_sci.c b/drivers/misc/loongson/ec_sci.c new file mode 100644 index 0000000..13917fc --- /dev/null +++ b/drivers/misc/loongson/ec_sci.c @@ -0,0 +1,1131 @@ +/* + * EC(Embedded Controller) KB3310B SCI EVENT management driver on Linux + * Author : liujl + * Date : 2008-10-22 + * + * NOTE : Until now, I have no idea for setting the interrupt to edge sensitive + * mode, amd's help should be needed for handling this problem + * So, I assume that the interrupt width is 120us + */ + +/***********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ec.h" +/***********************************************************************/ + +/* inode information */ +#define EC_SCI_MINOR_DEV MISC_DYNAMIC_MINOR +#define EC_SCI_DEV "sci" +#define SCI_IRQ_NUM 0x0A +#define CS5536_GPIO_SIZE 256 + +/* ec delay time 500us for register and status access */ +/* unit : us */ +#define EC_REG_DELAY 300 + +/***********************************************************************/ +struct ec_sci_reg{ + u32 addr; + u8 val; +}; +struct ec_sci_reg ecreg; + +struct sci_device { + /* the sci number get from ec */ + unsigned char sci_number; + + /* sci count */ + unsigned char sci_parameter; + + /* irq relative */ + unsigned char irq; + unsigned char irq_data; + + /* device name */ + unsigned char name[10]; + + /* gpio base registers and length */ + unsigned long gpio_base; + unsigned long gpio_size; + + /* lock & wait_queue */ + wait_queue_head_t wq; + spinlock_t lock; + + /* storage initial value of sci status register + * sci_init_value[0] as brightness + * sci_init_value[1] as volume + * sci_init_value[2] as ac + * sci_init_value[3] as display state + * sci_init_value[4] as vga state + */ + unsigned char sci_init_value[4]; +}; +struct sci_device *sci_device; + +#ifdef CONFIG_PROC_FS +static ssize_t sci_proc_read(struct file *file, char *buf, size_t len, loff_t *ppos); +static ssize_t sci_proc_write(struct file *file, const char *buf, size_t len, loff_t *ppos); +static unsigned int sci_poll(struct file *fp, poll_table *wait); +static struct proc_dir_entry *sci_proc_entry; +static struct file_operations sci_proc_fops = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) + owner : THIS_MODULE, +#endif + read : sci_proc_read, + poll : sci_poll, + write : sci_proc_write, +}; + +#define SCI_ACTION_COUNT 21 +#define SCI_ACTION_WIDTH 20 +char sci_action[SCI_ACTION_COUNT][SCI_ACTION_WIDTH] = { + "DISPLAY : LCD", + "DISPLAY : CRT", + "DISPLAY : ALL", + "DISPLAY : CHG", + "AUDIO : CHG", + "MACHINE : OFF", + "MACHINE : RES", + "CAMERA : ON", + "CAMERA : OFF", + //"LCDLED : ON", + //"LCDLED : OFF", + "LCD : ON", + "LCD : OFF", + "LED : ON", + "LED : OFF", + "VGA : ON", + "VGA : OFF", + "BKLIGHT : UP", + "BKLIGHT : DOWN", + "AC : IN", + "AC : OUT", + "NONE", + "NONE" +}; + +static enum { + CMD_DISPLAY_LCD = 0, + CMD_DISPLAY_CRT, + CMD_DISPLAY_ALL, + CMD_DISPLAY_CHANGE_BRIGHTNESS, + CMD_AUDIO_CHANGE_VOLUME, + CMD_MACHINE_OFF, + CMD_MACHINE_RESET, + CMD_CAMERA_ON, + CMD_CAMERA_OFF, + CMD_LCD_PWRON, + CMD_LCD_PWROFF, + CMD_LED_PWRON, + CMD_LED_PWROFF, + CMD_VGA_PWRON, + CMD_VGA_PWROFF, + CMD_BKLIGHT_UP, + CMD_BKLIGHT_DOWN, + CMD_AC_IN, + CMD_AC_OUT, + //CMD_LCDLED_PWRON, + //CMD_LCDLED_PWROFF, + CMD_NONE +}sci_cmd; + +#endif + +/*******************************************************************/ + +static void sci_display_lcd(void) +{ + unsigned char value; + + outb(0x21, 0x3c4); + value = inb(0x3c5); + value |= (1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x01; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + return; +} + +static void sci_display_crt(void) +{ + unsigned char value; + + outb(0x21, 0x3c4); + value = inb(0x3c5); + value &= ~(1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x02; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + return; +} + +static void sci_display_all(void) +{ + unsigned char value; + + outb(0x21, 0x3c4); + value = inb(0x3c5); + value &= ~(1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x03; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + return; +} + +#if 0 +static void sci_lcdled_power(unsigned char flag) +{ + unsigned char value; + + /* default display crt */ + outb(0x21, 0x3c4); + value = inb(0x3c5); + value &= ~(1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + + if(flag == CMD_LCDLED_PWRON){ + /* open lcd output */ + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x03; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + /* LCD backlight on */ + ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_ON); + } + else if(flag == CMD_LCDLED_PWROFF){ + /* close lcd output */ + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x02; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + + /* LCD backlight off */ + ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_OFF); + } + + return; +} +#endif + +static void sci_led_power(unsigned char flag) +{ + + if(flag == CMD_LED_PWRON){ + /* LCD backlight on */ + ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_ON); + } + else if(flag == CMD_LED_PWROFF){ + /* LCD backlight off */ + ec_write(REG_BACKLIGHT_CTRL, BIT_BACKLIGHT_OFF); + } +} + +static void sci_vga_power(unsigned char flag) +{ + unsigned char value; + + if(flag == CMD_VGA_PWRON){ + /* display crt */ + outb(0x21, 0x3c4); + value = inb(0x3c5); + value &= ~(1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + } + else if(flag == CMD_VGA_PWROFF){ + /* close crt */ + outb(0x21, 0x3c4); + value = inb(0x3c5); + value |= (1 << 7); + outb(0x21, 0x3c4); + outb(value, 0x3c5); + } + + return; +} + +static void sci_lcd_power(unsigned char flag) +{ + unsigned char value; + + if(flag == CMD_LCD_PWRON){ + /* open lcd output */ + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x03; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + } + else if(flag == CMD_LCD_PWROFF){ + /* close lcd output */ + outb(0x31, 0x3c4); + value = inb(0x3c5); + value = (value & 0xf8) | 0x02; + outb(0x31, 0x3c4); + outb(value, 0x3c5); + } + + return; +} + +static void sci_brightness_write(unsigned char flag) +{ + unsigned char level; + unsigned char level_max; + unsigned char level_min; + + level = ec_read(REG_DISPLAY_BRIGHTNESS); + + if(ec_read(REG_BAT_POWER) & BIT_BAT_POWER_ACIN){ + PRINTK_DBG("AC exist...\n"); + if(level == FLAG_DISPLAY_BRIGHTNESS_LEVEL_0) + level = FLAG_DISPLAY_BRIGHTNESS_LEVEL_1; + level_max = FLAG_DISPLAY_BRIGHTNESS_LEVEL_8; + level_min = FLAG_DISPLAY_BRIGHTNESS_LEVEL_1; + } + else{ + PRINTK_DBG("AC no exist...\n"); + if(level == FLAG_DISPLAY_BRIGHTNESS_LEVEL_8) + level = FLAG_DISPLAY_BRIGHTNESS_LEVEL_7; + level_max = FLAG_DISPLAY_BRIGHTNESS_LEVEL_7; + level_min = FLAG_DISPLAY_BRIGHTNESS_LEVEL_0; + } + if(flag == CMD_BKLIGHT_UP){ + if(level < level_max && level >= level_min) + ec_write(REG_DISPLAY_BRIGHTNESS, ++level); + PRINTK_DBG("Brightness status(UP): 0x%x\n", ec_read(REG_DISPLAY_BRIGHTNESS)); + } + else if(flag == CMD_BKLIGHT_DOWN){ + if(level <= level_max && level > level_min) + ec_write(REG_DISPLAY_BRIGHTNESS, --level); + PRINTK_DBG("Brightness status(DOWN): 0x%x\n", ec_read(REG_DISPLAY_BRIGHTNESS)); + } + + return; +} + +static void sci_ac_in_out(unsigned char flag) +{ + if(flag == CMD_AC_IN){ + if(ec_read(REG_DISPLAY_BRIGHTNESS) < FLAG_DISPLAY_BRIGHTNESS_LEVEL_8){ + PRINTK_DBG("ACIN...\n"); + ec_write(REG_DISPLAY_BRIGHTNESS, ec_read(REG_DISPLAY_BRIGHTNESS) + 1); + } + } + else if(flag == CMD_AC_OUT){ + if(ec_read(REG_DISPLAY_BRIGHTNESS) > FLAG_DISPLAY_BRIGHTNESS_LEVEL_0){ + PRINTK_DBG("ACOUT...\n"); + ec_write(REG_DISPLAY_BRIGHTNESS, ec_read(REG_DISPLAY_BRIGHTNESS) - 1); + } + } + + return; +} + +static void sci_display_change_brightness(void) +{ + ec_write(REG_DISPLAY_BRIGHTNESS, FLAG_DISPLAY_BRIGHTNESS_LEVEL_4); + return; +} + +static void sci_audio_change_volume(void) +{ + ec_write(REG_AUDIO_VOLUME, FLAG_AUDIO_VOLUME_LEVEL_5); + return; +} + +static void sci_camera_on_off(void) +{ + unsigned char val; + val = ec_read(REG_CAMERA_CONTROL); + ec_write(REG_CAMERA_CONTROL, val | (1 << 1)); + return; +} + +static void sci_machine_off(void) +{ +#ifdef CONFIG_64BIT + /* cpu-gpio0 output low */ + *((volatile unsigned int *)(0xffffffffbfe0011c)) &= ~0x00000001; + /* cpu-gpio0 as output */ + *((volatile unsigned int *)(0xffffffffbfe00120)) &= ~0x00000001; +#else + /* cpu-gpio0 output low */ + *((volatile unsigned int *)(0xbfe0011c)) &= ~0x00000001; + /* cpu-gpio0 as output */ + *((volatile unsigned int *)(0xbfe00120)) &= ~0x00000001; +#endif //end ifdef CONFIG_64BIT + return; +} + +static void sci_machine_reset(void) +{ + ec_write(REG_RESET, BIT_RESET_ON); + return; +} + +/*******************************************************************/ +//static const char driver_version[] = "1.0"; +static const char driver_version[] = VERSION; + +#ifdef CONFIG_PROC_FS +#define PROC_BUF_SIZE 128 +unsigned char proc_buf[PROC_BUF_SIZE]; + +/* + * sci_proc_read : + * read information from sci device and suppied to upper layer + * The format is as following : + * driver_version 1.0 + * DISPLAY BRIGHTNESS INCREASE + * DISPLAY BRIGHTNESS DECREASE + * AUDIO VOLUME INCREASE + * AUDIO VOLUME DECREASE + * MUTE 0x00 close, 0x01 open + * WLAN 0x00 close, 0x01 open + * LID 0x00 close, 0x01 open + * DISPLAY TOGGLE + * BLACK SCREEN + * SLEEP + * OVER TEMPERATURE + * CRT DETECT + * CAMERA 0x00 close, 0x01 open + * USB OC2 + * USB OC0 + * BAT IN + * AC IN + * INIT CAP + * CHARGE MODE + * STOP CHARGE + * BAT LOW + * BAT FULL + */ +static ssize_t sci_proc_read(struct file *file, char *buf, size_t len, loff_t *ppos) +{ + unsigned char event[SCI_MAX_EVENT_COUNT]; + int ret = 0; + int i; + int count = 0; + DECLARE_WAITQUEUE(wait, current); + + PRINTK_DBG("0 irq_data %d\n", sci_device->irq_data); + + if (sci_device->irq_data == 0) { + add_wait_queue(&(sci_device->wq), &wait); + + while (!sci_device->irq_data) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } + remove_wait_queue(&(sci_device->wq), &wait); + } + + + PRINTK_DBG("1 irq_data %d\n", sci_device->irq_data); + __set_current_state(TASK_RUNNING); + + + ret = sprintf(proc_buf, "0x%x\t%d\n", sci_device->sci_number, sci_device->sci_parameter); + + count = strlen(proc_buf); + sci_device->irq_data = 0; + + if(len < count) + return -ENOMEM; + if(PROC_BUF_SIZE < count) + return -ENOMEM; + + if(copy_to_user(buf, proc_buf, count)) + return -EFAULT; + + return count; +} + +/* + * sci_proc_write : + * get the upper layer's action and take action. + */ +static ssize_t sci_proc_write(struct file *file, const char *buf, size_t len, loff_t *ppos) +{ + int i; + + if(len > PROC_BUF_SIZE) + return -ENOMEM; + if(copy_from_user(proc_buf, buf, len)) + return -EFAULT; + proc_buf[len] = '\0'; + + PRINTK_DBG("proc_buf : %s\n", proc_buf); + for(i = 0; i < SCI_ACTION_COUNT; i++){ + if(strncmp(proc_buf, sci_action[i], strlen(sci_action[i])) == 0){ + sci_cmd = i; + break; + } + } + if(i == SCI_ACTION_COUNT) + sci_cmd = CMD_NONE; + PRINTK_DBG("sci_cmd: %d\n", sci_cmd); + switch(sci_cmd){ + case CMD_DISPLAY_LCD : + sci_display_lcd(); + PRINTK_DBG(KERN_DEBUG "CMD_DISPLAY_LCD"); + break; + case CMD_DISPLAY_CRT : + sci_display_crt(); + PRINTK_DBG(KERN_DEBUG "CMD_DISPLAY_CRT"); + break; + case CMD_DISPLAY_ALL : + sci_display_all(); + PRINTK_DBG(KERN_DEBUG "CMD_DISPLAY_ALL"); + break; + case CMD_DISPLAY_CHANGE_BRIGHTNESS : + sci_display_change_brightness(); + PRINTK_DBG(KERN_DEBUG "CMD_DISPLAY_CHANGE_BRIGHTNESS"); + break; + case CMD_AUDIO_CHANGE_VOLUME : + sci_audio_change_volume(); + PRINTK_DBG(KERN_DEBUG "CMD_AUDIO_CHANGE_VOLUME"); + break; + case CMD_MACHINE_OFF : + sci_machine_off(); + PRINTK_DBG(KERN_DEBUG "CMD_MACHINE_OFF"); + break; + case CMD_MACHINE_RESET : + sci_machine_reset(); + PRINTK_DBG(KERN_DEBUG "CMD_MACHINE_RESET"); + break; + case CMD_CAMERA_ON : + sci_camera_on_off(); + PRINTK_DBG(KERN_DEBUG "CMD_CAMERA_ON"); + break; + case CMD_CAMERA_OFF : + sci_camera_on_off(); + PRINTK_DBG(KERN_DEBUG "CMD_CAMERA_OFF"); + break; + /* case CMD_LCDLED_PWRON : + sci_lcdled_power(CMD_LCDLED_PWRON); + PRINTK_DBG(KERN_DEBUG "CMD_LCDLED_PWRON"); + break; + case CMD_LCDLED_PWROFF : + sci_lcdled_power(CMD_LCDLED_PWROFF); + PRINTK_DBG(KERN_DEBUG "CMD_LCDLED_PWROFF"); + break; + */ case CMD_LCD_PWRON : + sci_lcd_power(CMD_LCD_PWRON); + PRINTK_DBG(KERN_DEBUG "CMD_LCD_PWRON\n"); + break; + case CMD_LCD_PWROFF : + sci_lcd_power(CMD_LCD_PWROFF); + PRINTK_DBG(KERN_DEBUG "CMD_LCD_PWROFF\n"); + break; + case CMD_LED_PWRON : + sci_led_power(CMD_LED_PWRON); + PRINTK_DBG(KERN_DEBUG "CMD_LED_PWRON\n"); + break; + case CMD_LED_PWROFF : + sci_led_power(CMD_LED_PWROFF); + PRINTK_DBG(KERN_DEBUG "CMD_LED_PWROFF\n"); + break; + case CMD_VGA_PWRON : + sci_vga_power(CMD_VGA_PWRON); + PRINTK_DBG(KERN_DEBUG "CMD_VGA_PWRON\n"); + break; + case CMD_VGA_PWROFF : + sci_vga_power(CMD_VGA_PWROFF); + PRINTK_DBG(KERN_DEBUG "CMD_VGA_PWROFF\n"); + break; + case CMD_BKLIGHT_UP : + sci_brightness_write(CMD_BKLIGHT_UP); + PRINTK_DBG(KERN_DEBUG "CMD_BKLIGHT_UP\n"); + break; + case CMD_BKLIGHT_DOWN : + PRINTK_DBG(KERN_DEBUG "CMD_BKLIGHT_DOWN: %d\n", CMD_BKLIGHT_DOWN); + sci_brightness_write(CMD_BKLIGHT_DOWN); + PRINTK_DBG(KERN_DEBUG "CMD_BKLIGHT_DOWN\n"); + break; + case CMD_AC_IN : + sci_ac_in_out(CMD_AC_IN); + PRINTK_DBG(KERN_DEBUG "CMD_AC_IN\n"); + break; + case CMD_AC_OUT : + sci_ac_in_out(CMD_AC_OUT); + PRINTK_DBG(KERN_DEBUG "CMD_AC_OUT\n"); + break; + + default : + printk(KERN_ERR "EC SCI : Not supported cmd.\n"); + return -EINVAL; + } + + return len; +} +#endif + +/*******************************************************************************/ + +/* + * sci_query_event_num : + * using query command to ec to get the proper event number + */ +static int sci_query_event_num(void) +{ + int ret = 0; + + ret = ec_query_seq(CMD_GET_EVENT_NUM); + return ret; +} + +/* + * sci_parse_num : + * parse the event number routine, and store all the information + * to the sci_num_array[] for upper layer using + */ +static int sci_parse_num(struct sci_device *sci_device) +{ + unsigned char val; + + switch(sci_device->sci_number){ + case SCI_EVENT_NUM_LID : + sci_device->sci_parameter = ec_read(REG_LID_DETECT); + break; + case SCI_EVENT_NUM_DISPLAY_TOGGLE : + if (ec_read(REG_CRT_DETECT) == 1) + sci_device->sci_init_value[3] = (sci_device->sci_init_value[3] + 1) % 3; + sci_device->sci_parameter = sci_device->sci_init_value[3]; + break; + case SCI_EVENT_NUM_SLEEP : + sci_device->sci_parameter = 0x01; + break; + case SCI_EVENT_NUM_OVERTEMP : /* fix me, state not clear */ + sci_device->sci_parameter = (ec_read(REG_BAT_CHARGE_STATUS) & BIT_BAT_CHARGE_STATUS_OVERTEMP) >> 2; + break; + case SCI_EVENT_NUM_CRT_DETECT : + sci_device->sci_parameter = ec_read(REG_CRT_DETECT); + if (sci_device->sci_parameter == 0) sci_device->sci_init_value[3] = 0; + break; + case SCI_EVENT_NUM_CAMERA : + sci_device->sci_parameter = ec_read(REG_CAMERA_STATUS); + break; + case SCI_EVENT_NUM_USB_OC2 : + sci_device->sci_parameter = ec_read(REG_USB2_FLAG); + break; + case SCI_EVENT_NUM_USB_OC0 : + sci_device->sci_parameter = ec_read(REG_USB0_FLAG); + break; + case SCI_EVENT_NUM_AC_BAT : + val = ec_read(REG_BAT_POWER) & BIT_BAT_POWER_ACIN; + sci_device->sci_parameter= 3; + if (sci_device->sci_init_value[2] == 0 && val == 1) + sci_device->sci_parameter = 1; + if (sci_device->sci_init_value[2] == 1 && val == 0) + sci_device->sci_parameter = 0; + sci_device->sci_init_value[2] = val; + break; + case SCI_EVENT_NUM_DISPLAY_BRIGHTNESS : + sci_device->sci_parameter = ec_read(REG_DISPLAY_BRIGHTNESS); + break; + case SCI_EVENT_NUM_AUDIO_VOLUME : + val = ec_read(REG_AUDIO_VOLUME); + sci_device->sci_parameter = val; +#if 0 + if (val == 8 || val > sci_device->sci_init_value[1]) + sci_device->sci_parameter = 1; + if (val == 0 || val < sci_device->sci_init_value[1]) + sci_device->sci_parameter = 0; + sci_device->sci_init_value[1] = val; +#endif + break; + case SCI_EVENT_NUM_WLAN : + sci_device->sci_parameter = ec_read(REG_WLAN_STATUS); + break; + case SCI_EVENT_NUM_AUDIO_MUTE : + sci_device->sci_parameter = ec_read(REG_AUDIO_MUTE); + break; + case SCI_EVENT_NUM_BLACK_SCREEN : + sci_device->sci_parameter = ec_read(REG_DISPLAY_LCD); + break; + + default : + PRINTK_DBG(KERN_ERR "EC SCI : not supported SCI NUMBER.\n"); + return -EINVAL; + break; + } + + return 0; +} + +/***************************************************************/ +#define EC_SCI_EVENT_BASE 0x21 +ec_handler ec_irq_handler[SCI_MAX_EVENT_COUNT]; + +void ec_handler_install(int event_nu, ec_handler irq_handler) +{ + ec_irq_handler[event_nu - EC_SCI_EVENT_BASE] = irq_handler; +} + +EXPORT_SYMBOL(ec_handler_install); + +void ec_handler_uninstall(int event_nu) +{ + ec_irq_handler[event_nu - EC_SCI_EVENT_BASE] = NULL; +} + +EXPORT_SYMBOL(ec_handler_uninstall); + + +/* + * sci_int_routine : sci main interrupt routine + * we will do the query and get event number together + * so the interrupt routine should be longer than 120us + * now at least 3ms elpase for it. + */ +static irqreturn_t sci_int_routine(int irq, void *dev_id) +{ + int ret; + + if(sci_device->irq != irq){ + PRINTK_DBG(KERN_ERR "EC SCI :spurious irq.\n"); + return IRQ_NONE; + } + + /* query the event number */ + ret = sci_query_event_num(); + if(ret < 0){ + PRINTK_DBG("ret 1: %d\n", ret); + return IRQ_NONE; + } + + ret = sci_get_event_num(); + if(ret < 0){ + PRINTK_DBG("ret 2: %d\n", ret); + return IRQ_NONE; + } + sci_device->sci_number = ret; + + PRINTK_DBG(KERN_INFO "sci_number :0x%x\n", sci_device->sci_number); + + /* report the AC/BAT change */ + if((sci_device->sci_number == SCI_EVENT_NUM_AC_BAT) ||(sci_device->sci_number == 0x31)){ + ec_handler handler; + handler = ec_irq_handler[SCI_EVENT_NUM_AC_BAT - EC_SCI_EVENT_BASE]; + if(handler) + handler(); + } + + /* parse the event number and wake the queue */ + if( (sci_device->sci_number != 0x00) + && (sci_device->sci_number != 0xff) ){ + ret = sci_parse_num(sci_device); + PRINTK_DBG("ret 3: %d\n", ret); + if(!ret) + sci_device->irq_data = 1; + else + sci_device->irq_data = 0; + + wake_up_interruptible(&(sci_device->wq)); + PRINTK_DBG("interrupitble\n"); + } + + return IRQ_HANDLED; +} + +/************************************************************/ + +static int sci_open(struct inode * inode, struct file * filp) +{ + PRINTK_DBG(KERN_INFO "SCI : open ok.\n"); + return 0; +} + +static int sci_release(struct inode * inode, struct file * filp) +{ + PRINTK_DBG(KERN_INFO "SCI : close ok.\n"); + return 0; +} + +/* + * sci_poll : poll routine for upper layer using + */ +static unsigned int sci_poll(struct file *fp, poll_table *wait) +{ + int mask = 0; + + //printk("current task %p\n", current); + poll_wait(fp, &(sci_device->wq), wait); + if(sci_device->irq_data){ + //printk("current task 1 %p\n", current); + mask = POLLIN | POLLRDNORM; + } + + return mask; +} + +static int sci_ioctl(struct inode *inode, struct file *filp, unsigned long cmd, unsigned long arg) +{ + void __user *ptr = (void __user *)arg; + int ret = 0; + + switch(cmd){ +// case IOCTL_GET_INIT_STATE : + case 1 : + ret = copy_from_user(&ecreg, ptr, sizeof(struct ec_sci_reg)); + if(ret){ + printk(KERN_ERR "read from user error.\n"); + return -EFAULT; + } + if(ecreg.addr < 0xf400 || ecreg.addr > 0xffff){ + return -EINVAL; + } + ecreg.val = ec_read(ecreg.addr); + ret = copy_to_user(ptr, &ecreg, sizeof(struct ec_sci_reg)); + if(ret){ + printk(KERN_ERR "reg read : copy to user error.\n"); + return -EFAULT; + } + break; + default : + break; + } + + return 0; +} + +static long sci_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return sci_ioctl(file->f_dentry->d_inode, file, cmd, arg); +} + +static const struct file_operations sci_fops = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) + .owner = THIS_MODULE, +#endif +#ifdef CONFIG_64BIT + .compat_ioctl = sci_compat_ioctl, +#else + .ioclt = sci_ioctl, +#endif + .open = sci_open, + .poll = sci_poll, + .release = sci_release, +}; + +static struct miscdevice sci_dev = { + .minor = EC_SCI_MINOR_DEV, + .name = EC_SCI_DEV, + .fops = &sci_fops +}; + +/********************************************************/ + +static struct pci_device_id sci_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, + { } +}; +MODULE_DEVICE_TABLE(pci, sci_pci_tbl); + +/* + * sci_low_level_init : + * config and init some msr and gpio register properly. + */ +static int sci_low_level_init(struct sci_device *scidev) +{ + u32 hi, lo; + u32 gpio_base = scidev->gpio_base; + int ret = 0; + unsigned long flags; + + /* filter the former kb3310 interrupt for security */ + ret = sci_query_event_num(); + if(ret){ + PRINTK_DBG(KERN_ERR "sci low level init query event num failed.\n"); + return ret; + } + + /* for filtering next number interrupt */ + udelay(10000); + + /* set gpio native registers and msrs for GPIO27 SCI EVENT PIN + * gpio : + * input, pull-up, no-invert, event-count and value 0, + * no-filter, no edge mode + * gpio27 map to Virtual gpio0 + * msr : + * no primary and lpc + * Unrestricted Z input to IG10 from Virtual gpio 0. + */ + local_irq_save(flags); + _rdmsr(0x80000024, &hi, &lo); + lo &= ~(1 << 10); + _wrmsr(0x80000024, hi, lo); + _rdmsr(0x80000025, &hi, &lo); + lo &= ~(1 << 10); + _wrmsr(0x80000025, hi, lo); + _rdmsr(0x80000023, &hi, &lo); + lo |= (0x0a << 0); + _wrmsr(0x80000023, hi, lo); + local_irq_restore(flags); + + /* set gpio27 as sci interrupt : + * input, pull-up, no-fliter, no-negedge, invert + * the sci event is just about 120us + */ + asm(".set noreorder\n"); + // input enable + outl( 0x00000800, (gpio_base | 0xA0) ); + // revert the input + outl( 0x00000800, (gpio_base | 0xA4) ); + // event-int enable + outl( 0x00000800, (gpio_base | 0xB8) ); + asm(".set reorder\n"); + + return 0; +} + +/* + * sci_pci_init : + * pci init routine + */ +static int __devinit sci_pci_init(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + u32 gpio_base; + int ret = -EIO; + //int i; + + /* init the sci device */ + sci_device = kmalloc(sizeof(struct sci_device), GFP_KERNEL); + if(sci_device == NULL){ + PRINTK_DBG(KERN_ERR "EC SCI : get memory for sci_device failed.\n"); + return -ENOMEM; + } + init_waitqueue_head(&(sci_device->wq)); + spin_lock_init(&sci_device->lock); + sci_device->irq = SCI_IRQ_NUM; + sci_device->irq_data = 0x00; + sci_device->sci_number = 0x00; + strcpy(sci_device->name, EC_SCI_DEV); + + sci_device->sci_init_value[0] = ec_read(REG_DISPLAY_BRIGHTNESS); + sci_device->sci_init_value[1] = ec_read(REG_AUDIO_VOLUME); + sci_device->sci_init_value[2] = ec_read(REG_BAT_POWER) & BIT_BAT_POWER_ACIN; + sci_device->sci_init_value[3] = 0; + + sci_device->sci_parameter = 0x00; + + /* enable pci device and get the GPIO resources */ + ret = pci_enable_device(pdev); + if(ret){ + PRINTK_DBG(KERN_ERR "EC SCI : enable pci device failed.\n"); + ret = -ENODEV; + goto out_pdev; + } + + gpio_base = 0x0000; + gpio_base = pci_resource_start(pdev, 1); + gpio_base &= ~0x0003; + if(gpio_base == 0x0000){ + PRINTK_DBG(KERN_ERR "EC SCI : get resource failed.\n"); + ret = -ENODEV; + goto out_resource; + } + if(request_region(gpio_base, CS5536_GPIO_SIZE, EC_SCI_DEV) == NULL){ + PRINTK_DBG(KERN_ERR "EC SCI : base 0x%x, length 0x%x already in use.\n", gpio_base, CS5536_GPIO_SIZE); + goto out_resource; + } + sci_device->gpio_base = gpio_base; + sci_device->gpio_size = CS5536_GPIO_SIZE; + + /* init the relative gpio and msrs */ + ret = sci_low_level_init(sci_device); + if(ret < 0){ + printk(KERN_ERR "EC SCI : low level init failed.\n"); + goto out_irq; + } + + /* alloc the interrupt for sci not pci */ + ret = request_irq(sci_device->irq, sci_int_routine, IRQF_SHARED, sci_device->name, sci_device); + if(ret){ + printk(KERN_ERR "EC SCI : request irq %d failed.\n", sci_device->irq); + ret = -EFAULT; + goto out_irq; + } + + /* register the misc device */ + ret = misc_register(&sci_dev); + if (ret != 0) { + printk(KERN_ERR "EC SCI : misc register failed.\n"); + ret = -EFAULT; + goto out_misc; + } + + ret = 0; + PRINTK_DBG(KERN_INFO "sci probe ok...\n"); + goto out; + +out_misc : + free_irq(sci_device->irq, sci_device); +out_irq : + release_region(sci_device->gpio_base, sci_device->gpio_size); +out_resource : + pci_disable_device(pdev); +out_pdev : + kfree(sci_device); +out : + return ret; +} + +static int sci_pci_resume(struct pci_dev *pdev, pm_message_t msg) +{ + int ret = -EIO; + + /* enable device */ + //ret = pci_restore_state(pdev); + if(pci_enable_device(pdev)){ + printk(KERN_ERR "EC SCI : enable pci device failed.\n"); + return -1; + } + /* reinit the relative gpio and msrs */ + ret = sci_low_level_init(sci_device); + if(ret < 0){ + printk(KERN_ERR "EC SCI : low level init failed.\n"); + } + pdev->dev.power.power_state = msg; + + return ret; +} + +static int sci_pci_suspend (struct pci_dev *pdev, pm_message_t msg) +{ + int ret; + + /* do suspend */ + if (msg.event == PM_EVENT_SUSPEND) { + ret = pci_save_state(pdev); + pci_disable_device(pdev); + } + + pdev->dev.power.power_state = msg; + + return 0; +} + +static void __devexit sci_pci_remove(struct pci_dev *pdev) +{ + misc_deregister(&sci_dev); + free_irq(sci_device->irq, sci_device); + release_region(sci_device->gpio_base, sci_device->gpio_size); + pci_disable_device(pdev); + kfree(sci_device); + + return; +} + +static struct pci_driver sci_driver = { + .name = EC_SCI_DEV, + .id_table = sci_pci_tbl, + .probe = sci_pci_init, + .remove = __devexit_p(sci_pci_remove), +#ifdef CONFIG_PM + .suspend = sci_pci_suspend, + .resume = sci_pci_resume, +#endif +}; + + +/**************************************************************************/ + +static int __init sci_init(void) +{ + int ret = 0; + +#ifdef CONFIG_PROC_FS + sci_proc_entry = NULL; + sci_proc_entry = create_proc_entry(EC_SCI_DEV, S_IWUSR | S_IRUGO, NULL); + if(sci_proc_entry == NULL){ + printk(KERN_ERR "EC SCI : register /proc/sci failed.\n"); + return -EINVAL; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) + sci_proc_entry->owner = THIS_MODULE; +#endif + sci_proc_entry->proc_fops = &sci_proc_fops; +#endif + + ret = pci_register_driver(&sci_driver); + if(ret){ + printk(KERN_ERR "EC SCI : registrer pci driver error.\n"); +#ifdef CONFIG_PROC_FS + remove_proc_entry(EC_SCI_DEV, NULL); +#endif + return ret; + } + + printk(KERN_INFO "SCI event handler on KB3310B Embedded Controller init.\n"); + + return ret; +} + +static void __exit sci_exit(void) +{ +#ifdef CONFIG_PROC_FS + remove_proc_entry(EC_SCI_DEV, NULL); +#endif + pci_unregister_driver(&sci_driver); + printk(KERN_INFO "SCI event handler on KB3310B Embedded Controller exit.\n"); + + return; +} + +module_init(sci_init); +module_exit(sci_exit); + +MODULE_AUTHOR("liujl "); +MODULE_DESCRIPTION("SCI Event Management for KB3310"); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/misc/loongson/io_msr_debug.c b/drivers/misc/loongson/io_msr_debug.c new file mode 100644 index 0000000..f54be1b --- /dev/null +++ b/drivers/misc/loongson/io_msr_debug.c @@ -0,0 +1,203 @@ +/* + * Debug IO and MSR resources driver on Linux + * Author : liujl + * huangw + * Date : 2009-03-03 + * + * NOTE : + * 1, The IO and the MSR resources accessing read/write are supported. + */ + +/*******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct io_msr_reg { + u32 addr; /* the address of IO and MSR registers */ + u8 val; /* the register value for IO */ + u32 hi; /* the register value for MSR's high part */ + u32 lo; /* the register value for MSR's low part */ +}; + +#define IOCTL_RDMSR _IOR('F', 5, int) +#define IOCTL_WRMSR _IOR('F', 6, int) +#define IOCTL_RDIO _IOR('F', 7, int) +#define IOCTL_WRIO _IOR('F', 8, int) + +/* ec io space range */ +#define IO_MAX_ADDR 0xBFD0FFFF +#define IO_MIN_ADDR 0xBFD00000 + +/* define kernel version number for support new kernel version */ +//#define KERNEL_VERSION 2.6.30 + +extern void _rdmsr(u32 msr, u32 *hi, u32 *lo); +extern void _wrmsr(u32 msr, u32 hi, u32 lo); +/*******************************************************************/ + +static int io_msr_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) +{ + void __user *ptr = (void __user *)arg; + struct io_msr_reg *iomsrreg = (struct io_msr_reg *)(filp->private_data); + int ret = 0; + + switch (cmd) { + case IOCTL_RDIO : + ret = copy_from_user(iomsrreg, ptr, sizeof(struct io_msr_reg)); + if(ret){ + printk(KERN_ERR "IO read : copy from user error.\n"); + return -EFAULT; + } + + if(iomsrreg->addr > IO_MAX_ADDR || iomsrreg->addr < IO_MIN_ADDR){ + printk(KERN_ERR "IO read : out of IO address range.\n"); + return -EINVAL; + } +#ifdef CONFIG_64BIT + iomsrreg->val = *((volatile unsigned char *)(iomsrreg->addr | 0xffffffff00000000)); +#else + iomsrreg->val = *((volatile unsigned char *)(iomsrreg->addr)); +#endif + ret = copy_to_user(ptr, iomsrreg, sizeof(struct io_msr_reg)); + if(ret){ + printk(KERN_ERR "IO read : copy to user error.\n"); + return -EFAULT; + } + break; + case IOCTL_WRIO : + ret = copy_from_user(iomsrreg, ptr, sizeof(struct io_msr_reg)); + if(ret){ + printk(KERN_ERR "IO write : copy from user error.\n"); + return -EFAULT; + } + + if(iomsrreg->addr > IO_MAX_ADDR || iomsrreg->addr < IO_MIN_ADDR){ + printk(KERN_ERR "IO write : out of IO address range.\n"); + return -EINVAL; + } +#ifdef CONFIG_64BIT + *((volatile unsigned char *)(iomsrreg->addr | 0xffffffff00000000)) = iomsrreg->val; +#else + *((volatile unsigned char *)(iomsrreg->addr)) = iomsrreg->val; +#endif + break; + case IOCTL_RDMSR : + ret = copy_from_user( iomsrreg, ptr, sizeof(struct io_msr_reg) ); + if(ret){ + printk(KERN_ERR "MSR read : copy from user error.\n"); + return -EFAULT; + } + _rdmsr( iomsrreg->addr, &(iomsrreg->hi), &(iomsrreg->lo) ); + ret = copy_to_user( ptr, iomsrreg, sizeof(struct io_msr_reg) ); + if(ret){ + printk(KERN_ERR "MSR read : copy to user error.\n"); + return -EFAULT; + } + break; + case IOCTL_WRMSR : + ret = copy_from_user(iomsrreg, ptr, sizeof(struct io_msr_reg)); + if(ret){ + printk(KERN_ERR "MSR write : copy from user error.\n"); + return -EFAULT; + } + _wrmsr(iomsrreg->addr, iomsrreg->hi, iomsrreg->lo); + break; + + default : + break; + } + + return 0; +} + +static long io_msr_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return io_msr_ioctl(file->f_dentry->d_inode, file, cmd, arg); +} + +static int io_msr_open(struct inode * inode, struct file * filp) +{ + struct io_msr_reg *iomsrreg = NULL; + iomsrreg = kmalloc(sizeof(struct io_msr_reg), GFP_KERNEL); + if (iomsrreg) { + filp->private_data = iomsrreg; + } + + return iomsrreg ? 0 : -ENOMEM; +} + +static int io_msr_release(struct inode * inode, struct file * filp) +{ + struct io_msr_reg *iomsrreg = (struct io_msr_reg *)(filp->private_data); + + filp->private_data = NULL; + kfree(iomsrreg); + + return 0; +} + +static struct file_operations io_msr_fops = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) + .owner = THIS_MODULE, +#endif + .open = io_msr_open, + .release = io_msr_release, + .read = NULL, + .write = NULL, +#ifdef CONFIG_64BIT + .compat_ioctl = io_msr_compat_ioctl, +#else + .ioctl = io_msr_ioctl, +#endif +}; + +/*********************************************************/ + +static struct miscdevice io_msr_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "io_msr_dev", + .fops = &io_msr_fops +}; + +static int __init io_msr_init(void) +{ + int ret; + + printk(KERN_INFO "IO and MSR read/write device init.\n"); + ret = misc_register(&io_msr_device); + + return ret; +} + +static void __exit io_msr_exit(void) +{ + printk(KERN_INFO "IO and MSR read/write device exit.\n"); + misc_deregister(&io_msr_device); +} + +module_init(io_msr_init); +module_exit(io_msr_exit); + +MODULE_AUTHOR("liujl "); +MODULE_DESCRIPTION("IO and MSR resources debug"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/loongson/pmon_flash.c b/drivers/misc/loongson/pmon_flash.c new file mode 100644 index 0000000..d6e879a --- /dev/null +++ b/drivers/misc/loongson/pmon_flash.c @@ -0,0 +1,107 @@ +/* + * Copyright www.lemote.com + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FLASH_PHYS_ADDR 0x1fc00000 +#define FLASH_SIZE 0x080000 + +#define FLASH_PARTITION0_ADDR 0x00000000 +#define FLASH_PARTITION0_SIZE 0x00080000 + +/* define kernel version number for support new kernel version */ +//#define KERNEL_VERSION 2.6.30 + +struct map_info flash_map = { + .name = "flash device", + .size = FLASH_SIZE, + .bankwidth = 1, +}; + +struct mtd_partition flash_parts[] = { + { + .name = "Bootloader", + .offset = FLASH_PARTITION0_ADDR, + .size = FLASH_PARTITION0_SIZE + }, +}; + +#define PARTITION_COUNT ARRAY_SIZE(flash_parts) + +static struct mtd_info *mymtd; + +int __init init_flash(void) +{ + printk(KERN_NOTICE "Flash flash device: %x at %x\n", + FLASH_SIZE, FLASH_PHYS_ADDR); + + flash_map.phys = FLASH_PHYS_ADDR; + flash_map.virt = ioremap(FLASH_PHYS_ADDR, + FLASH_SIZE); + + if (!flash_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } + + simple_map_init(&flash_map); + + mymtd = do_map_probe("cfi_probe", &flash_map); + if (mymtd) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) + mymtd->owner = THIS_MODULE; +#endif + add_mtd_partitions(mymtd, flash_parts, PARTITION_COUNT); + printk(KERN_NOTICE "pmon flash device initialized\n"); + return 0; + } + + iounmap((void *)flash_map.virt); + return -ENXIO; +} + +static void __exit cleanup_flash(void) +{ + if (mymtd) { + del_mtd_partitions(mymtd); + map_destroy(mymtd); + } + if (flash_map.virt) { + iounmap((void *)flash_map.virt); + flash_map.virt = 0; + } +} + +module_init(init_flash); +module_exit(cleanup_flash); + + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Yanhua"); +MODULE_DESCRIPTION("MTD map driver for pmon programming module"); diff --git a/drivers/misc/loongson/yeeloong_laptop.c b/drivers/misc/loongson/yeeloong_laptop.c new file mode 100644 index 0000000..38631b6 --- /dev/null +++ b/drivers/misc/loongson/yeeloong_laptop.c @@ -0,0 +1,652 @@ +/* + * Driver for YeeLoong laptop extras + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin + * + * Hongbing Hu Add the battery driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ec.h" + +/* + * Battery driver + */ + +#define BIT_BAT_POWER_ACIN (1 << 0) // adapter is inserted + +#define APM_AC_OFFLINE 0 +#define APM_AC_ONLINE 1 +#define APM_AC_BACKUP 2 +#define APM_AC_UNKNOWN 0xff + +#define APM_BATTERY_STATUS_HIGH 0 +#define APM_BATTERY_STATUS_LOW 1 +#define APM_BATTERY_STATUS_CRITICAL 2 +#define APM_BATTERY_STATUS_CHARGING 3 +#define APM_BATTERY_STATUS_NOT_PRESENT 4 +#define APM_BATTERY_STATUS_UNKNOWN 0xff + +struct yeeloong_power_info { + unsigned int ac_in; /* AC insert or no */ + unsigned int bat_in; /* Battery insert or no */ + + /* we use capacity for caculating the life and time */ + unsigned int curr_cap; + + /* battery designed capacity */ + unsigned int design_cap; + /* battery designed voltage */ + unsigned int design_vol; + /* battery capacity after full charged */ + unsigned int full_charged_cap; + /* battery vendor number */ + unsigned char vendor; + /* battery cell count */ + unsigned char cell_count; + + /* battery dynamic charge/discharge voltage */ + unsigned int voltage_now; + /* battery dynamic charge/discharge current */ + int current_now; + /* battery current temperature */ + unsigned int temperature; + unsigned int remain_time; + unsigned int health; + unsigned int charge_status; +}; + +struct yeeloong_power_info *power_info; + +static struct power_supply yeeloong_ac, yeeloong_bat; + +/********************************************************** + * Get power supply status * + **********************************************************/ +static void yeeloong_read_bat_status(void) +{ + unsigned int charge, status, health, state; + + /* fixed value */ + power_info->design_cap = (ec_read(REG_BAT_DESIGN_CAP_HIGH) << 8) + | ec_read(REG_BAT_DESIGN_CAP_LOW); + power_info->design_vol = (ec_read(REG_BAT_DESIGN_VOL_HIGH) << 8) + | ec_read(REG_BAT_DESIGN_VOL_LOW); + power_info->full_charged_cap = (ec_read(REG_BAT_FULLCHG_CAP_HIGH) << 8) + | ec_read(REG_BAT_FULLCHG_CAP_LOW); + + /* dynamic value */ + power_info->voltage_now = (ec_read(REG_BAT_VOLTAGE_HIGH) << 8) + | (ec_read(REG_BAT_VOLTAGE_LOW)); + power_info->current_now = (ec_read(REG_BAT_CURRENT_HIGH) << 8) + | (ec_read(REG_BAT_CURRENT_LOW)); + if(power_info->current_now & 0x8000) + power_info->current_now = 0xffff - power_info->current_now; + power_info->temperature = (ec_read(REG_BAT_TEMPERATURE_HIGH) << 8) + | (ec_read(REG_BAT_TEMPERATURE_LOW)); + power_info->curr_cap = (ec_read(REG_BAT_RELATIVE_CAP_HIGH) << 8) + | (ec_read(REG_BAT_RELATIVE_CAP_LOW)); + power_info->ac_in = ((ec_read(REG_BAT_POWER)) & BIT_BAT_POWER_ACIN) + ? APM_AC_ONLINE : APM_AC_OFFLINE; + + status = ec_read(REG_BAT_STATUS); + charge = ec_read(REG_BAT_CHARGE); + health = ec_read(REG_BAT_CHARGE_STATUS); + state = ec_read(REG_BAT_STATE); /* This register is no need ? */ + + power_info->bat_in = status & BIT_BAT_STATUS_IN; + if(power_info->bat_in) /* we assume that the health is good */ + power_info->health = POWER_SUPPLY_HEALTH_GOOD; + else{ /* no battery present */ + power_info->health = POWER_SUPPLY_HEALTH_UNKNOWN; + power_info->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; + } + + if(status & (BIT_BAT_STATUS_DESTROY | BIT_BAT_STATUS_LOW)) + power_info->health = POWER_SUPPLY_HEALTH_DEAD; + if(status & BIT_BAT_STATUS_FULL ){ + power_info->charge_status = POWER_SUPPLY_STATUS_FULL; + power_info->curr_cap = 100; + } + + if(health & BIT_BAT_CHARGE_STATUS_OVERTEMP) + power_info->health = POWER_SUPPLY_HEALTH_OVERHEAT; + + if(charge & FLAG_BAT_CHARGE_DISCHARGE) + power_info->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; + else if (charge & FLAG_BAT_CHARGE_CHARGE) + power_info->charge_status = POWER_SUPPLY_STATUS_CHARGING; +} + +/********************************************************************* + * Power properties + *********************************************************************/ + +static int yeeloong_get_ac_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = power_info->ac_in; + break; + default: + return -EINVAL; + } + + return 0; +} + +static enum power_supply_property yeeloong_ac_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static struct power_supply yeeloong_ac = { + .name = "yeeloong-ac", + .type = POWER_SUPPLY_TYPE_MAINS, + .properties = yeeloong_ac_props, + .num_properties = ARRAY_SIZE(yeeloong_ac_props), + .get_property = yeeloong_get_ac_prop, +}; + +/********************************************************************* + * Battery properties + *********************************************************************/ + +static int yeeloong_bat_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + + unsigned int ac_in, bat_in; + + ac_in = power_info->ac_in; + bat_in = power_info->bat_in; + yeeloong_read_bat_status(); + if(ac_in != power_info->ac_in) + power_supply_changed(&yeeloong_ac); + if(bat_in != power_info->bat_in) + power_supply_changed(&yeeloong_bat); + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + val->intval = power_info->charge_status; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = power_info->bat_in; + break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: + val->intval = power_info->design_vol * 1000; /* mV -> µV */ + break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + val->intval = power_info->design_cap * 1000; /* mA -> µA */ + break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + val->intval = power_info->full_charged_cap * 1000;/* µA */ + break; + case POWER_SUPPLY_PROP_HEALTH: + val->intval = power_info->health; + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + val->intval = power_info->current_now * 1000; /* mA -> µA */ + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval = power_info->voltage_now * 1000; /* mV -> µV */ + break; + case POWER_SUPPLY_PROP_CAPACITY: + val->intval = power_info->curr_cap; /* percentage */ + break; + case POWER_SUPPLY_PROP_TEMP: + val->intval = power_info->temperature; /* Celcius */ + break; + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: + /* calculate the remain time, maybe it is wrong */ + if(power_info->bat_in != APM_BATTERY_STATUS_NOT_PRESENT) + power_info->remain_time = ((power_info->curr_cap - 3) * 54 + 142) / 60; + else + power_info->remain_time = 0x00; + val->intval = power_info->remain_time * 60; /* units sec */ + break; + default: + return -EINVAL; + } + + return 0; +} + +static enum power_supply_property yeeloong_bat_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_TEMP, +}; + +static struct power_supply yeeloong_bat = { + .name = "yeeloong-bat", + .type = POWER_SUPPLY_TYPE_BATTERY, + .properties = yeeloong_bat_props, + .num_properties = ARRAY_SIZE(yeeloong_bat_props), + .get_property = yeeloong_bat_get_property, +}; + +/* + * End battery driver + */ + +#define MAX_BRIGHTNESS 8 +#define DEFAULT_BRIGHTNESS (MAX_BRIGHTNESS - 1) + +static int yeeloong_set_brightness(struct backlight_device *bd) +{ + unsigned int level, current_level; + static unsigned int old_level; + + level = (bd->props.fb_blank == FB_BLANK_UNBLANK && + bd->props.power == FB_BLANK_UNBLANK) ? + bd->props.brightness : 0; + + if (level > MAX_BRIGHTNESS) + level = MAX_BRIGHTNESS; + else if (level < 0) + level = 0; + + /* avoid tune the brightness when the EC is tuning it */ + current_level = ec_read(REG_DISPLAY_BRIGHTNESS); +// if ((old_level == current_level) && (old_level != level)) + if (old_level != level) + ec_write(REG_DISPLAY_BRIGHTNESS, level); + old_level = level; + + return 0; +} + +static int yeeloong_get_brightness(struct backlight_device *bd) +{ + return (int)ec_read(REG_DISPLAY_BRIGHTNESS); +} + +static struct backlight_ops yeeloong_ops = { + .get_brightness = yeeloong_get_brightness, + .update_status = yeeloong_set_brightness, +}; + +static struct backlight_device *yeeloong_backlight_device; + + +/* + * Hwmon + */ + +/* fan speed divider */ +#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/ + +/* pwm(auto/manual) enable or not */ +static int yeeloong_get_fan_pwm_enable(void) +{ + int value = 0; + + /* This get the fan control method: auto or manual */ + value = ec_read(0xf459); + + return value; +} + +static void yeeloong_set_fan_pwm_enable(int manual) +{ + if (manual) + ec_write(0xf459, 1); + else + ec_write(0xf459, 0); +} + +static int yeeloong_get_fan_pwm(void) +{ + /* fan speed level */ + return ec_read(0xf4cc); +} + +static void yeeloong_set_fan_pwm(int value) +{ + int status; + + /* need to ensure the level?? */ + printk(KERN_INFO "fan pwm, value = %d\n", value); + + value = SENSORS_LIMIT(value, 0, 3); + + /* if value is not ZERO, we should ensure it is on */ + if (value != 0) { + status = ec_read(0xf4da); + if (status == 0) + ec_write(0xf4d2, 1); + } + /* 0xf4cc is for writing */ + ec_write(0xf4cc, value); +} + +static int yeeloong_get_fan_rpm(void) +{ + int value = 0; + + value = FAN_SPEED_DIVIDER / + (((ec_read(REG_FAN_SPEED_HIGH) & 0x0f) << 8) | + ec_read(REG_FAN_SPEED_LOW)); + + return value; +} + +/* Thermal subdriver + */ + +static int yeeloong_get_cpu_temp(void) +{ + int value; + + value = ec_read(REG_TEMPERATURE_VALUE); + + if (value & (1 << 7)) + value = (value & 0x7f) - 128; + else + value = value & 0xff; + + return value * 1000; +} + +static int parse_arg(const char *buf, unsigned long count, int *val) +{ + if (!count) + return 0; + if (sscanf(buf, "%i", val) != 1) + return -EINVAL; + return count; +} + +static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count) +{ + int rv, value; + + rv = parse_arg(buf, count, &value); + if (rv > 0) + set(value); + return rv; +} + +static ssize_t show_sys_hwmon(int (*get)(void), char *buf) +{ + return sprintf(buf, "%d\n", get()); +} + + +#define CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \ + static ssize_t show_##_name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ + { \ + return show_sys_hwmon(_set, buf); \ + } \ + static ssize_t store_##_name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ + { \ + return store_sys_hwmon(_get, buf, count); \ + } \ + static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0); + +CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, yeeloong_get_fan_rpm, NULL); +CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, + yeeloong_get_fan_pwm, yeeloong_set_fan_pwm); +CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, + yeeloong_get_fan_pwm_enable, yeeloong_set_fan_pwm_enable); +CREATE_SENSOR_ATTR(temp1_input, S_IRUGO, + yeeloong_get_cpu_temp, NULL); + +static ssize_t +show_name(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "yeeloong\n"); +} +static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); + +static struct attribute *hwmon_attributes[] = { + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_name.dev_attr.attr, + NULL +}; + +static struct attribute_group hwmon_attribute_group = { + .attrs = hwmon_attributes +}; + +struct device *yeeloong_sensors_device; + +#ifdef CONFIG_SUSPEND +static int yeeloong_suspend(struct platform_device *pdev, pm_message_t state) +{ + printk(KERN_INFO "yeeloong specific suspend\n"); + + /* minimize the speed of FAN */ + yeeloong_set_fan_pwm_enable(1); + yeeloong_set_fan_pwm(1); + + return 0; +} + +static int yeeloong_resume(struct platform_device *pdev) +{ + printk(KERN_INFO "yeeloong specific resume\n"); + + /* resume fan to auto mode */ + yeeloong_set_fan_pwm_enable(0); + + return 0; +} +#else +static int yeeloong_suspend(struct platform_device *pdev, pm_message_t state) +{ + return 0; +} +static int yeeloong_resume(struct platform_device *pdev) +{ + return 0; +} +#endif + +static struct platform_driver platform_driver = { + .driver = { + .name = "yeeloong-laptop", + .owner = THIS_MODULE, + }, +#ifdef CONFIG_PM + .suspend = yeeloong_suspend, + .resume = yeeloong_resume, +#endif +}; + +static struct platform_device *yeeloong_pdev; + +static ssize_t yeeloong_pdev_name_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "yeeloong laptop\n"); +} + +static struct device_attribute dev_attr_yeeloong_pdev_name = + __ATTR(name, S_IRUGO, yeeloong_pdev_name_show, NULL); + +/* report power state changes */ +void yeeloong_power_change_trigger_event(void) +{ + unsigned int ac_in, bat_in; + + ac_in = power_info->ac_in; + bat_in = power_info->bat_in; + + yeeloong_read_bat_status(); + + if(ac_in != power_info->ac_in) + power_supply_changed(&yeeloong_ac); + if(bat_in != power_info->bat_in) + power_supply_changed(&yeeloong_bat); +} + +static int __init yeeloong_init(void) +{ + int ret; + + /* Register platform stuff */ + ret = platform_driver_register(&platform_driver); + if (ret) + return ret; + yeeloong_pdev = platform_device_alloc("yeeloong-laptop", -1); + if (!yeeloong_pdev) { + ret = -ENOMEM; + platform_driver_unregister(&platform_driver); + return ret; + } + ret = platform_device_add(yeeloong_pdev); + if (ret) { + platform_device_put(yeeloong_pdev); + return ret; + } + + if (IS_ERR(yeeloong_pdev)) { + ret = PTR_ERR(yeeloong_pdev); + yeeloong_pdev = NULL; + printk(KERN_INFO "unable to register hwmon platform device\n"); + return ret; + } + ret = device_create_file(&yeeloong_pdev->dev, + &dev_attr_yeeloong_pdev_name); + if (ret) { + printk(KERN_INFO "unable to create sysfs hwmon device attributes\n"); + return ret; + } + + /* backlight */ + yeeloong_backlight_device = backlight_device_register( + "backlight0", + &yeeloong_pdev->dev, NULL, + &yeeloong_ops); + + if (IS_ERR(yeeloong_backlight_device)) { + ret = PTR_ERR(yeeloong_backlight_device); + yeeloong_backlight_device = NULL; + return ret; + } + + yeeloong_backlight_device->props.max_brightness = MAX_BRIGHTNESS; + yeeloong_backlight_device->props.brightness = DEFAULT_BRIGHTNESS; + backlight_update_status(yeeloong_backlight_device); + + /* sensors */ + yeeloong_sensors_device = hwmon_device_register(&yeeloong_pdev->dev); + if (IS_ERR(yeeloong_sensors_device)) { + printk(KERN_INFO "Could not register yeeloong hwmon device\n"); + return PTR_ERR(yeeloong_sensors_device); + } + ret = sysfs_create_group(&yeeloong_sensors_device->kobj, + &hwmon_attribute_group); + if (ret) { + sysfs_remove_group(&yeeloong_sensors_device->kobj, + &hwmon_attribute_group); + hwmon_device_unregister(yeeloong_sensors_device); + yeeloong_sensors_device = NULL; + } + /* ensure fan is set to auto mode */ + yeeloong_set_fan_pwm_enable(0); + + /* Register battery driver */ + power_info = kzalloc(sizeof(struct yeeloong_power_info),GFP_KERNEL); + if(!power_info) { + printk(KERN_ERR "Get memory failed.\n"); + return -ENOMEM; + } + + /* Battery vendor and cell */ + power_info->vendor = ec_read(REG_BAT_VENDOR); + power_info->cell_count = ec_read(REG_BAT_CELL_COUNT); + printk(KERN_INFO "Battery vendor: %s cell: %d\n", + (power_info->vendor == FLAG_BAT_VENDOR_SANYO)?"SANYO":"SIMPLO", power_info->cell_count); + + ret = power_supply_register(&yeeloong_pdev->dev, &yeeloong_ac); + if (ret) + goto ac_register_failed; + ret = power_supply_register(&yeeloong_pdev->dev, &yeeloong_bat); + if (ret) + goto battery_register_failed; + + ec_handler_install(SCI_EVENT_NUM_AC_BAT, yeeloong_power_change_trigger_event); + + goto success; + +battery_register_failed: + power_supply_unregister(&yeeloong_bat); +ac_register_failed: + power_supply_unregister(&yeeloong_ac); + kfree(power_info); +success: + return ret; +} + +static void __exit yeeloong_exit(void) +{ + /* Unregister battery driver */ + ec_handler_uninstall(SCI_EVENT_NUM_AC_BAT); + power_supply_unregister(&yeeloong_bat); + power_supply_unregister(&yeeloong_ac); + kfree(power_info); + + if (yeeloong_backlight_device) { + backlight_device_unregister(yeeloong_backlight_device); + yeeloong_backlight_device = NULL; + } + + if (yeeloong_sensors_device) { + sysfs_remove_group(&yeeloong_sensors_device->kobj, + &hwmon_attribute_group); + hwmon_device_unregister(yeeloong_sensors_device); + } + + if (yeeloong_pdev) { + platform_device_unregister(yeeloong_pdev); + } + platform_driver_unregister(&platform_driver); +} + +module_init(yeeloong_init); +module_exit(yeeloong_exit); + +MODULE_AUTHOR("Wu Zhangjin "); +MODULE_DESCRIPTION("YeeLoong laptop driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 60a0453..20fada7 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2272,6 +2272,13 @@ config MV643XX_ETH Some boards that use the Discovery chipset are the Momenco Ocelot C and Jaguar ATX and Pegasos II. +config TITAN_GE + bool "PMC-Sierra TITAN Gigabit Ethernet Support" + depends on PMC_YOSEMITE + help + This enables support for the the integrated ethernet of + PMC-Sierra's Titan SoC. + config QLA3XXX tristate "QLogic QLA3XXX Network Driver Support" depends on PCI diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 7629c90..284ed83 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -129,6 +129,8 @@ obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o obj-$(CONFIG_QLA3XXX) += qla3xxx.o +obj-$(CONFIG_TITAN_GE) += titan_mdio.o titan_ge.o + obj-$(CONFIG_PPP) += ppp_generic.o obj-$(CONFIG_PPP_ASYNC) += ppp_async.o obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o diff --git a/drivers/net/titan_ge.c b/drivers/net/titan_ge.c new file mode 100644 index 0000000..dc137bf --- /dev/null +++ b/drivers/net/titan_ge.c @@ -0,0 +1,2069 @@ +/* + * drivers/net/titan_ge.c - Driver for Titan ethernet ports + * + * Copyright (C) 2003 PMC-Sierra Inc. + * Author : Manish Lachwani (lachwani@pmc-sierra.com) + * + * 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. + */ + +/* + * The MAC unit of the Titan consists of the following: + * + * -> XDMA Engine to move data to from the memory to the MAC packet FIFO + * -> FIFO is where the incoming and outgoing data is placed + * -> TRTG is the unit that pulls the data from the FIFO for Tx and pushes + * the data into the FIFO for Rx + * -> TMAC is the outgoing MAC interface and RMAC is the incoming. + * -> AFX is the address filtering block + * -> GMII block to communicate with the PHY + * + * Rx will look like the following: + * GMII --> RMAC --> AFX --> TRTG --> Rx FIFO --> XDMA --> CPU memory + * + * Tx will look like the following: + * CPU memory --> XDMA --> Tx FIFO --> TRTG --> TMAC --> GMII + * + * The Titan driver has support for the following performance features: + * -> Rx side checksumming + * -> Jumbo Frames + * -> Interrupt Coalscing + * -> Rx NAPI + * -> SKB Recycling + * -> Transmit/Receive descriptors in SRAM + * -> Fast routing for IP forwarding + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* For MII specifc registers, titan_mdio.h should be included */ +#include + +#include +#include +#include +#include +#include +#include + +#include "titan_ge.h" +#include "titan_mdio.h" + +/* Static Function Declarations */ +static int titan_ge_eth_open(struct net_device *); +static void titan_ge_eth_stop(struct net_device *); +static struct net_device_stats *titan_ge_get_stats(struct net_device *); +static int titan_ge_init_rx_desc_ring(titan_ge_port_info *, int, int, + unsigned long, unsigned long, + unsigned long); +static int titan_ge_init_tx_desc_ring(titan_ge_port_info *, int, + unsigned long, unsigned long); + +static int titan_ge_open(struct net_device *); +static int titan_ge_start_xmit(struct sk_buff *, struct net_device *); +static int titan_ge_stop(struct net_device *); + +static unsigned long titan_ge_tx_coal(unsigned long, int); + +static void titan_ge_port_reset(unsigned int); +static int titan_ge_free_tx_queue(titan_ge_port_info *); +static int titan_ge_rx_task(struct net_device *, titan_ge_port_info *); +static int titan_ge_port_start(struct net_device *, titan_ge_port_info *); + +static int titan_ge_return_tx_desc(titan_ge_port_info *, int); + +/* + * Some configuration for the FIFO and the XDMA channel needs + * to be done only once for all the ports. This flag controls + * that + */ +static unsigned long config_done; + +/* + * One time out of memory flag + */ +static unsigned int oom_flag; + +static int titan_ge_poll(struct net_device *netdev, int *budget); + +static int titan_ge_receive_queue(struct net_device *, unsigned int); + +static struct platform_device *titan_ge_device[3]; + +/* MAC Address */ +extern unsigned char titan_ge_mac_addr_base[6]; + +unsigned long titan_ge_base; +static unsigned long titan_ge_sram; + +static char titan_string[] = "titan"; + +/* + * The Titan GE has two alignment requirements: + * -> skb->data to be cacheline aligned (32 byte) + * -> IP header alignment to 16 bytes + * + * The latter is not implemented. So, that results in an extra copy on + * the Rx. This is a big performance hog. For the former case, the + * dev_alloc_skb() has been replaced with titan_ge_alloc_skb(). The size + * requested is calculated: + * + * Ethernet Frame Size : 1518 + * Ethernet Header : 14 + * Future Titan change for IP header alignment : 2 + * + * Hence, we allocate (1518 + 14 + 2+ 64) = 1580 bytes. For IP header + * alignment, we use skb_reserve(). + */ + +#define ALIGNED_RX_SKB_ADDR(addr) \ + ((((unsigned long)(addr) + (64UL - 1UL)) \ + & ~(64UL - 1UL)) - (unsigned long)(addr)) + +#define titan_ge_alloc_skb(__length, __gfp_flags) \ +({ struct sk_buff *__skb; \ + __skb = alloc_skb((__length) + 64, (__gfp_flags)); \ + if(__skb) { \ + int __offset = (int) ALIGNED_RX_SKB_ADDR(__skb->data); \ + if(__offset) \ + skb_reserve(__skb, __offset); \ + } \ + __skb; \ +}) + +/* + * Configure the GMII block of the Titan based on what the PHY tells us + */ +static void titan_ge_gmii_config(int port_num) +{ + unsigned int reg_data = 0, phy_reg; + int err; + + err = titan_ge_mdio_read(port_num, TITAN_GE_MDIO_PHY_STATUS, &phy_reg); + + if (err == TITAN_GE_MDIO_ERROR) { + printk(KERN_ERR + "Could not read PHY control register 0x11 \n"); + printk(KERN_ERR + "Setting speed to 1000 Mbps and Duplex to Full \n"); + + return; + } + + err = titan_ge_mdio_write(port_num, TITAN_GE_MDIO_PHY_IE, 0); + + if (phy_reg & 0x8000) { + if (phy_reg & 0x2000) { + /* Full Duplex and 1000 Mbps */ + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE + + (port_num << 12)), 0x201); + } else { + /* Half Duplex and 1000 Mbps */ + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE + + (port_num << 12)), 0x2201); + } + } + if (phy_reg & 0x4000) { + if (phy_reg & 0x2000) { + /* Full Duplex and 100 Mbps */ + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE + + (port_num << 12)), 0x100); + } else { + /* Half Duplex and 100 Mbps */ + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE + + (port_num << 12)), 0x2100); + } + } + reg_data = TITAN_GE_READ(TITAN_GE_GMII_CONFIG_GENERAL + + (port_num << 12)); + reg_data |= 0x3; + TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_GENERAL + + (port_num << 12)), reg_data); +} + +/* + * Enable the TMAC if it is not + */ +static void titan_ge_enable_tx(unsigned int port_num) +{ + unsigned long reg_data; + + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + (port_num << 12)); + if (!(reg_data & 0x8000)) { + printk("TMAC disabled for port %d!! \n", port_num); + + reg_data |= 0x0001; /* Enable TMAC */ + reg_data |= 0x4000; /* CRC Check Enable */ + reg_data |= 0x2000; /* Padding enable */ + reg_data |= 0x0800; /* CRC Add enable */ + reg_data |= 0x0080; /* PAUSE frame */ + + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 + + (port_num << 12)), reg_data); + } +} + +/* + * Tx Timeout function + */ +static void titan_ge_tx_timeout(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + + printk(KERN_INFO "%s: TX timeout ", netdev->name); + printk(KERN_INFO "Resetting card \n"); + + /* Do the reset outside of interrupt context */ + schedule_work(&titan_ge_eth->tx_timeout_task); +} + +/* + * Update the AFX tables for UC and MC for slice 0 only + */ +static void titan_ge_update_afx(titan_ge_port_info * titan_ge_eth) +{ + int port = titan_ge_eth->port_num; + unsigned int i; + volatile unsigned long reg_data = 0; + u8 p_addr[6]; + + memcpy(p_addr, titan_ge_eth->port_mac_addr, 6); + + /* Set the MAC address here for TMAC and RMAC */ + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_HI + (port << 12)), + ((p_addr[5] << 8) | p_addr[4])); + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_MID + (port << 12)), + ((p_addr[3] << 8) | p_addr[2])); + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_LOW + (port << 12)), + ((p_addr[1] << 8) | p_addr[0])); + + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_HI + (port << 12)), + ((p_addr[5] << 8) | p_addr[4])); + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_MID + (port << 12)), + ((p_addr[3] << 8) | p_addr[2])); + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port << 12)), + ((p_addr[1] << 8) | p_addr[0])); + + TITAN_GE_WRITE((0x112c | (port << 12)), 0x1); + /* Configure the eight address filters */ + for (i = 0; i < 8; i++) { + /* Select each of the eight filters */ + TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_2 + + (port << 12)), i); + + /* Configure the match */ + reg_data = 0x9; /* Forward Enable Bit */ + TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_0 + + (port << 12)), reg_data); + + /* Finally, AFX Exact Match Address Registers */ + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_LOW + (port << 12)), + ((p_addr[1] << 8) | p_addr[0])); + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_MID + (port << 12)), + ((p_addr[3] << 8) | p_addr[2])); + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_HIGH + (port << 12)), + ((p_addr[5] << 8) | p_addr[4])); + + /* VLAN id set to 0 */ + TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_VID + + (port << 12)), 0); + } +} + +/* + * Actual Routine to reset the adapter when the timeout occurred + */ +static void titan_ge_tx_timeout_task(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + int port = titan_ge_eth->port_num; + + printk("Titan GE: Transmit timed out. Resetting ... \n"); + + /* Dump debug info */ + printk(KERN_ERR "TRTG cause : %x \n", + TITAN_GE_READ(0x100c + (port << 12))); + + /* Fix this for the other ports */ + printk(KERN_ERR "FIFO cause : %x \n", TITAN_GE_READ(0x482c)); + printk(KERN_ERR "IE cause : %x \n", TITAN_GE_READ(0x0040)); + printk(KERN_ERR "XDMA GDI ERROR : %x \n", + TITAN_GE_READ(0x5008 + (port << 8))); + printk(KERN_ERR "CHANNEL ERROR: %x \n", + TITAN_GE_READ(TITAN_GE_CHANNEL0_INTERRUPT + + (port << 8))); + + netif_device_detach(netdev); + titan_ge_port_reset(titan_ge_eth->port_num); + titan_ge_port_start(netdev, titan_ge_eth); + netif_device_attach(netdev); +} + +/* + * Change the MTU of the Ethernet Device + */ +static int titan_ge_change_mtu(struct net_device *netdev, int new_mtu) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + unsigned long flags; + + if ((new_mtu > 9500) || (new_mtu < 64)) + return -EINVAL; + + spin_lock_irqsave(&titan_ge_eth->lock, flags); + + netdev->mtu = new_mtu; + + /* Now we have to reopen the interface so that SKBs with the new + * size will be allocated */ + + if (netif_running(netdev)) { + titan_ge_eth_stop(netdev); + + if (titan_ge_eth_open(netdev) != TITAN_OK) { + printk(KERN_ERR + "%s: Fatal error on opening device\n", + netdev->name); + spin_unlock_irqrestore(&titan_ge_eth->lock, flags); + return -1; + } + } + + spin_unlock_irqrestore(&titan_ge_eth->lock, flags); + return 0; +} + +/* + * Titan Gbe Interrupt Handler. All the three ports send interrupt to one line + * only. Once an interrupt is triggered, figure out the port and then check + * the channel. + */ +static irqreturn_t titan_ge_int_handler(int irq, void *dev_id) +{ + struct net_device *netdev = (struct net_device *) dev_id; + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + unsigned int port_num = titan_ge_eth->port_num; + unsigned int reg_data; + unsigned int eth_int_cause_error = 0, is; + unsigned long eth_int_cause1; + int err = 0; +#ifdef CONFIG_SMP + unsigned long eth_int_cause2; +#endif + + /* Ack the CPU interrupt */ + switch (port_num) { + case 0: + is = OCD_READ(RM9000x2_OCD_INTP0STATUS1); + OCD_WRITE(RM9000x2_OCD_INTP0CLEAR1, is); + +#ifdef CONFIG_SMP + is = OCD_READ(RM9000x2_OCD_INTP1STATUS1); + OCD_WRITE(RM9000x2_OCD_INTP1CLEAR1, is); +#endif + break; + + case 1: + is = OCD_READ(RM9000x2_OCD_INTP0STATUS0); + OCD_WRITE(RM9000x2_OCD_INTP0CLEAR0, is); + +#ifdef CONFIG_SMP + is = OCD_READ(RM9000x2_OCD_INTP1STATUS0); + OCD_WRITE(RM9000x2_OCD_INTP1CLEAR0, is); +#endif + break; + + case 2: + is = OCD_READ(RM9000x2_OCD_INTP0STATUS4); + OCD_WRITE(RM9000x2_OCD_INTP0CLEAR4, is); + +#ifdef CONFIG_SMP + is = OCD_READ(RM9000x2_OCD_INTP1STATUS4); + OCD_WRITE(RM9000x2_OCD_INTP1CLEAR4, is); +#endif + } + + eth_int_cause1 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_A); +#ifdef CONFIG_SMP + eth_int_cause2 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_B); +#endif + + /* Spurious interrupt */ +#ifdef CONFIG_SMP + if ( (eth_int_cause1 == 0) && (eth_int_cause2 == 0)) { +#else + if (eth_int_cause1 == 0) { +#endif + eth_int_cause_error = TITAN_GE_READ(TITAN_GE_CHANNEL0_INTERRUPT + + (port_num << 8)); + + if (eth_int_cause_error == 0) + return IRQ_NONE; + } + + /* Handle Tx first. No need to ack interrupts */ +#ifdef CONFIG_SMP + if ( (eth_int_cause1 & 0x20202) || + (eth_int_cause2 & 0x20202) ) +#else + if (eth_int_cause1 & 0x20202) +#endif + titan_ge_free_tx_queue(titan_ge_eth); + + /* Handle the Rx next */ +#ifdef CONFIG_SMP + if ( (eth_int_cause1 & 0x10101) || + (eth_int_cause2 & 0x10101)) { +#else + if (eth_int_cause1 & 0x10101) { +#endif + if (netif_rx_schedule_prep(netdev)) { + unsigned int ack; + + ack = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE); + /* Disable Tx and Rx both */ + if (port_num == 0) + ack &= ~(0x3); + if (port_num == 1) + ack &= ~(0x300); + + if (port_num == 2) + ack &= ~(0x30000); + + /* Interrupts have been disabled */ + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, ack); + + __netif_rx_schedule(netdev); + } + } + + /* Handle error interrupts */ + if (eth_int_cause_error && (eth_int_cause_error != 0x2)) { + printk(KERN_ERR + "XDMA Channel Error : %x on port %d\n", + eth_int_cause_error, port_num); + + printk(KERN_ERR + "XDMA GDI Hardware error : %x on port %d\n", + TITAN_GE_READ(0x5008 + (port_num << 8)), port_num); + + printk(KERN_ERR + "XDMA currently has %d Rx descriptors \n", + TITAN_GE_READ(0x5048 + (port_num << 8))); + + printk(KERN_ERR + "XDMA currently has prefetcted %d Rx descriptors \n", + TITAN_GE_READ(0x505c + (port_num << 8))); + + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_INTERRUPT + + (port_num << 8)), eth_int_cause_error); + } + + /* + * PHY interrupt to inform abt the changes. Reading the + * PHY Status register will clear the interrupt + */ + if ((!(eth_int_cause1 & 0x30303)) && + (eth_int_cause_error == 0)) { + err = + titan_ge_mdio_read(port_num, + TITAN_GE_MDIO_PHY_IS, ®_data); + + if (reg_data & 0x0400) { + /* Link status change */ + titan_ge_mdio_read(port_num, + TITAN_GE_MDIO_PHY_STATUS, ®_data); + if (!(reg_data & 0x0400)) { + /* Link is down */ + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } else { + /* Link is up */ + netif_carrier_on(netdev); + netif_wake_queue(netdev); + + /* Enable the queue */ + titan_ge_enable_tx(port_num); + } + } + } + + return IRQ_HANDLED; +} + +/* + * Multicast and Promiscuous mode set. The + * set_multi entry point is called whenever the + * multicast address list or the network interface + * flags are updated. + */ +static void titan_ge_set_multi(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + unsigned int port_num = titan_ge_eth->port_num; + unsigned long reg_data; + + reg_data = TITAN_GE_READ(TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 + + (port_num << 12)); + + if (netdev->flags & IFF_PROMISC) { + reg_data |= 0x2; + } + else if (netdev->flags & IFF_ALLMULTI) { + reg_data |= 0x01; + reg_data |= 0x400; /* Use the 64-bit Multicast Hash bin */ + } + else { + reg_data = 0x2; + } + + TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 + + (port_num << 12)), reg_data); + if (reg_data & 0x01) { + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_LOW + + (port_num << 12)), 0xffff); + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_MIDLOW + + (port_num << 12)), 0xffff); + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_MIDHI + + (port_num << 12)), 0xffff); + TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_HI + + (port_num << 12)), 0xffff); + } +} + +/* + * Open the network device + */ +static int titan_ge_open(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + unsigned int port_num = titan_ge_eth->port_num; + unsigned int irq = TITAN_ETH_PORT_IRQ - port_num; + int retval; + + retval = request_irq(irq, titan_ge_int_handler, + SA_INTERRUPT | SA_SAMPLE_RANDOM , netdev->name, netdev); + + if (retval != 0) { + printk(KERN_ERR "Cannot assign IRQ number to TITAN GE \n"); + return -1; + } + + netdev->irq = irq; + printk(KERN_INFO "Assigned IRQ %d to port %d\n", irq, port_num); + + spin_lock_irq(&(titan_ge_eth->lock)); + + if (titan_ge_eth_open(netdev) != TITAN_OK) { + spin_unlock_irq(&(titan_ge_eth->lock)); + printk("%s: Error opening interface \n", netdev->name); + free_irq(netdev->irq, netdev); + return -EBUSY; + } + + spin_unlock_irq(&(titan_ge_eth->lock)); + + return 0; +} + +/* + * Allocate the SKBs for the Rx ring. Also used + * for refilling the queue + */ +static int titan_ge_rx_task(struct net_device *netdev, + titan_ge_port_info *titan_ge_port) +{ + struct device *device = &titan_ge_device[titan_ge_port->port_num]->dev; + volatile titan_ge_rx_desc *rx_desc; + struct sk_buff *skb; + int rx_used_desc; + int count = 0; + + while (titan_ge_port->rx_ring_skbs < titan_ge_port->rx_ring_size) { + + /* First try to get the skb from the recycler */ +#ifdef TITAN_GE_JUMBO_FRAMES + skb = titan_ge_alloc_skb(TITAN_GE_JUMBO_BUFSIZE, GFP_ATOMIC); +#else + skb = titan_ge_alloc_skb(TITAN_GE_STD_BUFSIZE, GFP_ATOMIC); +#endif + if (unlikely(!skb)) { + /* OOM, set the flag */ + printk("OOM \n"); + oom_flag = 1; + break; + } + count++; + skb->dev = netdev; + + titan_ge_port->rx_ring_skbs++; + + rx_used_desc = titan_ge_port->rx_used_desc_q; + rx_desc = &(titan_ge_port->rx_desc_area[rx_used_desc]); + +#ifdef TITAN_GE_JUMBO_FRAMES + rx_desc->buffer_addr = dma_map_single(device, skb->data, + TITAN_GE_JUMBO_BUFSIZE - 2, DMA_FROM_DEVICE); +#else + rx_desc->buffer_addr = dma_map_single(device, skb->data, + TITAN_GE_STD_BUFSIZE - 2, DMA_FROM_DEVICE); +#endif + + titan_ge_port->rx_skb[rx_used_desc] = skb; + rx_desc->cmd_sts = TITAN_GE_RX_BUFFER_OWNED; + + titan_ge_port->rx_used_desc_q = + (rx_used_desc + 1) % TITAN_GE_RX_QUEUE; + } + + return count; +} + +/* + * Actual init of the Tital GE port. There is one register for + * the channel configuration + */ +static void titan_port_init(struct net_device *netdev, + titan_ge_port_info * titan_ge_eth) +{ + unsigned long reg_data; + + titan_ge_port_reset(titan_ge_eth->port_num); + + /* First reset the TMAC */ + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG); + reg_data |= 0x80000000; + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data); + + udelay(30); + + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG); + reg_data &= ~(0xc0000000); + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data); + + /* Now reset the RMAC */ + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG); + reg_data |= 0x00080000; + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data); + + udelay(30); + + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG); + reg_data &= ~(0x000c0000); + TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data); +} + +/* + * Start the port. All the hardware specific configuration + * for the XDMA, Tx FIFO, Rx FIFO, TMAC, RMAC, TRTG and AFX + * go here + */ +static int titan_ge_port_start(struct net_device *netdev, + titan_ge_port_info * titan_port) +{ + volatile unsigned long reg_data, reg_data1; + int port_num = titan_port->port_num; + int count = 0; + unsigned long reg_data_1; + + if (config_done == 0) { + reg_data = TITAN_GE_READ(0x0004); + reg_data |= 0x100; + TITAN_GE_WRITE(0x0004, reg_data); + + reg_data &= ~(0x100); + TITAN_GE_WRITE(0x0004, reg_data); + + /* Turn on GMII/MII mode and turn off TBI mode */ + reg_data = TITAN_GE_READ(TITAN_GE_TSB_CTRL_1); + reg_data |= 0x00000700; + reg_data &= ~(0x00800000); /* Fencing */ + + TITAN_GE_WRITE(0x000c, 0x00001100); + + TITAN_GE_WRITE(TITAN_GE_TSB_CTRL_1, reg_data); + + /* Set the CPU Resource Limit register */ + TITAN_GE_WRITE(0x00f8, 0x8); + + /* Be conservative when using the BIU buffers */ + TITAN_GE_WRITE(0x0068, 0x4); + } + + titan_port->tx_threshold = 0; + titan_port->rx_threshold = 0; + + /* We need to write the descriptors for Tx and Rx */ + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_TX_DESC + (port_num << 8)), + (unsigned long) titan_port->tx_dma); + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_RX_DESC + (port_num << 8)), + (unsigned long) titan_port->rx_dma); + + if (config_done == 0) { + /* Step 1: XDMA config */ + reg_data = TITAN_GE_READ(TITAN_GE_XDMA_CONFIG); + reg_data &= ~(0x80000000); /* clear reset */ + reg_data |= 0x1 << 29; /* sparse tx descriptor spacing */ + reg_data |= 0x1 << 28; /* sparse rx descriptor spacing */ + reg_data |= (0x1 << 23) | (0x1 << 24); /* Descriptor Coherency */ + reg_data |= (0x1 << 21) | (0x1 << 22); /* Data Coherency */ + TITAN_GE_WRITE(TITAN_GE_XDMA_CONFIG, reg_data); + } + + /* IR register for the XDMA */ + reg_data = TITAN_GE_READ(TITAN_GE_GDI_INTERRUPT_ENABLE + (port_num << 8)); + reg_data |= 0x80068000; /* No Rx_OOD */ + TITAN_GE_WRITE((TITAN_GE_GDI_INTERRUPT_ENABLE + (port_num << 8)), reg_data); + + /* Start the Tx and Rx XDMA controller */ + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG + (port_num << 8)); + reg_data &= 0x4fffffff; /* Clear tx reset */ + reg_data &= 0xfff4ffff; /* Clear rx reset */ + +#ifdef TITAN_GE_JUMBO_FRAMES + reg_data |= 0xa0 | 0x30030000; +#else + reg_data |= 0x40 | 0x20030000; +#endif + +#ifndef CONFIG_SMP + reg_data &= ~(0x10); + reg_data |= 0x0f; /* All of the packet */ +#endif + + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG + (port_num << 8)), reg_data); + + /* Rx desc count */ + count = titan_ge_rx_task(netdev, titan_port); + TITAN_GE_WRITE((0x5048 + (port_num << 8)), count); + count = TITAN_GE_READ(0x5048 + (port_num << 8)); + + udelay(30); + + /* + * Step 2: Configure the SDQPF, i.e. FIFO + */ + if (config_done == 0) { + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_CTL); + reg_data = 0x1; + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data); + reg_data &= ~(0x1); + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data); + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_CTL); + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data); + + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_CTL); + reg_data = 0x1; + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data); + reg_data &= ~(0x1); + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data); + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_CTL); + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data); + } + /* + * Enable RX FIFO 0, 4 and 8 + */ + if (port_num == 0) { + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_0); + + reg_data |= 0x100000; + reg_data |= (0xff << 10); + + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_0, reg_data); + /* + * BAV2,BAV and DAV settings for the Rx FIFO + */ + reg_data1 = TITAN_GE_READ(0x4844); + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1); + TITAN_GE_WRITE(0x4844, reg_data1); + + reg_data &= ~(0x00100000); + reg_data |= 0x200000; + + TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_0, reg_data); + + reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_0); + reg_data |= 0x100000; + + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data); + + reg_data |= (0xff << 10); + + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data); + + /* + * BAV2, BAV and DAV settings for the Tx FIFO + */ + reg_data1 = TITAN_GE_READ(0x4944); + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10); + + TITAN_GE_WRITE(0x4944, reg_data1); + + reg_data &= ~(0x00100000); + reg_data |= 0x200000; + + TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data); + + } + + if (port_num == 1) { + reg_data = TITAN_GE_READ(0x4870); + + reg_data |= 0x100000; + reg_data |= (0xff << 10) | (0xff + 1); + + TITAN_GE_WRITE(0x4870, reg_data); + /* + * BAV2,BAV and DAV settings for the Rx FIFO + */ + reg_data1 = TITAN_GE_READ(0x4874); + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1); + TITAN_GE_WRITE(0x4874, reg_data1); + + reg_data &= ~(0x00100000); + reg_data |= 0x200000; + + TITAN_GE_WRITE(0x4870, reg_data); + + reg_data = TITAN_GE_READ(0x494c); + reg_data |= 0x100000; + + TITAN_GE_WRITE(0x494c, reg_data); + reg_data |= (0xff << 10) | (0xff + 1); + TITAN_GE_WRITE(0x494c, reg_data); + + /* + * BAV2, BAV and DAV settings for the Tx FIFO + */ + reg_data1 = TITAN_GE_READ(0x4950); + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10); + + TITAN_GE_WRITE(0x4950, reg_data1); + + reg_data &= ~(0x00100000); + reg_data |= 0x200000; + + TITAN_GE_WRITE(0x494c, reg_data); + } + + /* + * Titan 1.2 revision does support port #2 + */ + if (port_num == 2) { + /* + * Put the descriptors in the SRAM + */ + reg_data = TITAN_GE_READ(0x48a0); + + reg_data |= 0x100000; + reg_data |= (0xff << 10) | (2*(0xff + 1)); + + TITAN_GE_WRITE(0x48a0, reg_data); + /* + * BAV2,BAV and DAV settings for the Rx FIFO + */ + reg_data1 = TITAN_GE_READ(0x48a4); + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1); + TITAN_GE_WRITE(0x48a4, reg_data1); + + reg_data &= ~(0x00100000); + reg_data |= 0x200000; + + TITAN_GE_WRITE(0x48a0, reg_data); + + reg_data = TITAN_GE_READ(0x4958); + reg_data |= 0x100000; + + TITAN_GE_WRITE(0x4958, reg_data); + reg_data |= (0xff << 10) | (2*(0xff + 1)); + TITAN_GE_WRITE(0x4958, reg_data); + + /* + * BAV2, BAV and DAV settings for the Tx FIFO + */ + reg_data1 = TITAN_GE_READ(0x495c); + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10); + + TITAN_GE_WRITE(0x495c, reg_data1); + + reg_data &= ~(0x00100000); + reg_data |= 0x200000; + + TITAN_GE_WRITE(0x4958, reg_data); + } + + if (port_num == 2) { + reg_data = TITAN_GE_READ(0x48a0); + + reg_data |= 0x100000; + reg_data |= (0xff << 10) | (2*(0xff + 1)); + + TITAN_GE_WRITE(0x48a0, reg_data); + /* + * BAV2,BAV and DAV settings for the Rx FIFO + */ + reg_data1 = TITAN_GE_READ(0x48a4); + reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1); + TITAN_GE_WRITE(0x48a4, reg_data1); + + reg_data &= ~(0x00100000); + reg_data |= 0x200000; + + TITAN_GE_WRITE(0x48a0, reg_data); + + reg_data = TITAN_GE_READ(0x4958); + reg_data |= 0x100000; + + TITAN_GE_WRITE(0x4958, reg_data); + reg_data |= (0xff << 10) | (2*(0xff + 1)); + TITAN_GE_WRITE(0x4958, reg_data); + + /* + * BAV2, BAV and DAV settings for the Tx FIFO + */ + reg_data1 = TITAN_GE_READ(0x495c); + reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10); + + TITAN_GE_WRITE(0x495c, reg_data1); + + reg_data &= ~(0x00100000); + reg_data |= 0x200000; + + TITAN_GE_WRITE(0x4958, reg_data); + } + + /* + * Step 3: TRTG block enable + */ + reg_data = TITAN_GE_READ(TITAN_GE_TRTG_CONFIG + (port_num << 12)); + + /* + * This is the 1.2 revision of the chip. It has fix for the + * IP header alignment. Now, the IP header begins at an + * aligned address and this wont need an extra copy in the + * driver. This performance drawback existed in the previous + * versions of the silicon + */ + reg_data_1 = TITAN_GE_READ(0x103c + (port_num << 12)); + reg_data_1 |= 0x40000000; + TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1); + + reg_data_1 |= 0x04000000; + TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1); + + mdelay(5); + + reg_data_1 &= ~(0x04000000); + TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1); + + mdelay(5); + + reg_data |= 0x0001; + TITAN_GE_WRITE((TITAN_GE_TRTG_CONFIG + (port_num << 12)), reg_data); + + /* + * Step 4: Start the Tx activity + */ + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_2 + (port_num << 12)), 0xe197); +#ifdef TITAN_GE_JUMBO_FRAMES + TITAN_GE_WRITE((0x1258 + (port_num << 12)), 0x4000); +#endif + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + (port_num << 12)); + reg_data |= 0x0001; /* Enable TMAC */ + reg_data |= 0x6c70; /* PAUSE also set */ + + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 + (port_num << 12)), reg_data); + + udelay(30); + + /* Destination Address drop bit */ + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_2 + (port_num << 12)); + reg_data |= 0x218; /* DA_DROP bit and pause */ + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_2 + (port_num << 12)), reg_data); + + TITAN_GE_WRITE((0x1218 + (port_num << 12)), 0x3); + +#ifdef TITAN_GE_JUMBO_FRAMES + TITAN_GE_WRITE((0x1208 + (port_num << 12)), 0x4000); +#endif + /* Start the Rx activity */ + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)); + reg_data |= 0x0001; /* RMAC Enable */ + reg_data |= 0x0010; /* CRC Check enable */ + reg_data |= 0x0040; /* Min Frame check enable */ + reg_data |= 0x4400; /* Max Frame check enable */ + + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)), reg_data); + + udelay(30); + + /* + * Enable the Interrupts for Tx and Rx + */ + reg_data1 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE); + + if (port_num == 0) { + reg_data1 |= 0x3; +#ifdef CONFIG_SMP + TITAN_GE_WRITE(0x0038, 0x003); +#else + TITAN_GE_WRITE(0x0038, 0x303); +#endif + } + + if (port_num == 1) { + reg_data1 |= 0x300; + } + + if (port_num == 2) + reg_data1 |= 0x30000; + + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data1); + TITAN_GE_WRITE(0x003c, 0x300); + + if (config_done == 0) { + TITAN_GE_WRITE(0x0024, 0x04000024); /* IRQ vector */ + TITAN_GE_WRITE(0x0020, 0x000fb000); /* INTMSG base */ + } + + /* Priority */ + reg_data = TITAN_GE_READ(0x1038 + (port_num << 12)); + reg_data &= ~(0x00f00000); + TITAN_GE_WRITE((0x1038 + (port_num << 12)), reg_data); + + /* Step 5: GMII config */ + titan_ge_gmii_config(port_num); + + if (config_done == 0) { + TITAN_GE_WRITE(0x1a80, 0); + config_done = 1; + } + + return TITAN_OK; +} + +/* + * Function to queue the packet for the Ethernet device + */ +static void titan_ge_tx_queue(titan_ge_port_info * titan_ge_eth, + struct sk_buff * skb) +{ + struct device *device = &titan_ge_device[titan_ge_eth->port_num]->dev; + unsigned int curr_desc = titan_ge_eth->tx_curr_desc_q; + volatile titan_ge_tx_desc *tx_curr; + int port_num = titan_ge_eth->port_num; + + tx_curr = &(titan_ge_eth->tx_desc_area[curr_desc]); + tx_curr->buffer_addr = + dma_map_single(device, skb->data, skb_headlen(skb), + DMA_TO_DEVICE); + + titan_ge_eth->tx_skb[curr_desc] = (struct sk_buff *) skb; + tx_curr->buffer_len = skb_headlen(skb); + + /* Last descriptor enables interrupt and changes ownership */ + tx_curr->cmd_sts = 0x1 | (1 << 15) | (1 << 5); + + /* Kick the XDMA to start the transfer from memory to the FIFO */ + TITAN_GE_WRITE((0x5044 + (port_num << 8)), 0x1); + + /* Current descriptor updated */ + titan_ge_eth->tx_curr_desc_q = (curr_desc + 1) % TITAN_GE_TX_QUEUE; + + /* Prefetch the next descriptor */ + prefetch((const void *) + &titan_ge_eth->tx_desc_area[titan_ge_eth->tx_curr_desc_q]); +} + +/* + * Actually does the open of the Ethernet device + */ +static int titan_ge_eth_open(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + unsigned int port_num = titan_ge_eth->port_num; + struct device *device = &titan_ge_device[port_num]->dev; + unsigned long reg_data; + unsigned int phy_reg; + int err = 0; + + /* Stop the Rx activity */ + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)); + reg_data &= ~(0x00000001); + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)), reg_data); + + /* Clear the port interrupts */ + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_INTERRUPT + (port_num << 8)), 0x0); + + if (config_done == 0) { + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0); + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_B, 0); + } + + /* Set the MAC Address */ + memcpy(titan_ge_eth->port_mac_addr, netdev->dev_addr, 6); + + if (config_done == 0) + titan_port_init(netdev, titan_ge_eth); + + titan_ge_update_afx(titan_ge_eth); + + /* Allocate the Tx ring now */ + titan_ge_eth->tx_ring_skbs = 0; + titan_ge_eth->tx_ring_size = TITAN_GE_TX_QUEUE; + + /* Allocate space in the SRAM for the descriptors */ + titan_ge_eth->tx_desc_area = (titan_ge_tx_desc *) + (titan_ge_sram + TITAN_TX_RING_BYTES * port_num); + titan_ge_eth->tx_dma = TITAN_SRAM_BASE + TITAN_TX_RING_BYTES * port_num; + + if (!titan_ge_eth->tx_desc_area) { + printk(KERN_ERR + "%s: Cannot allocate Tx Ring (size %d bytes) for port %d\n", + netdev->name, TITAN_TX_RING_BYTES, port_num); + return -ENOMEM; + } + + memset(titan_ge_eth->tx_desc_area, 0, titan_ge_eth->tx_desc_area_size); + + /* Now initialize the Tx descriptor ring */ + titan_ge_init_tx_desc_ring(titan_ge_eth, + titan_ge_eth->tx_ring_size, + (unsigned long) titan_ge_eth->tx_desc_area, + (unsigned long) titan_ge_eth->tx_dma); + + /* Allocate the Rx ring now */ + titan_ge_eth->rx_ring_size = TITAN_GE_RX_QUEUE; + titan_ge_eth->rx_ring_skbs = 0; + + titan_ge_eth->rx_desc_area = + (titan_ge_rx_desc *)(titan_ge_sram + 0x1000 + TITAN_RX_RING_BYTES * port_num); + + titan_ge_eth->rx_dma = TITAN_SRAM_BASE + 0x1000 + TITAN_RX_RING_BYTES * port_num; + + if (!titan_ge_eth->rx_desc_area) { + printk(KERN_ERR "%s: Cannot allocate Rx Ring (size %d bytes)\n", + netdev->name, TITAN_RX_RING_BYTES); + + printk(KERN_ERR "%s: Freeing previously allocated TX queues...", + netdev->name); + + dma_free_coherent(device, titan_ge_eth->tx_desc_area_size, + (void *) titan_ge_eth->tx_desc_area, + titan_ge_eth->tx_dma); + + return -ENOMEM; + } + + memset(titan_ge_eth->rx_desc_area, 0, titan_ge_eth->rx_desc_area_size); + + /* Now initialize the Rx ring */ +#ifdef TITAN_GE_JUMBO_FRAMES + if ((titan_ge_init_rx_desc_ring + (titan_ge_eth, titan_ge_eth->rx_ring_size, TITAN_GE_JUMBO_BUFSIZE, + (unsigned long) titan_ge_eth->rx_desc_area, 0, + (unsigned long) titan_ge_eth->rx_dma)) == 0) +#else + if ((titan_ge_init_rx_desc_ring + (titan_ge_eth, titan_ge_eth->rx_ring_size, TITAN_GE_STD_BUFSIZE, + (unsigned long) titan_ge_eth->rx_desc_area, 0, + (unsigned long) titan_ge_eth->rx_dma)) == 0) +#endif + panic("%s: Error initializing RX Ring\n", netdev->name); + + /* Fill the Rx ring with the SKBs */ + titan_ge_port_start(netdev, titan_ge_eth); + + /* + * Check if Interrupt Coalscing needs to be turned on. The + * values specified in the register is multiplied by + * (8 x 64 nanoseconds) to determine when an interrupt should + * be sent to the CPU. + */ + + if (TITAN_GE_TX_COAL) { + titan_ge_eth->tx_int_coal = + titan_ge_tx_coal(TITAN_GE_TX_COAL, port_num); + } + + err = titan_ge_mdio_read(port_num, TITAN_GE_MDIO_PHY_STATUS, &phy_reg); + if (err == TITAN_GE_MDIO_ERROR) { + printk(KERN_ERR + "Could not read PHY control register 0x11 \n"); + return TITAN_ERROR; + } + if (!(phy_reg & 0x0400)) { + netif_carrier_off(netdev); + netif_stop_queue(netdev); + return TITAN_ERROR; + } else { + netif_carrier_on(netdev); + netif_start_queue(netdev); + } + + return TITAN_OK; +} + +/* + * Queue the packet for Tx. Currently no support for zero copy, + * checksum offload and Scatter Gather. The chip does support + * Scatter Gather only. But, that wont help here since zero copy + * requires support for Tx checksumming also. + */ +int titan_ge_start_xmit(struct sk_buff *skb, struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + unsigned long flags; + struct net_device_stats *stats; +//printk("titan_ge_start_xmit\n"); + + stats = &titan_ge_eth->stats; + spin_lock_irqsave(&titan_ge_eth->lock, flags); + + if ((TITAN_GE_TX_QUEUE - titan_ge_eth->tx_ring_skbs) <= + (skb_shinfo(skb)->nr_frags + 1)) { + netif_stop_queue(netdev); + spin_unlock_irqrestore(&titan_ge_eth->lock, flags); + printk(KERN_ERR "Tx OOD \n"); + return 1; + } + + titan_ge_tx_queue(titan_ge_eth, skb); + titan_ge_eth->tx_ring_skbs++; + + if (TITAN_GE_TX_QUEUE <= (titan_ge_eth->tx_ring_skbs + 4)) { + spin_unlock_irqrestore(&titan_ge_eth->lock, flags); + titan_ge_free_tx_queue(titan_ge_eth); + spin_lock_irqsave(&titan_ge_eth->lock, flags); + } + + stats->tx_bytes += skb->len; + stats->tx_packets++; + + spin_unlock_irqrestore(&titan_ge_eth->lock, flags); + + netdev->trans_start = jiffies; + + return 0; +} + +/* + * Actually does the Rx. Rx side checksumming supported. + */ +static int titan_ge_rx(struct net_device *netdev, int port_num, + titan_ge_port_info * titan_ge_port, + titan_ge_packet * packet) +{ + int rx_curr_desc, rx_used_desc; + volatile titan_ge_rx_desc *rx_desc; + + rx_curr_desc = titan_ge_port->rx_curr_desc_q; + rx_used_desc = titan_ge_port->rx_used_desc_q; + + if (((rx_curr_desc + 1) % TITAN_GE_RX_QUEUE) == rx_used_desc) + return TITAN_ERROR; + + rx_desc = &(titan_ge_port->rx_desc_area[rx_curr_desc]); + + if (rx_desc->cmd_sts & TITAN_GE_RX_BUFFER_OWNED) + return TITAN_ERROR; + + packet->skb = titan_ge_port->rx_skb[rx_curr_desc]; + packet->len = (rx_desc->cmd_sts & 0x7fff); + + /* + * At this point, we dont know if the checksumming + * actually helps relieve CPU. So, keep it for + * port 0 only + */ + packet->checksum = ntohs((rx_desc->buffer & 0xffff0000) >> 16); + packet->cmd_sts = rx_desc->cmd_sts; + + titan_ge_port->rx_curr_desc_q = (rx_curr_desc + 1) % TITAN_GE_RX_QUEUE; + + /* Prefetch the next descriptor */ + prefetch((const void *) + &titan_ge_port->rx_desc_area[titan_ge_port->rx_curr_desc_q + 1]); + + return TITAN_OK; +} + +/* + * Free the Tx queue of the used SKBs + */ +static int titan_ge_free_tx_queue(titan_ge_port_info *titan_ge_eth) +{ + unsigned long flags; + + /* Take the lock */ + spin_lock_irqsave(&(titan_ge_eth->lock), flags); + + while (titan_ge_return_tx_desc(titan_ge_eth, titan_ge_eth->port_num) == 0) + if (titan_ge_eth->tx_ring_skbs != 1) + titan_ge_eth->tx_ring_skbs--; + + spin_unlock_irqrestore(&titan_ge_eth->lock, flags); + + return TITAN_OK; +} + +/* + * Threshold beyond which we do the cleaning of + * Tx queue and new allocation for the Rx + * queue + */ +#define TX_THRESHOLD 4 +#define RX_THRESHOLD 10 + +/* + * Receive the packets and send it to the kernel. + */ +static int titan_ge_receive_queue(struct net_device *netdev, unsigned int max) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + unsigned int port_num = titan_ge_eth->port_num; + titan_ge_packet packet; + struct net_device_stats *stats; + struct sk_buff *skb; + unsigned long received_packets = 0; + unsigned int ack; + + stats = &titan_ge_eth->stats; + + while ((--max) + && (titan_ge_rx(netdev, port_num, titan_ge_eth, &packet) == TITAN_OK)) { + skb = (struct sk_buff *) packet.skb; + + titan_ge_eth->rx_ring_skbs--; + + if (--titan_ge_eth->rx_work_limit < 0) + break; + received_packets++; + + stats->rx_packets++; + stats->rx_bytes += packet.len; + + if ((packet.cmd_sts & TITAN_GE_RX_PERR) || + (packet.cmd_sts & TITAN_GE_RX_OVERFLOW_ERROR) || + (packet.cmd_sts & TITAN_GE_RX_TRUNC) || + (packet.cmd_sts & TITAN_GE_RX_CRC_ERROR)) { + stats->rx_dropped++; + dev_kfree_skb_any(skb); + + continue; + } + /* + * Either support fast path or slow path. Decision + * making can really slow down the performance. The + * idea is to cut down the number of checks and improve + * the fastpath. + */ + + skb_put(skb, packet.len - 2); + + /* + * Increment data pointer by two since thats where + * the MAC starts + */ + skb_reserve(skb, 2); + skb->protocol = eth_type_trans(skb, netdev); + netif_receive_skb(skb); + + if (titan_ge_eth->rx_threshold > RX_THRESHOLD) { + ack = titan_ge_rx_task(netdev, titan_ge_eth); + TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack); + titan_ge_eth->rx_threshold = 0; + } else + titan_ge_eth->rx_threshold++; + + if (titan_ge_eth->tx_threshold > TX_THRESHOLD) { + titan_ge_eth->tx_threshold = 0; + titan_ge_free_tx_queue(titan_ge_eth); + } + else + titan_ge_eth->tx_threshold++; + + } + return received_packets; +} + + +/* + * Enable the Rx side interrupts + */ +static void titan_ge_enable_int(unsigned int port_num, + titan_ge_port_info *titan_ge_eth, + struct net_device *netdev) +{ + unsigned long reg_data = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE); + + if (port_num == 0) + reg_data |= 0x3; + if (port_num == 1) + reg_data |= 0x300; + if (port_num == 2) + reg_data |= 0x30000; + + /* Re-enable interrupts */ + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data); +} + +/* + * Main function to handle the polling for Rx side NAPI. + * Receive interrupts have been disabled at this point. + * The poll schedules the transmit followed by receive. + */ +static int titan_ge_poll(struct net_device *netdev, int *budget) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + int port_num = titan_ge_eth->port_num; + int work_done = 0; + unsigned long flags, status; + + titan_ge_eth->rx_work_limit = *budget; + if (titan_ge_eth->rx_work_limit > netdev->quota) + titan_ge_eth->rx_work_limit = netdev->quota; + + do { + /* Do the transmit cleaning work here */ + titan_ge_free_tx_queue(titan_ge_eth); + + /* Ack the Rx interrupts */ + if (port_num == 0) + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x3); + if (port_num == 1) + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x300); + if (port_num == 2) + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x30000); + + work_done += titan_ge_receive_queue(netdev, 0); + + /* Out of quota and there is work to be done */ + if (titan_ge_eth->rx_work_limit < 0) + goto not_done; + + /* Receive alloc_skb could lead to OOM */ + if (oom_flag == 1) { + oom_flag = 0; + goto oom; + } + + status = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_A); + } while (status & 0x30300); + + /* If we are here, then no more interrupts to process */ + goto done; + +not_done: + *budget -= work_done; + netdev->quota -= work_done; + return 1; + +oom: + printk(KERN_ERR "OOM \n"); + netif_rx_complete(netdev); + return 0; + +done: + /* + * No more packets on the poll list. Turn the interrupts + * back on and we should be able to catch the new + * packets in the interrupt handler + */ + if (!work_done) + work_done = 1; + + *budget -= work_done; + netdev->quota -= work_done; + + spin_lock_irqsave(&titan_ge_eth->lock, flags); + + /* Remove us from the poll list */ + netif_rx_complete(netdev); + + /* Re-enable interrupts */ + titan_ge_enable_int(port_num, titan_ge_eth, netdev); + + spin_unlock_irqrestore(&titan_ge_eth->lock, flags); + + return 0; +} + +/* + * Close the network device + */ +int titan_ge_stop(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + + spin_lock_irq(&(titan_ge_eth->lock)); + titan_ge_eth_stop(netdev); + free_irq(netdev->irq, netdev); + spin_unlock_irq(&titan_ge_eth->lock); + + return TITAN_OK; +} + +/* + * Free the Tx ring + */ +static void titan_ge_free_tx_rings(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + unsigned int port_num = titan_ge_eth->port_num; + unsigned int curr; + unsigned long reg_data; + + /* Stop the Tx DMA */ + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG + + (port_num << 8)); + reg_data |= 0xc0000000; + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG + + (port_num << 8)), reg_data); + + /* Disable the TMAC */ + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + + (port_num << 12)); + reg_data &= ~(0x00000001); + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 + + (port_num << 12)), reg_data); + + for (curr = 0; + (titan_ge_eth->tx_ring_skbs) && (curr < TITAN_GE_TX_QUEUE); + curr++) { + if (titan_ge_eth->tx_skb[curr]) { + dev_kfree_skb(titan_ge_eth->tx_skb[curr]); + titan_ge_eth->tx_ring_skbs--; + } + } + + if (titan_ge_eth->tx_ring_skbs != 0) + printk + ("%s: Error on Tx descriptor free - could not free %d" + " descriptors\n", netdev->name, + titan_ge_eth->tx_ring_skbs); + +#ifndef TITAN_RX_RING_IN_SRAM + dma_free_coherent(&titan_ge_device[port_num]->dev, + titan_ge_eth->tx_desc_area_size, + (void *) titan_ge_eth->tx_desc_area, + titan_ge_eth->tx_dma); +#endif +} + +/* + * Free the Rx ring + */ +static void titan_ge_free_rx_rings(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + unsigned int port_num = titan_ge_eth->port_num; + unsigned int curr; + unsigned long reg_data; + + /* Stop the Rx DMA */ + reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG + + (port_num << 8)); + reg_data |= 0x000c0000; + TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG + + (port_num << 8)), reg_data); + + /* Disable the RMAC */ + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + + (port_num << 12)); + reg_data &= ~(0x00000001); + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + + (port_num << 12)), reg_data); + + for (curr = 0; + titan_ge_eth->rx_ring_skbs && (curr < TITAN_GE_RX_QUEUE); + curr++) { + if (titan_ge_eth->rx_skb[curr]) { + dev_kfree_skb(titan_ge_eth->rx_skb[curr]); + titan_ge_eth->rx_ring_skbs--; + } + } + + if (titan_ge_eth->rx_ring_skbs != 0) + printk(KERN_ERR + "%s: Error in freeing Rx Ring. %d skb's still" + " stuck in RX Ring - ignoring them\n", netdev->name, + titan_ge_eth->rx_ring_skbs); + +#ifndef TITAN_RX_RING_IN_SRAM + dma_free_coherent(&titan_ge_device[port_num]->dev, + titan_ge_eth->rx_desc_area_size, + (void *) titan_ge_eth->rx_desc_area, + titan_ge_eth->rx_dma); +#endif +} + +/* + * Actually does the stop of the Ethernet device + */ +static void titan_ge_eth_stop(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + + netif_stop_queue(netdev); + + titan_ge_port_reset(titan_ge_eth->port_num); + + titan_ge_free_tx_rings(netdev); + titan_ge_free_rx_rings(netdev); + + /* Disable the Tx and Rx Interrupts for all channels */ + TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, 0x0); +} + +/* + * Update the MAC address. Note that we have to write the + * address in three station registers, 16 bits each. And this + * has to be done for TMAC and RMAC + */ +static void titan_ge_update_mac_address(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + unsigned int port_num = titan_ge_eth->port_num; + u8 p_addr[6]; + + memcpy(titan_ge_eth->port_mac_addr, netdev->dev_addr, 6); + memcpy(p_addr, netdev->dev_addr, 6); + + /* Update the Address Filtering Match tables */ + titan_ge_update_afx(titan_ge_eth); + + printk("Station MAC : %d %d %d %d %d %d \n", + p_addr[5], p_addr[4], p_addr[3], + p_addr[2], p_addr[1], p_addr[0]); + + /* Set the MAC address here for TMAC and RMAC */ + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_HI + (port_num << 12)), + ((p_addr[5] << 8) | p_addr[4])); + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_MID + (port_num << 12)), + ((p_addr[3] << 8) | p_addr[2])); + TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_LOW + (port_num << 12)), + ((p_addr[1] << 8) | p_addr[0])); + + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_HI + (port_num << 12)), + ((p_addr[5] << 8) | p_addr[4])); + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_MID + (port_num << 12)), + ((p_addr[3] << 8) | p_addr[2])); + TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port_num << 12)), + ((p_addr[1] << 8) | p_addr[0])); +} + +/* + * Set the MAC address of the Ethernet device + */ +static int titan_ge_set_mac_address(struct net_device *dev, void *addr) +{ + titan_ge_port_info *tp = netdev_priv(dev); + struct sockaddr *sa = addr; + + memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); + + spin_lock_irq(&tp->lock); + titan_ge_update_mac_address(dev); + spin_unlock_irq(&tp->lock); + + return 0; +} + +/* + * Get the Ethernet device stats + */ +static struct net_device_stats *titan_ge_get_stats(struct net_device *netdev) +{ + titan_ge_port_info *titan_ge_eth = netdev_priv(netdev); + + return &titan_ge_eth->stats; +} + +/* + * Initialize the Rx descriptor ring for the Titan Ge + */ +static int titan_ge_init_rx_desc_ring(titan_ge_port_info * titan_eth_port, + int rx_desc_num, + int rx_buff_size, + unsigned long rx_desc_base_addr, + unsigned long rx_buff_base_addr, + unsigned long rx_dma) +{ + volatile titan_ge_rx_desc *rx_desc; + unsigned long buffer_addr; + int index; + unsigned long titan_ge_rx_desc_bus = rx_dma; + + buffer_addr = rx_buff_base_addr; + rx_desc = (titan_ge_rx_desc *) rx_desc_base_addr; + + /* Check alignment */ + if (rx_buff_base_addr & 0xF) + return 0; + + /* Check Rx buffer size */ + if ((rx_buff_size < 8) || (rx_buff_size > TITAN_GE_MAX_RX_BUFFER)) + return 0; + + /* 64-bit alignment + if ((rx_buff_base_addr + rx_buff_size) & 0x7) + return 0; */ + + /* Initialize the Rx desc ring */ + for (index = 0; index < rx_desc_num; index++) { + titan_ge_rx_desc_bus += sizeof(titan_ge_rx_desc); + rx_desc[index].cmd_sts = 0; + rx_desc[index].buffer_addr = buffer_addr; + titan_eth_port->rx_skb[index] = NULL; + buffer_addr += rx_buff_size; + } + + titan_eth_port->rx_curr_desc_q = 0; + titan_eth_port->rx_used_desc_q = 0; + + titan_eth_port->rx_desc_area = (titan_ge_rx_desc *) rx_desc_base_addr; + titan_eth_port->rx_desc_area_size = + rx_desc_num * sizeof(titan_ge_rx_desc); + + titan_eth_port->rx_dma = rx_dma; + + return TITAN_OK; +} + +/* + * Initialize the Tx descriptor ring. Descriptors in the SRAM + */ +static int titan_ge_init_tx_desc_ring(titan_ge_port_info * titan_ge_port, + int tx_desc_num, + unsigned long tx_desc_base_addr, + unsigned long tx_dma) +{ + titan_ge_tx_desc *tx_desc; + int index; + unsigned long titan_ge_tx_desc_bus = tx_dma; + + if (tx_desc_base_addr & 0xF) + return 0; + + tx_desc = (titan_ge_tx_desc *) tx_desc_base_addr; + + for (index = 0; index < tx_desc_num; index++) { + titan_ge_port->tx_dma_array[index] = + (dma_addr_t) titan_ge_tx_desc_bus; + titan_ge_tx_desc_bus += sizeof(titan_ge_tx_desc); + tx_desc[index].cmd_sts = 0x0000; + tx_desc[index].buffer_len = 0; + tx_desc[index].buffer_addr = 0x00000000; + titan_ge_port->tx_skb[index] = NULL; + } + + titan_ge_port->tx_curr_desc_q = 0; + titan_ge_port->tx_used_desc_q = 0; + + titan_ge_port->tx_desc_area = (titan_ge_tx_desc *) tx_desc_base_addr; + titan_ge_port->tx_desc_area_size = + tx_desc_num * sizeof(titan_ge_tx_desc); + + titan_ge_port->tx_dma = tx_dma; + return TITAN_OK; +} + +/* + * Initialize the device as an Ethernet device + */ +static int __init titan_ge_probe(struct device *device) +{ + titan_ge_port_info *titan_ge_eth; + struct net_device *netdev; + int port = to_platform_device(device)->id; + int err; + + netdev = alloc_etherdev(sizeof(titan_ge_port_info)); + if (!netdev) { + err = -ENODEV; + goto out; + } + + netdev->open = titan_ge_open; + netdev->stop = titan_ge_stop; + netdev->hard_start_xmit = titan_ge_start_xmit; + netdev->get_stats = titan_ge_get_stats; + netdev->set_multicast_list = titan_ge_set_multi; + netdev->set_mac_address = titan_ge_set_mac_address; + + /* Tx timeout */ + netdev->tx_timeout = titan_ge_tx_timeout; + netdev->watchdog_timeo = 2 * HZ; + + /* Set these to very high values */ + netdev->poll = titan_ge_poll; + netdev->weight = 64; + + netdev->tx_queue_len = TITAN_GE_TX_QUEUE; + netif_carrier_off(netdev); + netdev->base_addr = 0; + + netdev->change_mtu = titan_ge_change_mtu; + + titan_ge_eth = netdev_priv(netdev); + /* Allocation of memory for the driver structures */ + + titan_ge_eth->port_num = port; + + /* Configure the Tx timeout handler */ + INIT_WORK(&titan_ge_eth->tx_timeout_task, + (void (*)(void *)) titan_ge_tx_timeout_task, netdev); + + spin_lock_init(&titan_ge_eth->lock); + + /* set MAC addresses */ + memcpy(netdev->dev_addr, titan_ge_mac_addr_base, 6); + netdev->dev_addr[5] += port; + + err = register_netdev(netdev); + + if (err) + goto out_free_netdev; + + printk(KERN_NOTICE + "%s: port %d with MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", + netdev->name, port, netdev->dev_addr[0], + netdev->dev_addr[1], netdev->dev_addr[2], + netdev->dev_addr[3], netdev->dev_addr[4], + netdev->dev_addr[5]); + + printk(KERN_NOTICE "Rx NAPI supported, Tx Coalescing ON \n"); + + return 0; + +out_free_netdev: + kfree(netdev); + +out: + return err; +} + +static void __devexit titan_device_remove(struct device *device) +{ +} + +/* + * Reset the Ethernet port + */ +static void titan_ge_port_reset(unsigned int port_num) +{ + unsigned int reg_data; + + /* Stop the Tx port activity */ + reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + + (port_num << 12)); + reg_data &= ~(0x0001); + TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 + + (port_num << 12)), reg_data); + + /* Stop the Rx port activity */ + reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + + (port_num << 12)); + reg_data &= ~(0x0001); + TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + + (port_num << 12)), reg_data); + + return; +} + +/* + * Return the Tx desc after use by the XDMA + */ +static int titan_ge_return_tx_desc(titan_ge_port_info * titan_ge_eth, int port) +{ + int tx_desc_used; + struct sk_buff *skb; + + tx_desc_used = titan_ge_eth->tx_used_desc_q; + + /* return right away */ + if (tx_desc_used == titan_ge_eth->tx_curr_desc_q) + return TITAN_ERROR; + + /* Now the critical stuff */ + skb = titan_ge_eth->tx_skb[tx_desc_used]; + + dev_kfree_skb_any(skb); + + titan_ge_eth->tx_skb[tx_desc_used] = NULL; + titan_ge_eth->tx_used_desc_q = + (tx_desc_used + 1) % TITAN_GE_TX_QUEUE; + + return 0; +} + +/* + * Coalescing for the Tx path + */ +static unsigned long titan_ge_tx_coal(unsigned long delay, int port) +{ + unsigned long rx_delay; + + rx_delay = TITAN_GE_READ(TITAN_GE_INT_COALESCING); + delay = (delay << 16) | rx_delay; + + TITAN_GE_WRITE(TITAN_GE_INT_COALESCING, delay); + TITAN_GE_WRITE(0x5038, delay); + + return delay; +} + +static struct device_driver titan_soc_driver = { + .name = titan_string, + .bus = &platform_bus_type, + .probe = titan_ge_probe, + .remove = __devexit_p(titan_device_remove), +}; + +static void titan_platform_release (struct device *device) +{ + struct platform_device *pldev; + + /* free device */ + pldev = to_platform_device (device); + kfree (pldev); +} + +/* + * Register the Titan GE with the kernel + */ +static int __init titan_ge_init_module(void) +{ + struct platform_device *pldev; + unsigned int version, device; + int i; + + printk(KERN_NOTICE + "PMC-Sierra TITAN 10/100/1000 Ethernet Driver \n"); + + titan_ge_base = (unsigned long) ioremap(TITAN_GE_BASE, TITAN_GE_SIZE); + if (!titan_ge_base) { + printk("Mapping Titan GE failed\n"); + goto out; + } + + device = TITAN_GE_READ(TITAN_GE_DEVICE_ID); + version = (device & 0x000f0000) >> 16; + device &= 0x0000ffff; + + printk(KERN_NOTICE "Device Id : %x, Version : %x \n", device, version); + +#ifdef TITAN_RX_RING_IN_SRAM + titan_ge_sram = (unsigned long) ioremap(TITAN_SRAM_BASE, + TITAN_SRAM_SIZE); + if (!titan_ge_sram) { + printk("Mapping Titan SRAM failed\n"); + goto out_unmap_ge; + } +#endif + + if (driver_register(&titan_soc_driver)) { + printk(KERN_ERR "Driver registration failed\n"); + goto out_unmap_sram; + } + + for (i = 0; i < 3; i++) { + titan_ge_device[i] = NULL; + + if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) + continue; + + memset (pldev, 0, sizeof (*pldev)); + pldev->name = titan_string; + pldev->id = i; + pldev->dev.release = titan_platform_release; + titan_ge_device[i] = pldev; + + if (platform_device_register (pldev)) { + kfree (pldev); + titan_ge_device[i] = NULL; + continue; + } + + if (!pldev->dev.driver) { + /* + * The driver was not bound to this device, there was + * no hardware at this address. Unregister it, as the + * release fuction will take care of freeing the + * allocated structure + */ + titan_ge_device[i] = NULL; + platform_device_unregister (pldev); + } + } + + return 0; + +out_unmap_sram: + iounmap((void *)titan_ge_sram); + +out_unmap_ge: + iounmap((void *)titan_ge_base); + +out: + return -ENOMEM; +} + +/* + * Unregister the Titan GE from the kernel + */ +static void __exit titan_ge_cleanup_module(void) +{ + int i; + + driver_unregister(&titan_soc_driver); + + for (i = 0; i < 3; i++) { + if (titan_ge_device[i]) { + platform_device_unregister (titan_ge_device[i]); + titan_ge_device[i] = NULL; + } + } + + iounmap((void *)titan_ge_sram); + iounmap((void *)titan_ge_base); +} + +MODULE_AUTHOR("Manish Lachwani "); +MODULE_DESCRIPTION("Titan GE Ethernet driver"); +MODULE_LICENSE("GPL"); + +module_init(titan_ge_init_module); +module_exit(titan_ge_cleanup_module); diff --git a/drivers/net/titan_ge.h b/drivers/net/titan_ge.h new file mode 100644 index 0000000..3719f78 --- /dev/null +++ b/drivers/net/titan_ge.h @@ -0,0 +1,415 @@ +#ifndef _TITAN_GE_H_ +#define _TITAN_GE_H_ + +#include +#include +#include +#include + +/* + * These functions should be later moved to a more generic location since there + * will be others accessing it also + */ + +/* + * This is the way it works: LKB5 Base is at 0x0128. TITAN_BASE is defined in + * include/asm/titan_dep.h. TITAN_GE_BASE is the value in the TITAN_GE_LKB5 + * register. + */ + +#define TITAN_GE_BASE 0xfe000000UL +#define TITAN_GE_SIZE 0x10000UL + +extern unsigned long titan_ge_base; + +#define TITAN_GE_WRITE(offset, data) \ + *(volatile u32 *)(titan_ge_base + (offset)) = (data) + +#define TITAN_GE_READ(offset) *(volatile u32 *)(titan_ge_base + (offset)) + +#ifndef msec_delay +#define msec_delay(x) do { if(in_interrupt()) { \ + /* Don't mdelay in interrupt context! */ \ + BUG(); \ + } else { \ + set_current_state(TASK_UNINTERRUPTIBLE); \ + schedule_timeout((x * HZ)/1000); \ + } } while(0) +#endif + +#define TITAN_GE_PORT_0 + +#define TITAN_SRAM_BASE ((OCD_READ(RM9000x2_OCD_LKB13) & ~1) << 4) +#define TITAN_SRAM_SIZE 0x2000UL + +/* + * We may need these constants + */ +#define TITAN_BIT0 0x00000001 +#define TITAN_BIT1 0x00000002 +#define TITAN_BIT2 0x00000004 +#define TITAN_BIT3 0x00000008 +#define TITAN_BIT4 0x00000010 +#define TITAN_BIT5 0x00000020 +#define TITAN_BIT6 0x00000040 +#define TITAN_BIT7 0x00000080 +#define TITAN_BIT8 0x00000100 +#define TITAN_BIT9 0x00000200 +#define TITAN_BIT10 0x00000400 +#define TITAN_BIT11 0x00000800 +#define TITAN_BIT12 0x00001000 +#define TITAN_BIT13 0x00002000 +#define TITAN_BIT14 0x00004000 +#define TITAN_BIT15 0x00008000 +#define TITAN_BIT16 0x00010000 +#define TITAN_BIT17 0x00020000 +#define TITAN_BIT18 0x00040000 +#define TITAN_BIT19 0x00080000 +#define TITAN_BIT20 0x00100000 +#define TITAN_BIT21 0x00200000 +#define TITAN_BIT22 0x00400000 +#define TITAN_BIT23 0x00800000 +#define TITAN_BIT24 0x01000000 +#define TITAN_BIT25 0x02000000 +#define TITAN_BIT26 0x04000000 +#define TITAN_BIT27 0x08000000 +#define TITAN_BIT28 0x10000000 +#define TITAN_BIT29 0x20000000 +#define TITAN_BIT30 0x40000000 +#define TITAN_BIT31 0x80000000 + +/* Flow Control */ +#define TITAN_GE_FC_NONE 0x0 +#define TITAN_GE_FC_FULL 0x1 +#define TITAN_GE_FC_TX_PAUSE 0x2 +#define TITAN_GE_FC_RX_PAUSE 0x3 + +/* Duplex Settings */ +#define TITAN_GE_FULL_DUPLEX 0x1 +#define TITAN_GE_HALF_DUPLEX 0x2 + +/* Speed settings */ +#define TITAN_GE_SPEED_1000 0x1 +#define TITAN_GE_SPEED_100 0x2 +#define TITAN_GE_SPEED_10 0x3 + +/* Debugging info only */ +#undef TITAN_DEBUG + +/* Keep the rings in the Titan's SSRAM */ +#define TITAN_RX_RING_IN_SRAM + +#ifdef CONFIG_64BIT +#define TITAN_GE_IE_MASK 0xfffffffffb001b64 +#define TITAN_GE_IE_STATUS 0xfffffffffb001b60 +#else +#define TITAN_GE_IE_MASK 0xfb001b64 +#define TITAN_GE_IE_STATUS 0xfb001b60 +#endif + +/* Support for Jumbo Frames */ +#undef TITAN_GE_JUMBO_FRAMES + +/* Rx buffer size */ +#ifdef TITAN_GE_JUMBO_FRAMES +#define TITAN_GE_JUMBO_BUFSIZE 9080 +#else +#define TITAN_GE_STD_BUFSIZE 1580 +#endif + +/* + * Tx and Rx Interrupt Coalescing parameter. These values are + * for 1 Ghz processor. Rx coalescing can be taken care of + * by NAPI. NAPI is adaptive and hence useful. Tx coalescing + * is not adaptive. Hence, these values need to be adjusted + * based on load, CPU speed etc. + */ +#define TITAN_GE_RX_COAL 150 +#define TITAN_GE_TX_COAL 300 + +#if defined(__BIG_ENDIAN) + +/* Define the Rx descriptor */ +typedef struct eth_rx_desc { + u32 reserved; /* Unused */ + u32 buffer_addr; /* CPU buffer address */ + u32 cmd_sts; /* Command and Status */ + u32 buffer; /* XDMA buffer address */ +} titan_ge_rx_desc; + +/* Define the Tx descriptor */ +typedef struct eth_tx_desc { + u16 cmd_sts; /* Command, Status and Buffer count */ + u16 buffer_len; /* Length of the buffer */ + u32 buffer_addr; /* Physical address of the buffer */ +} titan_ge_tx_desc; + +#elif defined(__LITTLE_ENDIAN) + +/* Define the Rx descriptor */ +typedef struct eth_rx_desc { + u32 buffer_addr; /* CPU buffer address */ + u32 reserved; /* Unused */ + u32 buffer; /* XDMA buffer address */ + u32 cmd_sts; /* Command and Status */ +} titan_ge_rx_desc; + +/* Define the Tx descriptor */ +typedef struct eth_tx_desc { + u32 buffer_addr; /* Physical address of the buffer */ + u16 buffer_len; /* Length of the buffer */ + u16 cmd_sts; /* Command, Status and Buffer count */ +} titan_ge_tx_desc; +#endif + +/* Default Tx Queue Size */ +#define TITAN_GE_TX_QUEUE 128 +#define TITAN_TX_RING_BYTES (TITAN_GE_TX_QUEUE * sizeof(struct eth_tx_desc)) + +/* Default Rx Queue Size */ +#define TITAN_GE_RX_QUEUE 64 +#define TITAN_RX_RING_BYTES (TITAN_GE_RX_QUEUE * sizeof(struct eth_rx_desc)) + +/* Packet Structure */ +typedef struct _pkt_info { + unsigned int len; + unsigned int cmd_sts; + unsigned int buffer; + struct sk_buff *skb; + unsigned int checksum; +} titan_ge_packet; + + +#define PHYS_CNT 3 + +/* Titan Port specific data structure */ +typedef struct _eth_port_ctrl { + unsigned int port_num; + u8 port_mac_addr[6]; + + /* Rx descriptor pointers */ + int rx_curr_desc_q, rx_used_desc_q; + + /* Tx descriptor pointers */ + int tx_curr_desc_q, tx_used_desc_q; + + /* Rx descriptor area */ + volatile titan_ge_rx_desc *rx_desc_area; + unsigned int rx_desc_area_size; + struct sk_buff* rx_skb[TITAN_GE_RX_QUEUE]; + + /* Tx Descriptor area */ + volatile titan_ge_tx_desc *tx_desc_area; + unsigned int tx_desc_area_size; + struct sk_buff* tx_skb[TITAN_GE_TX_QUEUE]; + + /* Timeout task */ + struct work_struct tx_timeout_task; + + /* DMA structures and handles */ + dma_addr_t tx_dma; + dma_addr_t rx_dma; + dma_addr_t tx_dma_array[TITAN_GE_TX_QUEUE]; + + /* Device lock */ + spinlock_t lock; + + unsigned int tx_ring_skbs; + unsigned int rx_ring_size; + unsigned int tx_ring_size; + unsigned int rx_ring_skbs; + + struct net_device_stats stats; + + /* Tx and Rx coalescing */ + unsigned long rx_int_coal; + unsigned long tx_int_coal; + + /* Threshold for replenishing the Rx and Tx rings */ + unsigned int tx_threshold; + unsigned int rx_threshold; + + /* NAPI work limit */ + unsigned int rx_work_limit; +} titan_ge_port_info; + +/* Titan specific constants */ +#define TITAN_ETH_PORT_IRQ 3 + +/* Max Rx buffer */ +#define TITAN_GE_MAX_RX_BUFFER 65536 + +/* Tx and Rx Error */ +#define TITAN_GE_ERROR + +/* Rx Descriptor Command and Status */ + +#define TITAN_GE_RX_CRC_ERROR TITAN_BIT27 /* crc error */ +#define TITAN_GE_RX_OVERFLOW_ERROR TITAN_BIT15 /* overflow */ +#define TITAN_GE_RX_BUFFER_OWNED TITAN_BIT21 /* buffer ownership */ +#define TITAN_GE_RX_STP TITAN_BIT31 /* start of packet */ +#define TITAN_GE_RX_BAM TITAN_BIT30 /* broadcast address match */ +#define TITAN_GE_RX_PAM TITAN_BIT28 /* physical address match */ +#define TITAN_GE_RX_LAFM TITAN_BIT29 /* logical address filter match */ +#define TITAN_GE_RX_VLAN TITAN_BIT26 /* virtual lans */ +#define TITAN_GE_RX_PERR TITAN_BIT19 /* packet error */ +#define TITAN_GE_RX_TRUNC TITAN_BIT20 /* packet size greater than 32 buffers */ + +/* Tx Descriptor Command */ +#define TITAN_GE_TX_BUFFER_OWNED TITAN_BIT5 /* buffer ownership */ +#define TITAN_GE_TX_ENABLE_INTERRUPT TITAN_BIT15 /* Interrupt Enable */ + +/* Return Status */ +#define TITAN_OK 0x1 /* Good Status */ +#define TITAN_ERROR 0x2 /* Error Status */ + +/* MIB specific register offset */ +#define TITAN_GE_MSTATX_STATS_BASE_LOW 0x0800 /* MSTATX COUNTL[15:0] */ +#define TITAN_GE_MSTATX_STATS_BASE_MID 0x0804 /* MSTATX COUNTM[15:0] */ +#define TITAN_GE_MSTATX_STATS_BASE_HI 0x0808 /* MSTATX COUNTH[7:0] */ +#define TITAN_GE_MSTATX_CONTROL 0x0828 /* MSTATX Control */ +#define TITAN_GE_MSTATX_VARIABLE_SELECT 0x082C /* MSTATX Variable Select */ + +/* MIB counter offsets, add to the TITAN_GE_MSTATX_STATS_BASE_XXX */ +#define TITAN_GE_MSTATX_RXFRAMESOK 0x0040 +#define TITAN_GE_MSTATX_RXOCTETSOK 0x0050 +#define TITAN_GE_MSTATX_RXFRAMES 0x0060 +#define TITAN_GE_MSTATX_RXOCTETS 0x0070 +#define TITAN_GE_MSTATX_RXUNICASTFRAMESOK 0x0080 +#define TITAN_GE_MSTATX_RXBROADCASTFRAMESOK 0x0090 +#define TITAN_GE_MSTATX_RXMULTICASTFRAMESOK 0x00A0 +#define TITAN_GE_MSTATX_RXTAGGEDFRAMESOK 0x00B0 +#define TITAN_GE_MSTATX_RXMACPAUSECONTROLFRAMESOK 0x00C0 +#define TITAN_GE_MSTATX_RXMACCONTROLFRAMESOK 0x00D0 +#define TITAN_GE_MSTATX_RXFCSERROR 0x00E0 +#define TITAN_GE_MSTATX_RXALIGNMENTERROR 0x00F0 +#define TITAN_GE_MSTATX_RXSYMBOLERROR 0x0100 +#define TITAN_GE_MSTATX_RXLAYER1ERROR 0x0110 +#define TITAN_GE_MSTATX_RXINRANGELENGTHERROR 0x0120 +#define TITAN_GE_MSTATX_RXLONGLENGTHERROR 0x0130 +#define TITAN_GE_MSTATX_RXLONGLENGTHCRCERROR 0x0140 +#define TITAN_GE_MSTATX_RXSHORTLENGTHERROR 0x0150 +#define TITAN_GE_MSTATX_RXSHORTLLENGTHCRCERROR 0x0160 +#define TITAN_GE_MSTATX_RXFRAMES64OCTETS 0x0170 +#define TITAN_GE_MSTATX_RXFRAMES65TO127OCTETS 0x0180 +#define TITAN_GE_MSTATX_RXFRAMES128TO255OCTETS 0x0190 +#define TITAN_GE_MSTATX_RXFRAMES256TO511OCTETS 0x01A0 +#define TITAN_GE_MSTATX_RXFRAMES512TO1023OCTETS 0x01B0 +#define TITAN_GE_MSTATX_RXFRAMES1024TO1518OCTETS 0x01C0 +#define TITAN_GE_MSTATX_RXFRAMES1519TOMAXSIZE 0x01D0 +#define TITAN_GE_MSTATX_RXSTATIONADDRESSFILTERED 0x01E0 +#define TITAN_GE_MSTATX_RXVARIABLE 0x01F0 +#define TITAN_GE_MSTATX_GENERICADDRESSFILTERED 0x0200 +#define TITAN_GE_MSTATX_UNICASTFILTERED 0x0210 +#define TITAN_GE_MSTATX_MULTICASTFILTERED 0x0220 +#define TITAN_GE_MSTATX_BROADCASTFILTERED 0x0230 +#define TITAN_GE_MSTATX_HASHFILTERED 0x0240 +#define TITAN_GE_MSTATX_TXFRAMESOK 0x0250 +#define TITAN_GE_MSTATX_TXOCTETSOK 0x0260 +#define TITAN_GE_MSTATX_TXOCTETS 0x0270 +#define TITAN_GE_MSTATX_TXTAGGEDFRAMESOK 0x0280 +#define TITAN_GE_MSTATX_TXMACPAUSECONTROLFRAMESOK 0x0290 +#define TITAN_GE_MSTATX_TXFCSERROR 0x02A0 +#define TITAN_GE_MSTATX_TXSHORTLENGTHERROR 0x02B0 +#define TITAN_GE_MSTATX_TXLONGLENGTHERROR 0x02C0 +#define TITAN_GE_MSTATX_TXSYSTEMERROR 0x02D0 +#define TITAN_GE_MSTATX_TXMACERROR 0x02E0 +#define TITAN_GE_MSTATX_TXCARRIERSENSEERROR 0x02F0 +#define TITAN_GE_MSTATX_TXSQETESTERROR 0x0300 +#define TITAN_GE_MSTATX_TXUNICASTFRAMESOK 0x0310 +#define TITAN_GE_MSTATX_TXBROADCASTFRAMESOK 0x0320 +#define TITAN_GE_MSTATX_TXMULTICASTFRAMESOK 0x0330 +#define TITAN_GE_MSTATX_TXUNICASTFRAMESATTEMPTED 0x0340 +#define TITAN_GE_MSTATX_TXBROADCASTFRAMESATTEMPTED 0x0350 +#define TITAN_GE_MSTATX_TXMULTICASTFRAMESATTEMPTED 0x0360 +#define TITAN_GE_MSTATX_TXFRAMES64OCTETS 0x0370 +#define TITAN_GE_MSTATX_TXFRAMES65TO127OCTETS 0x0380 +#define TITAN_GE_MSTATX_TXFRAMES128TO255OCTETS 0x0390 +#define TITAN_GE_MSTATX_TXFRAMES256TO511OCTETS 0x03A0 +#define TITAN_GE_MSTATX_TXFRAMES512TO1023OCTETS 0x03B0 +#define TITAN_GE_MSTATX_TXFRAMES1024TO1518OCTETS 0x03C0 +#define TITAN_GE_MSTATX_TXFRAMES1519TOMAXSIZE 0x03D0 +#define TITAN_GE_MSTATX_TXVARIABLE 0x03E0 +#define TITAN_GE_MSTATX_RXSYSTEMERROR 0x03F0 +#define TITAN_GE_MSTATX_SINGLECOLLISION 0x0400 +#define TITAN_GE_MSTATX_MULTIPLECOLLISION 0x0410 +#define TITAN_GE_MSTATX_DEFERREDXMISSIONS 0x0420 +#define TITAN_GE_MSTATX_LATECOLLISIONS 0x0430 +#define TITAN_GE_MSTATX_ABORTEDDUETOXSCOLLS 0x0440 + +/* Interrupt specific defines */ +#define TITAN_GE_DEVICE_ID 0x0000 /* Device ID */ +#define TITAN_GE_RESET 0x0004 /* Reset reg */ +#define TITAN_GE_TSB_CTRL_0 0x000C /* TSB Control reg 0 */ +#define TITAN_GE_TSB_CTRL_1 0x0010 /* TSB Control reg 1 */ +#define TITAN_GE_INTR_GRP0_STATUS 0x0040 /* General Interrupt Group 0 Status */ +#define TITAN_GE_INTR_XDMA_CORE_A 0x0048 /* XDMA Channel Interrupt Status, Core A*/ +#define TITAN_GE_INTR_XDMA_CORE_B 0x004C /* XDMA Channel Interrupt Status, Core B*/ +#define TITAN_GE_INTR_XDMA_IE 0x0058 /* XDMA Channel Interrupt Enable */ +#define TITAN_GE_SDQPF_ECC_INTR 0x480C /* SDQPF ECC Interrupt Status */ +#define TITAN_GE_SDQPF_RXFIFO_CTL 0x4828 /* SDQPF RxFifo Control and Interrupt Enb*/ +#define TITAN_GE_SDQPF_RXFIFO_INTR 0x482C /* SDQPF RxFifo Interrupt Status */ +#define TITAN_GE_SDQPF_TXFIFO_CTL 0x4928 /* SDQPF TxFifo Control and Interrupt Enb*/ +#define TITAN_GE_SDQPF_TXFIFO_INTR 0x492C /* SDQPF TxFifo Interrupt Status */ +#define TITAN_GE_SDQPF_RXFIFO_0 0x4840 /* SDQPF RxFIFO Enable */ +#define TITAN_GE_SDQPF_TXFIFO_0 0x4940 /* SDQPF TxFIFO Enable */ +#define TITAN_GE_XDMA_CONFIG 0x5000 /* XDMA Global Configuration */ +#define TITAN_GE_XDMA_INTR_SUMMARY 0x5010 /* XDMA Interrupt Summary */ +#define TITAN_GE_XDMA_BUFADDRPRE 0x5018 /* XDMA Buffer Address Prefix */ +#define TITAN_GE_XDMA_DESCADDRPRE 0x501C /* XDMA Descriptor Address Prefix */ +#define TITAN_GE_XDMA_PORTWEIGHT 0x502C /* XDMA Port Weight Configuration */ + +/* Rx MAC defines */ +#define TITAN_GE_RMAC_CONFIG_1 0x1200 /* RMAC Configuration 1 */ +#define TITAN_GE_RMAC_CONFIG_2 0x1204 /* RMAC Configuration 2 */ +#define TITAN_GE_RMAC_MAX_FRAME_LEN 0x1208 /* RMAC Max Frame Length */ +#define TITAN_GE_RMAC_STATION_HI 0x120C /* Rx Station Address High */ +#define TITAN_GE_RMAC_STATION_MID 0x1210 /* Rx Station Address Middle */ +#define TITAN_GE_RMAC_STATION_LOW 0x1214 /* Rx Station Address Low */ +#define TITAN_GE_RMAC_LINK_CONFIG 0x1218 /* RMAC Link Configuration */ + +/* Tx MAC defines */ +#define TITAN_GE_TMAC_CONFIG_1 0x1240 /* TMAC Configuration 1 */ +#define TITAN_GE_TMAC_CONFIG_2 0x1244 /* TMAC Configuration 2 */ +#define TITAN_GE_TMAC_IPG 0x1248 /* TMAC Inter-Packet Gap */ +#define TITAN_GE_TMAC_STATION_HI 0x124C /* Tx Station Address High */ +#define TITAN_GE_TMAC_STATION_MID 0x1250 /* Tx Station Address Middle */ +#define TITAN_GE_TMAC_STATION_LOW 0x1254 /* Tx Station Address Low */ +#define TITAN_GE_TMAC_MAX_FRAME_LEN 0x1258 /* TMAC Max Frame Length */ +#define TITAN_GE_TMAC_MIN_FRAME_LEN 0x125C /* TMAC Min Frame Length */ +#define TITAN_GE_TMAC_PAUSE_FRAME_TIME 0x1260 /* TMAC Pause Frame Time */ +#define TITAN_GE_TMAC_PAUSE_FRAME_INTERVAL 0x1264 /* TMAC Pause Frame Interval */ + +/* GMII register */ +#define TITAN_GE_GMII_INTERRUPT_STATUS 0x1348 /* GMII Interrupt Status */ +#define TITAN_GE_GMII_CONFIG_GENERAL 0x134C /* GMII Configuration General */ +#define TITAN_GE_GMII_CONFIG_MODE 0x1350 /* GMII Configuration Mode */ + +/* Tx and Rx XDMA defines */ +#define TITAN_GE_INT_COALESCING 0x5030 /* Interrupt Coalescing */ +#define TITAN_GE_CHANNEL0_CONFIG 0x5040 /* Channel 0 XDMA config */ +#define TITAN_GE_CHANNEL0_INTERRUPT 0x504c /* Channel 0 Interrupt Status */ +#define TITAN_GE_GDI_INTERRUPT_ENABLE 0x5050 /* IE for the GDI Errors */ +#define TITAN_GE_CHANNEL0_PACKET 0x5060 /* Channel 0 Packet count */ +#define TITAN_GE_CHANNEL0_BYTE 0x5064 /* Channel 0 Byte count */ +#define TITAN_GE_CHANNEL0_TX_DESC 0x5054 /* Channel 0 Tx first desc */ +#define TITAN_GE_CHANNEL0_RX_DESC 0x5058 /* Channel 0 Rx first desc */ + +/* AFX (Address Filter Exact) register offsets for Slice 0 */ +#define TITAN_GE_AFX_EXACT_MATCH_LOW 0x1100 /* AFX Exact Match Address Low*/ +#define TITAN_GE_AFX_EXACT_MATCH_MID 0x1104 /* AFX Exact Match Address Mid*/ +#define TITAN_GE_AFX_EXACT_MATCH_HIGH 0x1108 /* AFX Exact Match Address Hi */ +#define TITAN_GE_AFX_EXACT_MATCH_VID 0x110C /* AFX Exact Match VID */ +#define TITAN_GE_AFX_MULTICAST_HASH_LOW 0x1110 /* AFX Multicast HASH Low */ +#define TITAN_GE_AFX_MULTICAST_HASH_MIDLOW 0x1114 /* AFX Multicast HASH MidLow */ +#define TITAN_GE_AFX_MULTICAST_HASH_MIDHI 0x1118 /* AFX Multicast HASH MidHi */ +#define TITAN_GE_AFX_MULTICAST_HASH_HI 0x111C /* AFX Multicast HASH Hi */ +#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_0 0x1120 /* AFX Address Filter Ctrl 0 */ +#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 0x1124 /* AFX Address Filter Ctrl 1 */ +#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_2 0x1128 /* AFX Address Filter Ctrl 2 */ + +/* Traffic Groomer block */ +#define TITAN_GE_TRTG_CONFIG 0x1000 /* TRTG Config */ + +#endif /* _TITAN_GE_H_ */ + diff --git a/drivers/net/titan_mdio.c b/drivers/net/titan_mdio.c new file mode 100644 index 0000000..8a8785b --- /dev/null +++ b/drivers/net/titan_mdio.c @@ -0,0 +1,217 @@ +/* + * drivers/net/titan_mdio.c - Driver for Titan ethernet ports + * + * Copyright (C) 2003 PMC-Sierra Inc. + * Author : Manish Lachwani (lachwani@pmc-sierra.com) + * + * 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. + * + * Management Data IO (MDIO) driver for the Titan GMII. Interacts with the Marvel PHY + * on the Titan. No support for the TBI as yet. + * + */ + +#include "titan_mdio.h" + +#define MDIO_DEBUG + +/* + * Local constants + */ +#define MAX_CLKA 1023 +#define MAX_PHY_DEV 31 +#define MAX_PHY_REG 31 +#define WRITEADDRS_OPCODE 0x0 +#define READ_OPCODE 0x2 +#define WRITE_OPCODE 0x1 +#define MAX_MDIO_POLL 100 + +/* + * Titan MDIO and SCMB registers + */ +#define TITAN_GE_SCMB_CONTROL 0x01c0 /* SCMB Control */ +#define TITAN_GE_SCMB_CLKA 0x01c4 /* SCMB Clock A */ +#define TITAN_GE_MDIO_COMMAND 0x01d0 /* MDIO Command */ +#define TITAN_GE_MDIO_DEVICE_PORT_ADDRESS 0x01d4 /* MDIO Device and Port addrs */ +#define TITAN_GE_MDIO_DATA 0x01d8 /* MDIO Data */ +#define TITAN_GE_MDIO_INTERRUPTS 0x01dC /* MDIO Interrupts */ + +/* + * Function to poll the MDIO + */ +static int titan_ge_mdio_poll(void) +{ + int i, val; + + for (i = 0; i < MAX_MDIO_POLL; i++) { + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND); + + if (!(val & 0x8000)) + return TITAN_GE_MDIO_GOOD; + } + + return TITAN_GE_MDIO_ERROR; +} + + +/* + * Initialize and configure the MDIO + */ +int titan_ge_mdio_setup(titan_ge_mdio_config *titan_mdio) +{ + unsigned long val; + + /* Reset the SCMB and program into MDIO mode*/ + TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x9000); + TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x1000); + + /* CLK A */ + val = TITAN_GE_MDIO_READ(TITAN_GE_SCMB_CLKA); + val = ( (val & ~(0x03ff)) | (titan_mdio->clka & 0x03ff)); + TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CLKA, val); + + /* Preamble Suppresion */ + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND); + val = ( (val & ~(0x0001)) | (titan_mdio->mdio_spre & 0x0001)); + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val); + + /* MDIO mode */ + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS); + val = ( (val & ~(0x4000)) | (titan_mdio->mdio_mode & 0x4000)); + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val); + + return TITAN_GE_MDIO_GOOD; +} + +/* + * Set the PHY address in indirect mode + */ +int titan_ge_mdio_inaddrs(int dev_addr, int reg_addr) +{ + volatile unsigned long val; + + /* Setup the PHY device */ + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS); + val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00)); + val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f)); + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val); + + /* Write the new address */ + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND); + val = ( (val & ~(0x0300)) | ( (WRITEADDRS_OPCODE << 8) & 0x0300)); + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val); + + return TITAN_GE_MDIO_GOOD; +} + +/* + * Read the MDIO register. This is what the individual parametes mean: + * + * dev_addr : PHY ID + * reg_addr : register offset + * + * See the spec for the Titan MAC. We operate in the Direct Mode. + */ + +#define MAX_RETRIES 2 + +int titan_ge_mdio_read(int dev_addr, int reg_addr, unsigned int *pdata) +{ + volatile unsigned long val; + int retries = 0; + + /* Setup the PHY device */ + +again: + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS); + val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00)); + val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f)); + val |= 0x4000; + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val); + + udelay(30); + + /* Issue the read command */ + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND); + val = ( (val & ~(0x0300)) | ( (READ_OPCODE << 8) & 0x0300)); + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val); + + udelay(30); + + if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD) + return TITAN_GE_MDIO_ERROR; + + *pdata = (unsigned int)TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DATA); + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS); + + udelay(30); + + if (val & 0x2) { + if (retries == MAX_RETRIES) + return TITAN_GE_MDIO_ERROR; + else { + retries++; + goto again; + } + } + + return TITAN_GE_MDIO_GOOD; +} + +/* + * Write to the MDIO register + * + * dev_addr : PHY ID + * reg_addr : register that needs to be written to + * + */ +int titan_ge_mdio_write(int dev_addr, int reg_addr, unsigned int data) +{ + volatile unsigned long val; + + if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD) + return TITAN_GE_MDIO_ERROR; + + /* Setup the PHY device */ + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS); + val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00)); + val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f)); + val |= 0x4000; + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val); + + udelay(30); + + /* Setup the data to write */ + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DATA, data); + + udelay(30); + + /* Issue the write command */ + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND); + val = ( (val & ~(0x0300)) | ( (WRITE_OPCODE << 8) & 0x0300)); + TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val); + + udelay(30); + + if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD) + return TITAN_GE_MDIO_ERROR; + + val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS); + if (val & 0x2) + return TITAN_GE_MDIO_ERROR; + + return TITAN_GE_MDIO_GOOD; +} + diff --git a/drivers/net/titan_mdio.h b/drivers/net/titan_mdio.h new file mode 100644 index 0000000..5d23344 --- /dev/null +++ b/drivers/net/titan_mdio.h @@ -0,0 +1,56 @@ +/* + * MDIO used to interact with the PHY when using GMII/MII + */ +#ifndef _TITAN_MDIO_H +#define _TITAN_MDIO_H + +#include +#include +#include +#include "titan_ge.h" + + +#define TITAN_GE_MDIO_ERROR (-9000) +#define TITAN_GE_MDIO_GOOD 0 + +#define TITAN_GE_MDIO_BASE titan_ge_base + +#define TITAN_GE_MDIO_READ(offset) \ + *(volatile u32 *)(titan_ge_base + (offset)) + +#define TITAN_GE_MDIO_WRITE(offset, data) \ + *(volatile u32 *)(titan_ge_base + (offset)) = (data) + + +/* GMII specific registers */ +#define TITAN_GE_MARVEL_PHY_ID 0x00 +#define TITAN_PHY_AUTONEG_ADV 0x04 +#define TITAN_PHY_LP_ABILITY 0x05 +#define TITAN_GE_MDIO_MII_CTRL 0x09 +#define TITAN_GE_MDIO_MII_EXTENDED 0x0f +#define TITAN_GE_MDIO_PHY_CTRL 0x10 +#define TITAN_GE_MDIO_PHY_STATUS 0x11 +#define TITAN_GE_MDIO_PHY_IE 0x12 +#define TITAN_GE_MDIO_PHY_IS 0x13 +#define TITAN_GE_MDIO_PHY_LED 0x18 +#define TITAN_GE_MDIO_PHY_LED_OVER 0x19 +#define PHY_ANEG_TIME_WAIT 45 /* 45 seconds wait time */ + +/* + * MDIO Config Structure + */ +typedef struct { + unsigned int clka; + int mdio_spre; + int mdio_mode; +} titan_ge_mdio_config; + +/* + * Function Prototypes + */ +int titan_ge_mdio_setup(titan_ge_mdio_config *); +int titan_ge_mdio_inaddrs(int, int); +int titan_ge_mdio_read(int, int, unsigned int *); +int titan_ge_mdio_write(int, int, unsigned int); + +#endif /* _TITAN_MDIO_H */ diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h index 5a9515c..22614bc 100644 --- a/drivers/net/wireless/rtl8187.h +++ b/drivers/net/wireless/rtl8187.h @@ -91,6 +91,8 @@ enum { struct rtl8187_priv { /* common between rtl818x drivers */ struct rtl818x_csr *map; +#define REG_BUF_SIZE 64 + void *reg_buf; const struct rtl818x_rf_ops *rf; struct ieee80211_vif *vif; int mode; @@ -129,9 +131,10 @@ static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv, usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, - (unsigned long)addr, idx & 0x03, &val, + (__u16)addr, idx & 0x03, priv->reg_buf, sizeof(val), HZ / 2); + val = *(u8*)priv->reg_buf; return val; } @@ -147,9 +150,10 @@ static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv, usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, - (unsigned long)addr, idx & 0x03, &val, + (unsigned long)addr, idx & 0x03, priv->reg_buf, sizeof(val), HZ / 2); + val = *(u16*)priv->reg_buf; return le16_to_cpu(val); } @@ -165,9 +169,10 @@ static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv, usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, - (unsigned long)addr, idx & 0x03, &val, + (unsigned long)addr, idx & 0x03, priv->reg_buf, sizeof(val), HZ / 2); + val = *(u32*)priv->reg_buf; return le32_to_cpu(val); } @@ -179,9 +184,10 @@ static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr) static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv, u8 *addr, u8 val, u8 idx) { + *(u8*)priv->reg_buf = val; usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - (unsigned long)addr, idx & 0x03, &val, + (unsigned long)addr, idx & 0x03, priv->reg_buf, sizeof(val), HZ / 2); } @@ -193,11 +199,11 @@ static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val) static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv, __le16 *addr, u16 val, u8 idx) { - __le16 buf = cpu_to_le16(val); + *(__le16 *)priv->reg_buf = cpu_to_le16(val); usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - (unsigned long)addr, idx & 0x03, &buf, sizeof(buf), + (unsigned long)addr, idx & 0x03, priv->reg_buf, sizeof(u16), HZ / 2); } @@ -210,11 +216,11 @@ static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr, static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv, __le32 *addr, u32 val, u8 idx) { - __le32 buf = cpu_to_le32(val); + *(__le32 *)priv->reg_buf = cpu_to_le32(val); usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, - (unsigned long)addr, idx & 0x03, &buf, sizeof(buf), + (unsigned long)addr, idx & 0x03, priv->reg_buf, sizeof(u32), HZ / 2); } diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 0cebbc4..58b5447 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -1037,6 +1037,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, priv = dev->priv; priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B); + priv->reg_buf = kmalloc(REG_BUF_SIZE, GFP_KERNEL); + SET_IEEE80211_DEV(dev, &intf->dev); usb_set_intfdata(intf, dev); priv->udev = udev; @@ -1231,6 +1233,10 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf) ieee80211_unregister_hw(dev); priv = dev->priv; + if(priv->reg_buf) { + kfree(priv->reg_buf); + priv->reg_buf = NULL; + } usb_put_dev(interface_to_usbdev(intf)); ieee80211_free_hw(dev); } diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 9f42cb8..15d6c60 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -279,7 +279,12 @@ static int usb_unbind_interface(struct device *dev) * altsetting means creating new endpoint device entries). * When either of these happens, defer the Set-Interface. */ - if (!error && intf->dev.power.status == DPM_ON) + if (intf->cur_altsetting->desc.bAlternateSetting == 0) { + /* Already in altsetting 0 so skip Set-Interface. + * Just re-enable it without affecting the endpoint toggles. + */ + usb_enable_interface(udev, intf, false); + } else if (!error && intf->dev.power.status == DPM_ON) usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); else diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 769f80f..eb6200b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2302,7 +2302,7 @@ void usb_ep0_reinit(struct usb_device *udev) { usb_disable_endpoint(udev, 0 + USB_DIR_IN); usb_disable_endpoint(udev, 0 + USB_DIR_OUT); - usb_enable_endpoint(udev, &udev->ep0); + usb_enable_endpoint(udev, &udev->ep0, true); } EXPORT_SYMBOL_GPL(usb_ep0_reinit); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 9cfa366..b7c5b0c 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1117,18 +1117,21 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers. * For control endpoints, both the input and output sides are handled. */ -void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) +void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep, + bool reset_toggle) { int epnum = usb_endpoint_num(&ep->desc); int is_out = usb_endpoint_dir_out(&ep->desc); int is_control = usb_endpoint_xfer_control(&ep->desc); if (is_out || is_control) { - usb_settoggle(dev, epnum, 1, 0); + if (reset_toggle) + usb_settoggle(dev, epnum, 1, 0); dev->ep_out[epnum] = ep; } if (!is_out || is_control) { - usb_settoggle(dev, epnum, 0, 0); + if (reset_toggle) + usb_settoggle(dev, epnum, 0, 0); dev->ep_in[epnum] = ep; } ep->enabled = 1; @@ -1141,14 +1144,14 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) * * Enables all the endpoints for the interface's current altsetting. */ -static void usb_enable_interface(struct usb_device *dev, - struct usb_interface *intf) +void usb_enable_interface(struct usb_device *dev, + struct usb_interface *intf, bool reset_toggles) { struct usb_host_interface *alt = intf->cur_altsetting; int i; for (i = 0; i < alt->desc.bNumEndpoints; ++i) - usb_enable_endpoint(dev, &alt->endpoint[i]); + usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles); } /** @@ -1270,7 +1273,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) * during the SETUP stage - hence EP0 toggles are "don't care" here. * (Likewise, EP0 never "halts" on well designed devices.) */ - usb_enable_interface(dev, iface); + usb_enable_interface(dev, iface, true); if (device_is_registered(&iface->dev)) usb_create_sysfs_intf_files(iface); @@ -1345,7 +1348,7 @@ int usb_reset_configuration(struct usb_device *dev) alt = &intf->altsetting[0]; intf->cur_altsetting = alt; - usb_enable_interface(dev, intf); + usb_enable_interface(dev, intf, true); if (device_is_registered(&intf->dev)) usb_create_sysfs_intf_files(intf); } @@ -1603,7 +1606,7 @@ free_interfaces: alt = &intf->altsetting[0]; intf->cur_altsetting = alt; - usb_enable_interface(dev, intf); + usb_enable_interface(dev, intf, true); intf->dev.parent = &dev->dev; intf->dev.driver = NULL; intf->dev.bus = &usb_bus_type; diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index be1fa07..956bf1e 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -362,7 +362,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; /* ep0 maxpacket comes later, from device descriptor */ - usb_enable_endpoint(dev, &dev->ep0); + usb_enable_endpoint(dev, &dev->ep0, true); dev->can_submit = 1; /* Save readable and stable topology id, distinguishing devices diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 9a1a45a..1d450e9 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -10,7 +10,9 @@ extern int usb_create_ep_files(struct device *parent, extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); extern void usb_enable_endpoint(struct usb_device *dev, - struct usb_host_endpoint *ep); + struct usb_host_endpoint *ep, bool reset_toggle); +extern void usb_enable_interface(struct usb_device *dev, + struct usb_interface *intf, bool reset_toggles); extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr); extern void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index dc21ade..5abf603 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include #include #include diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 740835b..97c4fbf 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -194,7 +194,22 @@ static int ehci_bus_resume (struct usb_hcd *hcd) u32 temp; u32 power_okay; int i; - +#ifdef CONFIG_MACH_LM2F + struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); + + if (pdev->vendor == PCI_VENDOR_ID_AMD && + pdev->device == PCI_DEVICE_ID_AMD_CS5536_EHC) { + u32 tmp; + tmp = ehci_readl(ehci, &ehci->regs->port_status[0]); + ehci_writel(ehci, tmp | 0x1000, &ehci->regs->port_status[0]); + tmp = ehci_readl(ehci, &ehci->regs->port_status[1]); + ehci_writel(ehci, tmp | 0x1000, &ehci->regs->port_status[1]); + tmp = ehci_readl(ehci, &ehci->regs->port_status[2]); + ehci_writel(ehci, tmp | 0x1000, &ehci->regs->port_status[2]); + tmp = ehci_readl(ehci, &ehci->regs->port_status[3]); + ehci_writel(ehci, tmp | 0x1000, &ehci->regs->port_status[3]); + } +#endif if (time_before (jiffies, ehci->next_statechange)) msleep(5); spin_lock_irq (&ehci->lock); @@ -419,6 +434,20 @@ static int check_reset_complete ( ehci_dbg (ehci, "port %d full speed --> companion\n", index + 1); +#if 1 + { + struct pci_dev *pdev; + + pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); + if (pdev->vendor == PCI_VENDOR_ID_AMD && + pdev->device == PCI_DEVICE_ID_AMD_CS5536_EHC) { + if (index == 3) { + printk("8187 speed changed \n"); + return port_status; + } + } + } +#endif // what happens if HCS_N_CC(params) == 0 ? port_status |= PORT_OWNER; port_status &= ~PORT_RWC_BITS; @@ -507,6 +536,7 @@ ehci_hub_descriptor ( ) { int ports = HCS_N_PORTS (ehci->hcs_params); u16 temp; + struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); desc->bDescriptorType = 0x29; desc->bPwrOn2PwrGood = 10; /* ehci 1.0, 2.3.9 says 20ms max */ @@ -516,6 +546,17 @@ ehci_hub_descriptor ( temp = 1 + (ports / 8); desc->bDescLength = 7 + 2 * temp; +#if 1 + pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); + if (pdev->vendor == PCI_VENDOR_ID_AMD && + pdev->device == PCI_DEVICE_ID_AMD_CS5536_EHC) { + //set_bit(3, &ehci->companion_ports); + //set_bit(0, &ehci->companion_ports); //sd + //Not use built in 8187b + desc->bNbrPorts = 3; + } +#endif + /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ memset (&desc->bitmap [0], 0, temp); memset (&desc->bitmap [temp], 0xff, temp); @@ -551,6 +592,7 @@ static int ehci_hub_control ( unsigned long flags; int retval = 0; unsigned selector; + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); /* * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR. diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 32bbce9..2ae5684 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -42,6 +42,10 @@ static void dl_done_list (struct ohci_hcd *); static void finish_unlinks (struct ohci_hcd *, u16); +#ifdef CONFIG_LEMOTE_2FNOTEBOOK +//#define __try_to_fix_cs5536_usb__ +#endif + #ifdef CONFIG_PM static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop) __releases(ohci->lock) @@ -749,6 +753,18 @@ static int ohci_hub_control ( default: goto error; } +#ifdef __try_to_fix_cs5536_usb__ + { + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + + if (pdev->vendor == PCI_VENDOR_ID_AMD && + pdev->device == PCI_DEVICE_ID_AMD_CS5536_OHC) { + if(wIndex == 0 || wIndex == 3) { + break; + } + } + } +#endif ohci_writel (ohci, temp, &ohci->regs->roothub.portstatus [wIndex]); // ohci_readl (ohci, &ohci->regs->roothub.portstatus [wIndex]); @@ -765,6 +781,19 @@ static int ohci_hub_control ( goto error; wIndex--; temp = roothub_portstatus (ohci, wIndex); +#ifdef __try_to_fix_cs5536_usb__ + { + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + + if (pdev->vendor == PCI_VENDOR_ID_AMD && + pdev->device == PCI_DEVICE_ID_AMD_CS5536_OHC) { + if(wIndex == 0 || wIndex == 3) { + temp = 0; + } + } + } +#endif + put_unaligned_le32(temp, buf); #ifndef OHCI_VERBOSE_DEBUG @@ -786,6 +815,19 @@ static int ohci_hub_control ( if (!wIndex || wIndex > ports) goto error; wIndex--; +#ifdef __try_to_fix_cs5536_usb__ + { + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + + if (pdev->vendor == PCI_VENDOR_ID_AMD && + pdev->device == PCI_DEVICE_ID_AMD_CS5536_OHC) { + if(wIndex == 0 || wIndex == 3) { + break; + } + } + } +#endif + switch (wValue) { case USB_PORT_FEAT_SUSPEND: #ifdef CONFIG_USB_OTG diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index a9c2ae3..b691e26 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -362,6 +362,15 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd) } #endif /* CONFIG_PM */ +//#ifdef __try_to_fix_cs5536_usb__ + if (1){ + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + + if (pdev->vendor == PCI_VENDOR_ID_AMD && + pdev->device == PCI_DEVICE_ID_AMD_CS5536_OHC) + ohci->num_ports = 3; + } +//#endif ret = ohci_run (ohci); if (ret < 0) { ohci_err (ohci, "can't start\n"); diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 70d135e..8d23162 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1899,6 +1899,38 @@ config FB_S3C2410_DEBUG Turn on debugging messages. Note that you can set/unset at run time through sysfs +config FB_SILICONMOTION + bool "Silicon Motion Display Support" + depends on FB + select FB_CFB_COPYAREA + select FB_CFB_FILLRECT + select FB_CFB_IMAGEBLIT + ---help--- + Frame Buffer driver for the Silicon Motion serial graphic card. + +config FB_SM7XX + bool "Silicon Motion SM7XX Frame Buffer Support" + depends on FB_SILICONMOTION + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame Buffer driver for the Silicon Motion SM7XX serial graphic card. + +config FB_SM7XX_ACCEL + bool "Siliconmotion Acceleration functions (EXPERIMENTAL)" + depends on FB_SM7XX && EXPERIMENTAL + ---help--- + This will compile the Trident frame buffer device with + acceleration functions. + +config FB_SM7XX_DUALHEAD + bool "SM7XX dualhead display support" + depends on FB_SM7XX + ---help--- + Say Y here if you want to use a secondary head display. + config FB_SM501 tristate "Silicon Motion SM501 framebuffer support" depends on FB && MFD_SM501 @@ -2054,4 +2086,15 @@ if FB || SGI_NEWPORT_CONSOLE source "drivers/video/logo/Kconfig" endif +config FB_SPLASH + bool "Support for the framebuffer splash" + depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING + default n + ---help--- + This option enables support for the Linux boot-up splash screen and + graphical backgrounds on consoles. Note that you will need userspace + splash utilities in order to take advantage of these features. Refer + to Documentation/fb/splash.txt for more information. + + If unsure, say N. endmenu diff --git a/drivers/video/Makefile b/drivers/video/Makefile index a6b5529..8ef2d31 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -14,6 +14,7 @@ fb-objs := $(fb-y) obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/ obj-y += backlight/ display/ +obj-$(CONFIG_FB_SPLASH) += fbsplash.o cfbsplash.o obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o @@ -71,6 +72,7 @@ obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o obj-$(CONFIG_FB_SGIVW) += sgivwfb.o +obj-$(CONFIG_FB_SILICONMOTION) += smi/ obj-$(CONFIG_FB_ACORN) += acornfb.o obj-$(CONFIG_FB_ATARI) += atafb.o c2p.o atafb_mfb.o \ atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o diff --git a/drivers/video/cfbsplash.c b/drivers/video/cfbsplash.c new file mode 100644 index 0000000..a0b4d0d --- /dev/null +++ b/drivers/video/cfbsplash.c @@ -0,0 +1,471 @@ +/* + * linux/drivers/video/cfbsplash.c -- Framebuffer splash render functions + * + * Copyright (C) 2004 Michal Januszewski + * + * Code based upon "Bootsplash" (C) 2001-2003 + * Volker Poplawski , + * Stefan Reinauer , + * Steffen Winterfeldt , + * Michael Schroeder , + * Ken Wimer . + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "console/fbcon.h" +#include "fbsplash.h" + +#define parse_pixel(shift,bpp,type) \ + do { \ + if (d & (0x80 >> (shift))) \ + dd2[(shift)] = fgx; \ + else \ + dd2[(shift)] = transparent ? *(type *)splash_src : bgx; \ + splash_src += (bpp); \ + } while (0) \ + +extern int get_color(struct vc_data *vc, struct fb_info *info, + u16 c, int is_fg); + +void fbsplash_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) +{ + int i, j, k; + int minlen = min(min(info->var.red.length, info->var.green.length), + info->var.blue.length); + u32 col; + + for (j = i = 0; i < 16; i++) { + k = color_table[i]; + + col = ((vc->vc_palette[j++] >> (8-minlen)) + << info->var.red.offset); + col |= ((vc->vc_palette[j++] >> (8-minlen)) + << info->var.green.offset); + col |= ((vc->vc_palette[j++] >> (8-minlen)) + << info->var.blue.offset); + ((u32 *)info->pseudo_palette)[k] = col; + } +} + +void fbsplash_renderc(struct fb_info *info, int ypos, int xpos, int height, + int width, u8* src, u32 fgx, u32 bgx, u8 transparent) +{ + unsigned int x, y; + u32 dd; + int bytespp = ((info->var.bits_per_pixel + 7) >> 3); + unsigned int d = ypos * info->fix.line_length + xpos * bytespp; + unsigned int ds = (ypos * info->var.xres + xpos) * bytespp; + u16 dd2[4]; + + u8* splash_src = (u8 *)(info->splash.data + ds); + u8* dst = (u8 *)(info->screen_base + d); + + if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres) + return; + + for (y = 0; y < height; y++) { + switch (info->var.bits_per_pixel) { + + case 32: + for (x = 0; x < width; x++) { + + if ((x & 7) == 0) + d = *src++; + if (d & 0x80) + dd = fgx; + else + dd = transparent ? + *(u32 *)splash_src : bgx; + + d <<= 1; + splash_src += 4; + fb_writel(dd, dst); + dst += 4; + } + break; + case 24: + for (x = 0; x < width; x++) { + + if ((x & 7) == 0) + d = *src++; + if (d & 0x80) + dd = fgx; + else + dd = transparent ? + (*(u32 *)splash_src & 0xffffff) : bgx; + + d <<= 1; + splash_src += 3; +#ifdef __LITTLE_ENDIAN + fb_writew(dd & 0xffff, dst); + dst += 2; + fb_writeb((dd >> 16), dst); +#else + fb_writew(dd >> 8, dst); + dst += 2; + fb_writeb(dd & 0xff, dst); +#endif + dst++; + } + break; + case 16: + for (x = 0; x < width; x += 2) { + if ((x & 7) == 0) + d = *src++; + + parse_pixel(0, 2, u16); + parse_pixel(1, 2, u16); +#ifdef __LITTLE_ENDIAN + dd = dd2[0] | (dd2[1] << 16); +#else + dd = dd2[1] | (dd2[0] << 16); +#endif + d <<= 2; + fb_writel(dd, dst); + dst += 4; + } + break; + + case 8: + for (x = 0; x < width; x += 4) { + if ((x & 7) == 0) + d = *src++; + + parse_pixel(0, 1, u8); + parse_pixel(1, 1, u8); + parse_pixel(2, 1, u8); + parse_pixel(3, 1, u8); + +#ifdef __LITTLE_ENDIAN + dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24); +#else + dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24); +#endif + d <<= 4; + fb_writel(dd, dst); + dst += 4; + } + } + + dst += info->fix.line_length - width * bytespp; + splash_src += (info->var.xres - width) * bytespp; + } +} + +#define cc2cx(a) \ + ((info->fix.visual == FB_VISUAL_TRUECOLOR || \ + info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? \ + ((u32*)info->pseudo_palette)[a] : a) + +void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, + const unsigned short *s, int count, int yy, int xx) +{ + unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + struct fbcon_ops *ops = info->fbcon_par; + int fg_color, bg_color, transparent; + u8 *src; + u32 bgx, fgx; + u16 c = scr_readw(s); + + fg_color = get_color(vc, info, c, 1); + bg_color = get_color(vc, info, c, 0); + + /* Don't paint the background image if console is blanked */ + transparent = ops->blank_state ? 0 : + (vc->vc_splash.bg_color == bg_color); + + xx = xx * vc->vc_font.width + vc->vc_splash.tx; + yy = yy * vc->vc_font.height + vc->vc_splash.ty; + + fgx = cc2cx(fg_color); + bgx = cc2cx(bg_color); + + while (count--) { + c = scr_readw(s++); + src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * + ((vc->vc_font.width + 7) >> 3); + + fbsplash_renderc(info, yy, xx, vc->vc_font.height, + vc->vc_font.width, src, fgx, bgx, transparent); + xx += vc->vc_font.width; + } +} + +void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor) +{ + int i; + unsigned int dsize, s_pitch; + struct fbcon_ops *ops = info->fbcon_par; + struct vc_data* vc; + u8 *src; + + /* we really don't need any cursors while the console is blanked */ + if (info->state != FBINFO_STATE_RUNNING || ops->blank_state) + return; + + vc = vc_cons[ops->currcon].d; + + src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC); + if (!src) + return; + + s_pitch = (cursor->image.width + 7) >> 3; + dsize = s_pitch * cursor->image.height; + if (cursor->enable) { + switch (cursor->rop) { + case ROP_XOR: + for (i = 0; i < dsize; i++) + src[i] = cursor->image.data[i] ^ cursor->mask[i]; + break; + case ROP_COPY: + default: + for (i = 0; i < dsize; i++) + src[i] = cursor->image.data[i] & cursor->mask[i]; + break; + } + } else + memcpy(src, cursor->image.data, dsize); + + fbsplash_renderc(info, + cursor->image.dy + vc->vc_splash.ty, + cursor->image.dx + vc->vc_splash.tx, + cursor->image.height, + cursor->image.width, + (u8*)src, + cc2cx(cursor->image.fg_color), + cc2cx(cursor->image.bg_color), + cursor->image.bg_color == vc->vc_splash.bg_color); + + kfree(src); +} + +static void splashset(u8 *dst, int height, int width, int dstbytes, + u32 bgx, int bpp) +{ + int i; + + if (bpp == 8) + bgx |= bgx << 8; + if (bpp == 16 || bpp == 8) + bgx |= bgx << 16; + + while (height-- > 0) { + u8 *p = dst; + + switch (bpp) { + + case 32: + for (i=0; i < width; i++) { + fb_writel(bgx, p); p += 4; + } + break; + case 24: + for (i=0; i < width; i++) { +#ifdef __LITTLE_ENDIAN + fb_writew((bgx & 0xffff),(u16*)p); p += 2; + fb_writeb((bgx >> 16),p++); +#else + fb_writew((bgx >> 8),(u16*)p); p += 2; + fb_writeb((bgx & 0xff),p++); +#endif + } + case 16: + for (i=0; i < width/4; i++) { + fb_writel(bgx,p); p += 4; + fb_writel(bgx,p); p += 4; + } + if (width & 2) { + fb_writel(bgx,p); p += 4; + } + if (width & 1) + fb_writew(bgx,(u16*)p); + break; + case 8: + for (i=0; i < width/4; i++) { + fb_writel(bgx,p); p += 4; + } + + if (width & 2) { + fb_writew(bgx,p); p += 2; + } + if (width & 1) + fb_writeb(bgx,(u8*)p); + break; + + } + dst += dstbytes; + } +} + +void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes, + int srclinebytes, int bpp) +{ + int i; + + while (height-- > 0) { + u32 *p = (u32 *)dst; + u32 *q = (u32 *)src; + + switch (bpp) { + + case 32: + for (i=0; i < width; i++) + fb_writel(*q++, p++); + break; + case 24: + for (i=0; i < (width*3/4); i++) + fb_writel(*q++, p++); + if ((width*3) % 4) { + if (width & 2) { + fb_writeb(*(u8*)q, (u8*)p); + } else if (width & 1) { + fb_writew(*(u16*)q, (u16*)p); + fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2)); + } + } + break; + case 16: + for (i=0; i < width/4; i++) { + fb_writel(*q++, p++); + fb_writel(*q++, p++); + } + if (width & 2) + fb_writel(*q++, p++); + if (width & 1) + fb_writew(*(u16*)q, (u16*)p); + break; + case 8: + for (i=0; i < width/4; i++) + fb_writel(*q++, p++); + + if (width & 2) { + fb_writew(*(u16*)q, (u16*)p); + q = (u32*) ((u16*)q + 1); + p = (u32*) ((u16*)p + 1); + } + if (width & 1) + fb_writeb(*(u8*)q, (u8*)p); + break; + } + + dst += linebytes; + src += srclinebytes; + } +} + +static void splashfill(struct fb_info *info, int sy, int sx, int height, + int width) +{ + int bytespp = ((info->var.bits_per_pixel + 7) >> 3); + int d = sy * info->fix.line_length + sx * bytespp; + int ds = (sy * info->var.xres + sx) * bytespp; + + fbsplash_copy((u8 *)(info->screen_base + d), (u8 *)(info->splash.data + ds), + height, width, info->fix.line_length, info->var.xres * bytespp, + info->var.bits_per_pixel); +} + +void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, + int height, int width) +{ + int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + int bg_color = attr_bgcol_ec(bgshift, vc, info); + int transparent = vc->vc_splash.bg_color == bg_color; + struct fbcon_ops *ops = info->fbcon_par; + u8 *dst; + + sy = sy * vc->vc_font.height + vc->vc_splash.ty; + sx = sx * vc->vc_font.width + vc->vc_splash.tx; + height *= vc->vc_font.height; + width *= vc->vc_font.width; + + /* Don't paint the background image if console is blanked */ + if (transparent && !ops->blank_state) { + splashfill(info, sy, sx, height, width); + } else { + dst = (u8 *)(info->screen_base + sy * info->fix.line_length + + sx * ((info->var.bits_per_pixel + 7) >> 3)); + splashset(dst, height, width, info->fix.line_length, cc2cx(bg_color), + info->var.bits_per_pixel); + } +} + +void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, + int bottom_only) +{ + unsigned int tw = vc->vc_cols*vc->vc_font.width; + unsigned int th = vc->vc_rows*vc->vc_font.height; + + if (!bottom_only) { + /* top margin */ + splashfill(info, 0, 0, vc->vc_splash.ty, info->var.xres); + /* left margin */ + splashfill(info, vc->vc_splash.ty, 0, th, vc->vc_splash.tx); + /* right margin */ + splashfill(info, vc->vc_splash.ty, vc->vc_splash.tx + tw, th, + info->var.xres - vc->vc_splash.tx - tw); + } + splashfill(info, vc->vc_splash.ty + th, 0, + info->var.yres - vc->vc_splash.ty - th, info->var.xres); +} + +void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, + int sx, int dx, int width) +{ + u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2); + u16 *s = d + (dx - sx); + u16 *start = d; + u16 *ls = d; + u16 *le = d + width; + u16 c; + int x = dx; + u16 attr = 1; + + do { + c = scr_readw(d); + if (attr != (c & 0xff00)) { + attr = c & 0xff00; + if (d > start) { + fbsplash_putcs(vc, info, start, d - start, y, x); + x += d - start; + start = d; + } + } + if (s >= ls && s < le && c == scr_readw(s)) { + if (d > start) { + fbsplash_putcs(vc, info, start, d - start, y, x); + x += d - start + 1; + start = d + 1; + } else { + x++; + start++; + } + } + s++; + d++; + } while (d < le); + if (d > start) + fbsplash_putcs(vc, info, start, d - start, y, x); +} + +void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank) +{ + if (blank) { + splashset((u8 *)info->screen_base, info->var.yres, info->var.xres, + info->fix.line_length, 0, info->var.bits_per_pixel); + } else { + update_screen(vc); + fbsplash_clear_margins(vc, info, 0); + } +} + diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index 69864b1..5aadd01 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c @@ -17,6 +17,7 @@ #include #include #include "fbcon.h" +#include "../fbsplash.h" /* * Accelerated handlers. @@ -54,6 +55,13 @@ static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy, area.height = height * vc->vc_font.height; area.width = width * vc->vc_font.width; + if (fbsplash_active(info, vc)) { + area.sx += vc->vc_splash.tx; + area.sy += vc->vc_splash.ty; + area.dx += vc->vc_splash.tx; + area.dy += vc->vc_splash.ty; + } + info->fbops->fb_copyarea(info, &area); } @@ -379,11 +387,15 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, cursor.image.depth = 1; cursor.rop = ROP_XOR; - if (info->fbops->fb_cursor) - err = info->fbops->fb_cursor(info, &cursor); + if (fbsplash_active(info, vc)) { + fbsplash_cursor(info, &cursor); + } else { + if (info->fbops->fb_cursor) + err = info->fbops->fb_cursor(info, &cursor); - if (err) - soft_cursor(info, &cursor); + if (err) + soft_cursor(info, &cursor); + } ops->cursor_reset = 0; } diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 038ea62..45a0669 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -90,6 +90,7 @@ #endif #include "fbcon.h" +#include "../fbsplash.h" #ifdef FBCONDEBUG # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args) @@ -105,7 +106,7 @@ enum { static struct display fb_display[MAX_NR_CONSOLES]; -static signed char con2fb_map[MAX_NR_CONSOLES]; +signed char con2fb_map[MAX_NR_CONSOLES]; static signed char con2fb_map_boot[MAX_NR_CONSOLES]; static int logo_lines; @@ -313,7 +314,7 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) vc->vc_mode != KD_TEXT || ops->graphics); } -static inline int get_color(struct vc_data *vc, struct fb_info *info, +inline int get_color(struct vc_data *vc, struct fb_info *info, u16 c, int is_fg) { int depth = fb_get_color_depth(&info->var, &info->fix); @@ -418,6 +419,7 @@ static void fb_flashcursor(struct work_struct *work) CM_ERASE : CM_DRAW; ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1), get_color(vc, info, c, 0)); + release_console_sem(); } @@ -588,6 +590,8 @@ static int fbcon_takeover(int show_logo) info_idx = -1; } + fbsplash_init(); + return err; } @@ -1029,6 +1033,12 @@ static const char *fbcon_startup(void) rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); cols /= vc->vc_font.width; rows /= vc->vc_font.height; + + if (fbsplash_active(info, vc)) { + cols = vc->vc_splash.twidth / vc->vc_font.width; + rows = vc->vc_splash.theight / vc->vc_font.height; + } + vc_resize(vc, cols, rows); DPRINTK("mode: %s\n", info->fix.id); @@ -1112,7 +1122,7 @@ static void fbcon_init(struct vc_data *vc, int init) cap = info->flags; if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || - (info->fix.type == FB_TYPE_TEXT)) + (info->fix.type == FB_TYPE_TEXT) || fbsplash_active(info, vc)) logo = 0; if (var_to_display(p, &info->var, info)) @@ -1314,6 +1324,11 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, if (sy < vc->vc_top && vc->vc_top == logo_lines) vc->vc_top = 0; + if (fbsplash_active(info, vc)) { + fbsplash_clear(vc, info, sy, sx, height, width); + return; + } + /* Split blits that cross physical y_wrap boundary */ y_break = p->vrows - p->yscroll; @@ -1333,10 +1348,15 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, struct display *p = &fb_display[vc->vc_num]; struct fbcon_ops *ops = info->fbcon_par; - if (!fbcon_is_inactive(vc, info)) - ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, - get_color(vc, info, scr_readw(s), 1), - get_color(vc, info, scr_readw(s), 0)); + if (!fbcon_is_inactive(vc, info)) { + + if (fbsplash_active(info, vc)) + fbsplash_putcs(vc, info, s, count, ypos, xpos); + else + ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, + get_color(vc, info, scr_readw(s), 1), + get_color(vc, info, scr_readw(s), 0)); + } } static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos) @@ -1352,8 +1372,13 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - if (!fbcon_is_inactive(vc, info)) - ops->clear_margins(vc, info, bottom_only); + if (!fbcon_is_inactive(vc, info)) { + if (fbsplash_active(info, vc)) { + fbsplash_clear_margins(vc, info, bottom_only); + } else { + ops->clear_margins(vc, info, bottom_only); + } + } } static void fbcon_cursor(struct vc_data *vc, int mode) @@ -1880,7 +1905,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, count = vc->vc_rows; if (softback_top) fbcon_softback_note(vc, t, count); - if (logo_shown >= 0) + if (logo_shown >= 0 || fbsplash_active(info, vc)) goto redraw_up; switch (p->scrollmode) { case SCROLL_MOVE: @@ -1974,6 +1999,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, count = vc->vc_rows; if (logo_shown >= 0) goto redraw_down; + if (fbsplash_active(info, vc)) + goto redraw_down; switch (p->scrollmode) { case SCROLL_MOVE: fbcon_redraw_blit(vc, info, p, b - 1, b - t - count, @@ -2125,6 +2152,13 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s } return; } + + if (fbsplash_active(info, vc) && sy == dy && height == 1) { + /* must use slower redraw bmove to keep background pic intact */ + fbsplash_bmove_redraw(vc, info, sy, sx, dx, width); + return; + } + ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx, height, width); } @@ -2195,8 +2229,9 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, var.yres = virt_h * virt_fh; x_diff = info->var.xres - var.xres; y_diff = info->var.yres - var.yres; - if (x_diff < 0 || x_diff > virt_fw || - y_diff < 0 || y_diff > virt_fh) { + + if ((x_diff < 0 || x_diff > virt_fw || + y_diff < 0 || y_diff > virt_fh) && !vc->vc_splash.state) { const struct fb_videomode *mode; DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); @@ -2232,6 +2267,25 @@ static int fbcon_switch(struct vc_data *vc) info = registered_fb[con2fb_map[vc->vc_num]]; ops = info->fbcon_par; + prev_console = ops->currcon; + if (prev_console != -1) + old_info = registered_fb[con2fb_map[prev_console]]; + + if (fbsplash_active_vc(vc)) { + struct vc_data *vc_curr = vc_cons[prev_console].d; + if (!vc_curr->vc_splash.theme || strcmp(vc->vc_splash.theme, vc_curr->vc_splash.theme)) { + if (fbsplash_call_helper("getpic", vc->vc_num)) + fbsplash_disable(vc, 0); + } + } else if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { + struct vc_data *vc_curr = vc_cons[prev_console].d; + if (vc_curr && fbsplash_active_vc(vc_curr)) { + /* Clear the screen to avoid displaying funky colors during + * palette updates. */ + memset((u8*)info->screen_base + info->fix.line_length * info->var.yoffset, + 0, info->var.yres * info->fix.line_length); + } + } if (softback_top) { if (softback_lines) @@ -2250,9 +2304,6 @@ static int fbcon_switch(struct vc_data *vc) logo_shown = FBCON_LOGO_CANSHOW; } - prev_console = ops->currcon; - if (prev_console != -1) - old_info = registered_fb[con2fb_map[prev_console]]; /* * FIXME: If we have multiple fbdev's loaded, we need to * update all info->currcon. Perhaps, we can place this @@ -2289,6 +2340,11 @@ static int fbcon_switch(struct vc_data *vc) if (old_info != info) fbcon_del_cursor_timer(old_info); } + + if (fbsplash_active_nores(info, vc) && !fbsplash_active(info, vc)) { + if (fbsplash_call_helper("modechange", vc->vc_num)) + fbsplash_disable(vc, 0); + } if (fbcon_is_inactive(vc, info) || ops->blank_state != FB_BLANK_UNBLANK) @@ -2409,7 +2465,12 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) if (info->fbops->fb_blank) ret = info->fbops->fb_blank(blank, info); if (ret) - fbcon_generic_blank(vc, info, blank); + { + if (fbsplash_active(info, vc)) + fbsplash_blank(vc, info, blank); + else + fbcon_generic_blank(vc, info, blank); + } } if (!blank) @@ -2568,13 +2629,22 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, } if (resize) { + /* reset wrap/pan */ int cols, rows; cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + + info->var.xoffset = info->var.yoffset = p->yscroll = 0; + if (fbsplash_active(info, vc)) { + cols = vc->vc_splash.twidth; + rows = vc->vc_splash.theight; + } cols /= w; rows /= h; + vc_resize(vc, cols, rows); + if (CON_IS_VISIBLE(vc) && softback_buf) fbcon_update_softback(vc); } else if (CON_IS_VISIBLE(vc) @@ -2703,7 +2773,7 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) int i, j, k, depth; u8 val; - if (fbcon_is_inactive(vc, info)) + if (fbcon_is_inactive(vc, info) || vc->vc_num != fg_console) return -EINVAL; if (!CON_IS_VISIBLE(vc)) @@ -2729,7 +2799,49 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) } else fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap); - return fb_set_cmap(&palette_cmap, info); + if (fbsplash_active(info, vc_cons[fg_console].d) && + info->fix.visual == FB_VISUAL_DIRECTCOLOR) { + + u16 *red, *green, *blue; + int minlen = min(min(info->var.red.length, info->var.green.length), + info->var.blue.length); + int h; + + struct fb_cmap cmap = { + .start = 0, + .len = (1 << minlen), + .red = NULL, + .green = NULL, + .blue = NULL, + .transp = NULL + }; + + red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL); + + if (!red) + goto out; + + green = red + 256; + blue = green + 256; + cmap.red = red; + cmap.green = green; + cmap.blue = blue; + + for (i = 0; i < cmap.len; i++) { + red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1); + } + + h = fb_set_cmap(&cmap, info); + fbsplash_fix_pseudo_pal(info, vc_cons[fg_console].d); + kfree(red); + + return h; + + } else if (fbsplash_active(info, vc_cons[fg_console].d) && + info->var.bits_per_pixel == 8 && info->splash.cmap.red != NULL) + fb_set_cmap(&info->splash.cmap, info); + +out: return fb_set_cmap(&palette_cmap, info); } static u16 *fbcon_screen_pos(struct vc_data *vc, int offset) @@ -2955,7 +3067,14 @@ static void fbcon_modechanged(struct fb_info *info) rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); cols /= vc->vc_font.width; rows /= vc->vc_font.height; - vc_resize(vc, cols, rows); + + if (!fbsplash_active_nores(info, vc)) { + vc_resize(vc, cols, rows); + } else { + if (fbsplash_call_helper("modechange", vc->vc_num)) + fbsplash_disable(vc, 0); + } + updatescrollmode(p, info, vc); scrollback_max = 0; scrollback_current = 0; @@ -3583,6 +3702,7 @@ static void fbcon_exit(void) } } + fbsplash_exit(); fbcon_has_exited = 1; } diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index 91b78e6..0a37cda 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c @@ -16,6 +16,7 @@ #include #include #include +#include "fbsplash.h" static u16 red2[] __read_mostly = { 0x0000, 0xaaaa @@ -234,14 +235,17 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) if (transp) htransp = *transp++; if (info->fbops->fb_setcolreg(start++, - hred, hgreen, hblue, + hred, hgreen, hblue, htransp, info)) break; } } - if (rc == 0) + if (rc == 0) { fb_copy_cmap(cmap, &info->cmap); - + if (fbsplash_active(info, vc_cons[fg_console].d) && + info->fix.visual == FB_VISUAL_DIRECTCOLOR) + fbsplash_fix_pseudo_pal(info, vc_cons[fg_console].d); + } return rc; } @@ -249,7 +253,7 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) { int rc, size = cmap->len * sizeof(u16); struct fb_cmap umap; - + if (cmap->start < 0 || (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)) return -EINVAL; diff --git a/drivers/video/fbsplash.c b/drivers/video/fbsplash.c new file mode 100644 index 0000000..75d8db8 --- /dev/null +++ b/drivers/video/fbsplash.c @@ -0,0 +1,424 @@ +/* + * linux/drivers/video/fbsplash.c -- Framebuffer splash routines + * + * Copyright (C) 2004 Michal Januszewski + * + * Code based upon "Bootsplash" (C) 2001-2003 + * Volker Poplawski , + * Stefan Reinauer , + * Steffen Winterfeldt , + * Michael Schroeder , + * Ken Wimer . + * + * Splash render routines are located in /linux/drivers/video/cfbsplash.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "console/fbcon.h" +#include "fbsplash.h" + +#define SPLASH_VERSION "0.9.2" + +extern signed char con2fb_map[]; +static int fbsplash_enable(struct vc_data *vc); +char fbsplash_path[KMOD_PATH_LEN] = "/sbin/splash_helper"; +static int initialized = 0; + +int fbsplash_call_helper(char* cmd, unsigned short vc) +{ + char *envp[] = { + "HOME=/", + "PATH=/sbin:/bin", + NULL + }; + + char tfb[5]; + char tcons[5]; + unsigned char fb = (int) con2fb_map[vc]; + + char *argv[] = { + fbsplash_path, + "2", + cmd, + tcons, + tfb, + vc_cons[vc].d->vc_splash.theme, + NULL + }; + + snprintf(tfb,5,"%d",fb); + snprintf(tcons,5,"%d",vc); + + return call_usermodehelper(fbsplash_path, argv, envp, 1); +} + +/* Disables fbsplash on a virtual console; called with console sem held. */ +int fbsplash_disable(struct vc_data *vc, unsigned char redraw) +{ + struct fb_info* info; + + if (!vc->vc_splash.state) + return -EINVAL; + + info = registered_fb[(int) con2fb_map[vc->vc_num]]; + + if (info == NULL) + return -EINVAL; + + vc->vc_splash.state = 0; + vc_resize(vc, info->var.xres / vc->vc_font.width, + info->var.yres / vc->vc_font.height); + + if (fg_console == vc->vc_num && redraw) { + redraw_screen(vc, 0); + update_region(vc, vc->vc_origin + + vc->vc_size_row * vc->vc_top, + vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2); + } + + printk(KERN_INFO "fbsplash: switched splash state to 'off' on console %d\n", + vc->vc_num); + + return 0; +} + +/* Enables fbsplash on a virtual console; called with console sem held. */ +static int fbsplash_enable(struct vc_data *vc) +{ + struct fb_info* info; + + info = registered_fb[(int) con2fb_map[vc->vc_num]]; + + if (vc->vc_splash.twidth == 0 || vc->vc_splash.theight == 0 || + info == NULL || vc->vc_splash.state || (!info->splash.data && + vc->vc_num == fg_console)) + return -EINVAL; + + vc->vc_splash.state = 1; + vc_resize(vc, vc->vc_splash.twidth / vc->vc_font.width, + vc->vc_splash.theight / vc->vc_font.height); + + if (fg_console == vc->vc_num) { + redraw_screen(vc, 0); + update_region(vc, vc->vc_origin + + vc->vc_size_row * vc->vc_top, + vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2); + fbsplash_clear_margins(vc, info, 0); + } + + printk(KERN_INFO "fbsplash: switched splash state to 'on' on console %d\n", + vc->vc_num); + + return 0; +} + +static inline int fbsplash_ioctl_dosetstate(struct vc_data *vc, unsigned int __user* state, unsigned char origin) +{ + int tmp, ret; + + if (get_user(tmp, state)) + return -EFAULT; + + if (origin == FB_SPLASH_IO_ORIG_USER) + acquire_console_sem(); + if (!tmp) + ret = fbsplash_disable(vc, 1); + else + ret = fbsplash_enable(vc); + if (origin == FB_SPLASH_IO_ORIG_USER) + release_console_sem(); + + return ret; +} + +static inline int fbsplash_ioctl_dogetstate(struct vc_data *vc, unsigned int __user *state) +{ + return put_user(vc->vc_splash.state, (unsigned int __user*) state); +} + +static int fbsplash_ioctl_dosetcfg(struct vc_data *vc, struct vc_splash __user *arg, unsigned char origin) +{ + struct vc_splash cfg; + struct fb_info *info; + int len; + char *tmp; + + info = registered_fb[(int) con2fb_map[vc->vc_num]]; + + if (copy_from_user(&cfg, arg, sizeof(struct vc_splash))) + return -EFAULT; + if (info == NULL || !cfg.twidth || !cfg.theight || + cfg.tx + cfg.twidth > info->var.xres || + cfg.ty + cfg.theight > info->var.yres) + return -EINVAL; + + len = strlen_user(cfg.theme); + if (!len || len > FB_SPLASH_THEME_LEN) + return -EINVAL; + tmp = kmalloc(len, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + if (copy_from_user(tmp, (void __user *)cfg.theme, len)) + return -EFAULT; + cfg.theme = tmp; + cfg.state = 0; + + /* If this ioctl is a response to a request from kernel, the console sem + * is already held; we also don't need to disable splash because either the + * new config and background picture will be successfully loaded, and the + * splash will stay on, or in case of a failure it'll be turned off in fbcon. */ + if (origin == FB_SPLASH_IO_ORIG_USER) { + acquire_console_sem(); + if (vc->vc_splash.state) + fbsplash_disable(vc, 1); + } + + if (vc->vc_splash.theme) + kfree(vc->vc_splash.theme); + + vc->vc_splash = cfg; + + if (origin == FB_SPLASH_IO_ORIG_USER) + release_console_sem(); + + printk(KERN_INFO "fbsplash: console %d using theme '%s'\n", + vc->vc_num, vc->vc_splash.theme); + return 0; +} + +static int fbsplash_ioctl_dogetcfg(struct vc_data *vc, struct vc_splash __user *arg) +{ + struct vc_splash splash; + char __user *tmp; + + if (get_user(tmp, &arg->theme)) + return -EFAULT; + + splash = vc->vc_splash; + splash.theme = tmp; + + if (vc->vc_splash.theme) { + if (copy_to_user(tmp, vc->vc_splash.theme, strlen(vc->vc_splash.theme) + 1)) + return -EFAULT; + } else + if (put_user(0, tmp)) + return -EFAULT; + + if (copy_to_user(arg, &splash, sizeof(struct vc_splash))) + return -EFAULT; + + return 0; +} + +static int fbsplash_ioctl_dosetpic(struct vc_data *vc, struct fb_image __user *arg, unsigned char origin) +{ + struct fb_image img; + struct fb_info *info; + int len; + u8 *tmp; + + if (vc->vc_num != fg_console) + return -EINVAL; + + info = registered_fb[(int) con2fb_map[vc->vc_num]]; + + if (info == NULL) + return -EINVAL; + + if (copy_from_user(&img, arg, sizeof(struct fb_image))) + return -EFAULT; + + if (img.width != info->var.xres || img.height != info->var.yres) { + printk(KERN_ERR "fbsplash: picture dimensions mismatch\n"); + return -EINVAL; + } + + if (img.depth != info->var.bits_per_pixel) { + printk(KERN_ERR "fbsplash: picture depth mismatch\n"); + return -EINVAL; + } + + if (img.depth == 8) { + if (!img.cmap.len || !img.cmap.red || !img.cmap.green || + !img.cmap.blue) + return -EINVAL; + + tmp = vmalloc(img.cmap.len * 3 * 2); + if (!tmp) + return -ENOMEM; + + if (copy_from_user(tmp, (void __user*)img.cmap.red, img.cmap.len * 2) || + copy_from_user(tmp + (img.cmap.len << 1), + (void __user*)img.cmap.green, (img.cmap.len << 1)) || + copy_from_user(tmp + (img.cmap.len << 2), + (void __user*)img.cmap.blue, (img.cmap.len << 1))) { + vfree(tmp); + return -EFAULT; + } + + img.cmap.transp = NULL; + img.cmap.red = (u16*)tmp; + img.cmap.green = img.cmap.red + img.cmap.len; + img.cmap.blue = img.cmap.green + img.cmap.len; + } else { + img.cmap.red = NULL; + } + + len = ((img.depth + 7) >> 3) * img.width * img.height; + tmp = vmalloc(len); + + if (!tmp) + goto out; + + if (copy_from_user(tmp, (void __user*)img.data, len)) + goto out; + + img.data = tmp; + + /* If this ioctl is a response to a request from kernel, the console sem + * is already held. */ + if (origin == FB_SPLASH_IO_ORIG_USER) + acquire_console_sem(); + + if (info->splash.data) + vfree((u8*)info->splash.data); + if (info->splash.cmap.red) + vfree(info->splash.cmap.red); + + info->splash = img; + + if (origin == FB_SPLASH_IO_ORIG_USER) + release_console_sem(); + + return 0; + +out: if (img.cmap.red) + vfree(img.cmap.red); + if (tmp) + vfree(tmp); + return -ENOMEM; +} + +static int splash_ioctl(struct inode * inode, struct file *filp, u_int cmd, + u_long arg) +{ + struct fb_splash_iowrapper __user *wrapper = (void __user*) arg; + struct vc_data *vc = NULL; + unsigned short vc_num = 0; + unsigned char origin = 0; + void __user *data = NULL; + + if (!access_ok(VERIFY_READ, wrapper, + sizeof(struct fb_splash_iowrapper))) + return -EFAULT; + + __get_user(vc_num, &wrapper->vc); + __get_user(origin, &wrapper->origin); + __get_user(data, &wrapper->data); + + if (!vc_cons_allocated(vc_num)) + return -EINVAL; + + vc = vc_cons[vc_num].d; + + switch (cmd) { + case FBIOSPLASH_SETPIC: + return fbsplash_ioctl_dosetpic(vc, (struct fb_image __user*)data, origin); + case FBIOSPLASH_SETCFG: + return fbsplash_ioctl_dosetcfg(vc, (struct vc_splash*)data, origin); + case FBIOSPLASH_GETCFG: + return fbsplash_ioctl_dogetcfg(vc, (struct vc_splash*)data); + case FBIOSPLASH_SETSTATE: + return fbsplash_ioctl_dosetstate(vc, (unsigned int *)data, origin); + case FBIOSPLASH_GETSTATE: + return fbsplash_ioctl_dogetstate(vc, (unsigned int *)data); + default: + return -ENOIOCTLCMD; + } +} + +static struct file_operations splash_ops = { + .owner = THIS_MODULE, + .ioctl = splash_ioctl +}; + +static struct miscdevice splash_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "fbsplash", + .fops = &splash_ops +}; + +void fbsplash_reset(void) +{ + struct fb_info *info; + struct vc_data *vc; + int i; + + vc = vc_cons[0].d; + info = registered_fb[0]; + + for (i = 0; i < num_registered_fb; i++) { + registered_fb[i]->splash.data = NULL; + registered_fb[i]->splash.cmap.red = NULL; + } + + for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) { + vc_cons[i].d->vc_splash.state = vc_cons[i].d->vc_splash.twidth = + vc_cons[i].d->vc_splash.theight = 0; + vc_cons[i].d->vc_splash.theme = NULL; + } + + return; +} + +int fbsplash_init(void) +{ + int i; + + fbsplash_reset(); + + if (initialized) + return 0; + + i = misc_register(&splash_dev); + if (i) { + printk(KERN_ERR "fbsplash: failed to register device\n"); + return i; + } + + fbsplash_call_helper("init", 0); + initialized = 1; + return 0; +} + +int fbsplash_exit(void) +{ + fbsplash_reset(); + return 0; +} + +EXPORT_SYMBOL(fbsplash_path); diff --git a/drivers/video/fbsplash.h b/drivers/video/fbsplash.h new file mode 100644 index 0000000..cb9398f --- /dev/null +++ b/drivers/video/fbsplash.h @@ -0,0 +1,78 @@ +/* + * linux/drivers/video/fbsplash.h -- Framebuffer splash headers + * + * Copyright (C) 2004 Michal Januszewski + * + */ + +#ifndef __FB_SPLASH_H +#define __FB_SPLASH_H + +#ifndef _LINUX_FB_H +#include +#endif + +/* This is needed for vc_cons in fbcmap.c */ +#include + +struct fb_cursor; +struct fb_info; +struct vc_data; + +#ifdef CONFIG_FB_SPLASH +/* fbsplash.c */ +int fbsplash_init(void); +int fbsplash_exit(void); +int fbsplash_call_helper(char* cmd, unsigned short cons); +int fbsplash_disable(struct vc_data *vc, unsigned char redraw); + +/* cfbsplash.c */ +void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx); +void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor); +void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width); +void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only); +void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank); +void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width); +void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp); +void fbsplash_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc); + +/* vt.c */ +void acquire_console_sem(void); +void release_console_sem(void); +void do_unblank_screen(int entering_gfx); + +/* struct vc_data *y */ +#define fbsplash_active_vc(y) (y->vc_splash.state && y->vc_splash.theme) + +/* struct fb_info *x, struct vc_data *y */ +#define fbsplash_active_nores(x,y) (x->splash.data && fbsplash_active_vc(y)) + +/* struct fb_info *x, struct vc_data *y */ +#define fbsplash_active(x,y) (fbsplash_active_nores(x,y) && \ + x->splash.width == x->var.xres && \ + x->splash.height == x->var.yres && \ + x->splash.depth == x->var.bits_per_pixel) + + +#else /* CONFIG_FB_SPLASH */ + +static inline void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {} +static inline void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {} +static inline void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor) {} +static inline void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {} +static inline void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {} +static inline void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank) {} +static inline void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {} +static inline void fbsplash_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {} +static inline int fbsplash_call_helper(char* cmd, unsigned short cons) { return 0; } +static inline int fbsplash_init(void) { return 0; } +static inline int fbsplash_exit(void) { return 0; } +static inline int fbsplash_disable(struct vc_data *vc, unsigned char redraw) { return 0; } + +#define fbsplash_active_vc(y) (0) +#define fbsplash_active_nores(x,y) (0) +#define fbsplash_active(x,y) (0) + +#endif /* CONFIG_FB_SPLASH */ + +#endif /* __FB_SPLASH_H */ diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c index da33d80..387d92f 100644 --- a/drivers/video/sis/init301.c +++ b/drivers/video/sis/init301.c @@ -4887,6 +4887,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr) } /* LVDS */ + SiS_SetReg(SiS_Pr->SiS_Part1Port, 0x2d, 0x11); } /*********************************************/ diff --git a/drivers/video/smi/Makefile b/drivers/video/smi/Makefile new file mode 100755 index 0000000..3d879cf --- /dev/null +++ b/drivers/video/smi/Makefile @@ -0,0 +1,8 @@ +obj-y += smi.o + +#DRIVER_OBJS = $(addprefix ../, cfbfillrect.o cfbcopyarea.o cfbimgblt.o) + +smi-y := $(DRIVER_OBJS) + +smi-y +=smtcfb.o + diff --git a/drivers/video/smi/sm501hw.h b/drivers/video/smi/sm501hw.h new file mode 100755 index 0000000..81fc52e --- /dev/null +++ b/drivers/video/smi/sm501hw.h @@ -0,0 +1,2160 @@ +/* + * linux/drivers/video/sm501hw.h -- Silicon Motion SM501 frame buffer device + * + * Copyright (C) 2006 Silicon Motion, Inc. + * Ge Wang, gewang@siliconmotion.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License version 2 or later. See the file COPYING in the main directory of + * this archive for more details. + */ + + +#define SM501_VIDEOMEMORYSIZE 0x00800000 /*Assume SMTC graphics chip has 8MB VRAM */ +#define SM502_REV_ID 0xC0 + +/* + * + * Definitions for the System Configuration registers. + * + */ + +#define SYSTEM_CTRL 0x000000 +#define SYSTEM_CTRL_DPMS 31:30 +#define SYSTEM_CTRL_DPMS_VPHP 0 +#define SYSTEM_CTRL_DPMS_VPHN 1 +#define SYSTEM_CTRL_DPMS_VNHP 2 +#define SYSTEM_CTRL_DPMS_VNHN 3 +#define SYSTEM_CTRL_PCI_BURST 29:29 +#define SYSTEM_CTRL_PCI_BURST_DISABLE 0 +#define SYSTEM_CTRL_PCI_BURST_ENABLE 1 +#define SYSTEM_CTRL_CSC_STATUS 28:28 +#define SYSTEM_CTRL_CSC_STATUS_IDLE 0 +#define SYSTEM_CTRL_CSC_STATUS_BUSY 1 +#define SYSTEM_CTRL_PCI_MASTER 25:25 +#define SYSTEM_CTRL_PCI_MASTER_STOP 0 +#define SYSTEM_CTRL_PCI_MASTER_START 1 +#define SYSTEM_CTRL_LATENCY_TIMER 24:24 +#define SYSTEM_CTRL_LATENCY_TIMER_ENABLE 0 +#define SYSTEM_CTRL_LATENCY_TIMER_DISABLE 1 +#define SYSTEM_CTRL_PANEL_STATUS 23:23 +#define SYSTEM_CTRL_PANEL_STATUS_CURRENT 0 +#define SYSTEM_CTRL_PANEL_STATUS_PENDING 1 +#define SYSTEM_CTRL_VIDEO_STATUS 22:22 +#define SYSTEM_CTRL_VIDEO_STATUS_CURRENT 0 +#define SYSTEM_CTRL_VIDEO_STATUS_PENDING 1 +#define SYSTEM_CTRL_DE_FIFO 20:20 +#define SYSTEM_CTRL_DE_FIFO_NOT_EMPTY 0 +#define SYSTEM_CTRL_DE_FIFO_EMPTY 1 +#define SYSTEM_CTRL_DE_STATUS 19:19 +#define SYSTEM_CTRL_DE_STATUS_IDLE 0 +#define SYSTEM_CTRL_DE_STATUS_BUSY 1 +#define SYSTEM_CTRL_CRT_STATUS 17:17 +#define SYSTEM_CTRL_CRT_STATUS_CURRENT 0 +#define SYSTEM_CTRL_CRT_STATUS_PENDING 1 +#define SYSTEM_CTRL_ZVPORT 16:16 +#define SYSTEM_CTRL_ZVPORT_0 0 +#define SYSTEM_CTRL_ZVPORT_1 1 +#define SYSTEM_CTRL_PCI_BURST_READ 15:15 +#define SYSTEM_CTRL_PCI_BURST_READ_DISABLE 0 +#define SYSTEM_CTRL_PCI_BURST_READ_ENABLE 1 +#define SYSTEM_CTRL_DE_ABORT 13:12 +#define SYSTEM_CTRL_DE_ABORT_NORMAL 0 +#define SYSTEM_CTRL_DE_ABORT_2D_ABORT 3 +#define SYSTEM_CTRL_PCI_SUBSYS_LOCK 11:11 +#define SYSTEM_CTRL_PCI_SUBSYS_LOCK_DISABLE 0 +#define SYSTEM_CTRL_PCI_SUBSYS_LOCK_ENABLE 1 +#define SYSTEM_CTRL_PCI_RETRY 7:7 +#define SYSTEM_CTRL_PCI_RETRY_ENABLE 0 +#define SYSTEM_CTRL_PCI_RETRY_DISABLE 1 +#define SYSTEM_CTRL_PCI_CLOCK_RUN 6:6 +#define SYSTEM_CTRL_PCI_CLOCK_RUN_DISABLE 0 +#define SYSTEM_CTRL_PCI_CLOCK_RUN_ENABLE 1 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE 5:4 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_1 0 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_2 1 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_4 2 +#define SYSTEM_CTRL_PCI_SLAVE_BURST_READ_SIZE_8 3 +#define SYSTEM_CTRL_CRT_TRISTATE 2:2 +#define SYSTEM_CTRL_CRT_TRISTATE_DISABLE 0 +#define SYSTEM_CTRL_CRT_TRISTATE_ENABLE 1 +#define SYSTEM_CTRL_INTMEM_TRISTATE 1:1 +#define SYSTEM_CTRL_INTMEM_TRISTATE_DISABLE 0 +#define SYSTEM_CTRL_INTMEM_TRISTATE_ENABLE 1 +#define SYSTEM_CTRL_PANEL_TRISTATE 0:0 +#define SYSTEM_CTRL_PANEL_TRISTATE_DISABLE 0 +#define SYSTEM_CTRL_PANEL_TRISTATE_ENABLE 1 + +#define MISC_CTRL 0x000004 +#define MISC_CTRL_PCI_PAD 31:30 +#define MISC_CTRL_PCI_PAD_24MA 0 +#define MISC_CTRL_PCI_PAD_12MA 1 +#define MISC_CTRL_PCI_PAD_8MA 2 +#define MISC_CTRL_48_SELECT 29:28 +#define MISC_CTRL_48_SELECT_CRYSTAL 0 +#define MISC_CTRL_48_SELECT_CPU_96 2 +#define MISC_CTRL_48_SELECT_CPU_48 3 +#define MISC_CTRL_UART1_SELECT 27:27 +#define MISC_CTRL_UART1_SELECT_UART 0 +#define MISC_CTRL_UART1_SELECT_SSP 1 +#define MISC_CTRL_8051_LATCH 26:26 +#define MISC_CTRL_8051_LATCH_DISABLE 0 +#define MISC_CTRL_8051_LATCH_ENABLE 1 +#define MISC_CTRL_FPDATA 25:25 +#define MISC_CTRL_FPDATA_18 0 +#define MISC_CTRL_FPDATA_24 1 +#define MISC_CTRL_CRYSTAL 24:24 +#define MISC_CTRL_CRYSTAL_24 0 +#define MISC_CTRL_CRYSTAL_12 1 +#define MISC_CTRL_DRAM_REFRESH 22:21 +#define MISC_CTRL_DRAM_REFRESH_8 0 +#define MISC_CTRL_DRAM_REFRESH_16 1 +#define MISC_CTRL_DRAM_REFRESH_32 2 +#define MISC_CTRL_DRAM_REFRESH_64 3 +#define MISC_CTRL_BUS_HOLD 20:18 +#define MISC_CTRL_BUS_HOLD_FIFO_EMPTY 0 +#define MISC_CTRL_BUS_HOLD_8 1 +#define MISC_CTRL_BUS_HOLD_16 2 +#define MISC_CTRL_BUS_HOLD_24 3 +#define MISC_CTRL_BUS_HOLD_32 4 +#define MISC_CTRL_HITACHI_READY 17:17 +#define MISC_CTRL_HITACHI_READY_NEGATIVE 0 +#define MISC_CTRL_HITACHI_READY_POSITIVE 1 +#define MISC_CTRL_INTERRUPT 16:16 +#define MISC_CTRL_INTERRUPT_NORMAL 0 +#define MISC_CTRL_INTERRUPT_INVERT 1 +#define MISC_CTRL_PLL_CLOCK_COUNT 15:15 +#define MISC_CTRL_PLL_CLOCK_COUNT_DISABLE 0 +#define MISC_CTRL_PLL_CLOCK_COUNT_ENABLE 1 +#define MISC_CTRL_DAC_BAND_GAP 14:13 +#define MISC_CTRL_DAC_POWER 12:12 +#define MISC_CTRL_DAC_POWER_ENABLE 0 +#define MISC_CTRL_DAC_POWER_DISABLE 1 +#define MISC_CTRL_USB_SLAVE_CONTROLLER 11:11 +#define MISC_CTRL_USB_SLAVE_CONTROLLER_CPU 0 +#define MISC_CTRL_USB_SLAVE_CONTROLLER_8051 1 +#define MISC_CTRL_BURST_LENGTH 10:10 +#define MISC_CTRL_BURST_LENGTH_8 0 +#define MISC_CTRL_BURST_LENGTH_1 1 +#define MISC_CTRL_USB_SELECT 9:9 +#define MISC_CTRL_USB_SELECT_MASTER 0 +#define MISC_CTRL_USB_SELECT_SLAVE 1 +#define MISC_CTRL_LOOPBACK 8:8 +#define MISC_CTRL_LOOPBACK_NORMAL 0 +#define MISC_CTRL_LOOPBACK_USB_HOST 1 +#define MISC_CTRL_CLOCK_DIVIDER_RESET 7:7 +#define MISC_CTRL_CLOCK_DIVIDER_RESET_ENABLE 0 +#define MISC_CTRL_CLOCK_DIVIDER_RESET_DISABLE 1 +#define MISC_CTRL_TEST_MODE 6:5 +#define MISC_CTRL_TEST_MODE_NORMAL 0 +#define MISC_CTRL_TEST_MODE_DEBUGGING 1 +#define MISC_CTRL_TEST_MODE_NAND 2 +#define MISC_CTRL_TEST_MODE_MEMORY 3 +#define MISC_CTRL_NEC_MMIO 4:4 +#define MISC_CTRL_NEC_MMIO_30 0 +#define MISC_CTRL_NEC_MMIO_62 1 +#define MISC_CTRL_CLOCK 3:3 +#define MISC_CTRL_CLOCK_PLL 0 +#define MISC_CTRL_CLOCK_TEST 1 +#define MISC_CTRL_HOST_BUS 2:0 +#define MISC_CTRL_HOST_BUS_HITACHI 0 +#define MISC_CTRL_HOST_BUS_PCI 1 +#define MISC_CTRL_HOST_BUS_XSCALE 2 +#define MISC_CTRL_HOST_BUS_STRONGARM 4 +#define MISC_CTRL_HOST_BUS_NEC 6 + +#define GPIO_MUX_LOW 0x000008 +#define GPIO_MUX_LOW_31 31:31 +#define GPIO_MUX_LOW_31_GPIO 0 +#define GPIO_MUX_LOW_31_PWM 1 +#define GPIO_MUX_LOW_30 30:30 +#define GPIO_MUX_LOW_30_GPIO 0 +#define GPIO_MUX_LOW_30_PWM 1 +#define GPIO_MUX_LOW_29 29:29 +#define GPIO_MUX_LOW_29_GPIO 0 +#define GPIO_MUX_LOW_29_PWM 1 +#define GPIO_MUX_LOW_28 28:28 +#define GPIO_MUX_LOW_28_GPIO 0 +#define GPIO_MUX_LOW_28_AC97_I2S 1 +#define GPIO_MUX_LOW_27 27:27 +#define GPIO_MUX_LOW_27_GPIO 0 +#define GPIO_MUX_LOW_27_AC97_I2S 1 +#define GPIO_MUX_LOW_26 26:26 +#define GPIO_MUX_LOW_26_GPIO 0 +#define GPIO_MUX_LOW_26_AC97_I2S 1 +#define GPIO_MUX_LOW_25 25:25 +#define GPIO_MUX_LOW_25_GPIO 0 +#define GPIO_MUX_LOW_25_AC97_I2S 1 +#define GPIO_MUX_LOW_24 24:24 +#define GPIO_MUX_LOW_24_GPIO 0 +#define GPIO_MUX_LOW_24_AC97 1 +#define GPIO_MUX_LOW_23 23:23 +#define GPIO_MUX_LOW_23_GPIO 0 +#define GPIO_MUX_LOW_23_ZVPORT 1 +#define GPIO_MUX_LOW_22 22:22 +#define GPIO_MUX_LOW_22_GPIO 0 +#define GPIO_MUX_LOW_22_ZVPORT 1 +#define GPIO_MUX_LOW_21 21:21 +#define GPIO_MUX_LOW_21_GPIO 0 +#define GPIO_MUX_LOW_21_ZVPORT 1 +#define GPIO_MUX_LOW_20 20:20 +#define GPIO_MUX_LOW_20_GPIO 0 +#define GPIO_MUX_LOW_20_ZVPORT 1 +#define GPIO_MUX_LOW_19 19:19 +#define GPIO_MUX_LOW_19_GPIO 0 +#define GPIO_MUX_LOW_19_ZVPORT 1 +#define GPIO_MUX_LOW_18 18:18 +#define GPIO_MUX_LOW_18_GPIO 0 +#define GPIO_MUX_LOW_18_ZVPORT 1 +#define GPIO_MUX_LOW_17 17:17 +#define GPIO_MUX_LOW_17_GPIO 0 +#define GPIO_MUX_LOW_17_ZVPORT 1 +#define GPIO_MUX_LOW_16 16:16 +#define GPIO_MUX_LOW_16_GPIO 0 +#define GPIO_MUX_LOW_16_ZVPORT 1 +#define GPIO_MUX_LOW_15 15:15 +#define GPIO_MUX_LOW_15_GPIO 0 +#define GPIO_MUX_LOW_15_8051 1 +#define GPIO_MUX_LOW_14 14:14 +#define GPIO_MUX_LOW_14_GPIO 0 +#define GPIO_MUX_LOW_14_8051 1 +#define GPIO_MUX_LOW_13 13:13 +#define GPIO_MUX_LOW_13_GPIO 0 +#define GPIO_MUX_LOW_13_8051 1 +#define GPIO_MUX_LOW_12 12:12 +#define GPIO_MUX_LOW_12_GPIO 0 +#define GPIO_MUX_LOW_12_8051 1 +#define GPIO_MUX_LOW_11 11:11 +#define GPIO_MUX_LOW_11_GPIO 0 +#define GPIO_MUX_LOW_11_8051 1 +#define GPIO_MUX_LOW_10 10:10 +#define GPIO_MUX_LOW_10_GPIO 0 +#define GPIO_MUX_LOW_10_8051 1 +#define GPIO_MUX_LOW_9 9:9 +#define GPIO_MUX_LOW_9_GPIO 0 +#define GPIO_MUX_LOW_9_8051 1 +#define GPIO_MUX_LOW_8 8:8 +#define GPIO_MUX_LOW_8_GPIO 0 +#define GPIO_MUX_LOW_8_8051 1 +#define GPIO_MUX_LOW_7 7:7 +#define GPIO_MUX_LOW_7_GPIO 0 +#define GPIO_MUX_LOW_7_8051 1 +#define GPIO_MUX_LOW_6 6:6 +#define GPIO_MUX_LOW_6_GPIO 0 +#define GPIO_MUX_LOW_6_8051 1 +#define GPIO_MUX_LOW_5 5:5 +#define GPIO_MUX_LOW_5_GPIO 0 +#define GPIO_MUX_LOW_5_8051 1 +#define GPIO_MUX_LOW_4 4:4 +#define GPIO_MUX_LOW_4_GPIO 0 +#define GPIO_MUX_LOW_4_8051 1 +#define GPIO_MUX_LOW_3 3:3 +#define GPIO_MUX_LOW_3_GPIO 0 +#define GPIO_MUX_LOW_3_8051 1 +#define GPIO_MUX_LOW_2 2:2 +#define GPIO_MUX_LOW_2_GPIO 0 +#define GPIO_MUX_LOW_2_8051 1 +#define GPIO_MUX_LOW_1 1:1 +#define GPIO_MUX_LOW_1_GPIO 0 +#define GPIO_MUX_LOW_1_8051 1 +#define GPIO_MUX_LOW_0 0:0 +#define GPIO_MUX_LOW_0_GPIO 0 +#define GPIO_MUX_LOW_0_8051 1 + +#define GPIO_MUX_HIGH 0x00000C +#define GPIO_MUX_HIGH_63 31:31 +#define GPIO_MUX_HIGH_63_GPIO 0 +#define GPIO_MUX_HIGH_63_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_62 30:30 +#define GPIO_MUX_HIGH_62_GPIO 0 +#define GPIO_MUX_HIGH_62_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_61 29:29 +#define GPIO_MUX_HIGH_61_GPIO 0 +#define GPIO_MUX_HIGH_61_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_60 28:28 +#define GPIO_MUX_HIGH_60_GPIO 0 +#define GPIO_MUX_HIGH_60_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_59 27:27 +#define GPIO_MUX_HIGH_59_GPIO 0 +#define GPIO_MUX_HIGH_59_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_58 26:26 +#define GPIO_MUX_HIGH_58_GPIO 0 +#define GPIO_MUX_HIGH_58_CRT_ZVPORT_FPDATA 1 +#define GPIO_MUX_HIGH_57 25:25 +#define GPIO_MUX_HIGH_57_GPIO 0 +#define GPIO_MUX_HIGH_57_CRT_ZVPORT 1 +#define GPIO_MUX_HIGH_56 24:24 +#define GPIO_MUX_HIGH_56_GPIO 0 +#define GPIO_MUX_HIGH_56_CRT_ZVPORT 1 +#define GPIO_MUX_HIGH_55 23:23 +#define GPIO_MUX_HIGH_55_GPIO 0 +#define GPIO_MUX_HIGH_55_CRT 1 +#define GPIO_MUX_HIGH_47 15:15 +#define GPIO_MUX_HIGH_47_GPIO 0 +#define GPIO_MUX_HIGH_47_I2C 1 +#define GPIO_MUX_HIGH_46 14:14 +#define GPIO_MUX_HIGH_46_GPIO 0 +#define GPIO_MUX_HIGH_46_I2C 1 +#define GPIO_MUX_HIGH_45 13:13 +#define GPIO_MUX_HIGH_45_GPIO 0 +#define GPIO_MUX_HIGH_45_SSP1 1 +#define GPIO_MUX_HIGH_44 12:12 +#define GPIO_MUX_HIGH_44_GPIO 0 +#define GPIO_MUX_HIGH_44_UART1_SSP1 1 +#define GPIO_MUX_HIGH_43 11:11 +#define GPIO_MUX_HIGH_43_GPIO 0 +#define GPIO_MUX_HIGH_43_UART1_SSP1 1 +#define GPIO_MUX_HIGH_42 10:10 +#define GPIO_MUX_HIGH_42_GPIO 0 +#define GPIO_MUX_HIGH_42_UART1_SSP1 1 +#define GPIO_MUX_HIGH_41 9:9 +#define GPIO_MUX_HIGH_41_GPIO 0 +#define GPIO_MUX_HIGH_41_UART1_SSP1 1 +#define GPIO_MUX_HIGH_40 8:8 +#define GPIO_MUX_HIGH_40_GPIO 0 +#define GPIO_MUX_HIGH_40_UART0 1 +#define GPIO_MUX_HIGH_39 7:7 +#define GPIO_MUX_HIGH_39_GPIO 0 +#define GPIO_MUX_HIGH_39_UART0 1 +#define GPIO_MUX_HIGH_38 6:6 +#define GPIO_MUX_HIGH_38_GPIO 0 +#define GPIO_MUX_HIGH_38_UART0 1 +#define GPIO_MUX_HIGH_37 5:5 +#define GPIO_MUX_HIGH_37_GPIO 0 +#define GPIO_MUX_HIGH_37_UART0 1 +#define GPIO_MUX_HIGH_36 4:4 +#define GPIO_MUX_HIGH_36_GPIO 0 +#define GPIO_MUX_HIGH_36_SSP0 1 +#define GPIO_MUX_HIGH_35 3:3 +#define GPIO_MUX_HIGH_35_GPIO 0 +#define GPIO_MUX_HIGH_35_SSP0 1 +#define GPIO_MUX_HIGH_34 2:2 +#define GPIO_MUX_HIGH_34_GPIO 0 +#define GPIO_MUX_HIGH_34_SSP0 1 +#define GPIO_MUX_HIGH_33 1:1 +#define GPIO_MUX_HIGH_33_GPIO 0 +#define GPIO_MUX_HIGH_33_SSP0 1 +#define GPIO_MUX_HIGH_32 0:0 +#define GPIO_MUX_HIGH_32_GPIO 0 +#define GPIO_MUX_HIGH_32_SSP0 1 + +#define DRAM_CTRL 0x000010 +#define DRAM_CTRL_EMBEDDED 31:31 +#define DRAM_CTRL_EMBEDDED_ENABLE 0 +#define DRAM_CTRL_EMBEDDED_DISABLE 1 +#define DRAM_CTRL_CPU_BURST 30:28 +#define DRAM_CTRL_CPU_BURST_1 0 +#define DRAM_CTRL_CPU_BURST_2 1 +#define DRAM_CTRL_CPU_BURST_4 2 +#define DRAM_CTRL_CPU_BURST_8 3 +#define DRAM_CTRL_CPU_CAS_LATENCY 27:27 +#define DRAM_CTRL_CPU_CAS_LATENCY_2 0 +#define DRAM_CTRL_CPU_CAS_LATENCY_3 1 +#define DRAM_CTRL_CPU_SIZE 26:24 +#define DRAM_CTRL_CPU_SIZE_2 0 +#define DRAM_CTRL_CPU_SIZE_4 1 +#define DRAM_CTRL_CPU_SIZE_64 4 +#define DRAM_CTRL_CPU_SIZE_32 5 +#define DRAM_CTRL_CPU_SIZE_16 6 +#define DRAM_CTRL_CPU_SIZE_8 7 +#define DRAM_CTRL_CPU_COLUMN_SIZE 23:22 +#define DRAM_CTRL_CPU_COLUMN_SIZE_1024 0 +#define DRAM_CTRL_CPU_COLUMN_SIZE_512 2 +#define DRAM_CTRL_CPU_COLUMN_SIZE_256 3 +#define DRAM_CTRL_CPU_ACTIVE_PRECHARGE 21:21 +#define DRAM_CTRL_CPU_ACTIVE_PRECHARGE_6 0 +#define DRAM_CTRL_CPU_ACTIVE_PRECHARGE_7 1 +#define DRAM_CTRL_CPU_RESET 20:20 +#define DRAM_CTRL_CPU_RESET_ENABLE 0 +#define DRAM_CTRL_CPU_RESET_DISABLE 1 +#define DRAM_CTRL_CPU_BANKS 19:19 +#define DRAM_CTRL_CPU_BANKS_2 0 +#define DRAM_CTRL_CPU_BANKS_4 1 +#define DRAM_CTRL_CPU_WRITE_PRECHARGE 18:18 +#define DRAM_CTRL_CPU_WRITE_PRECHARGE_2 0 +#define DRAM_CTRL_CPU_WRITE_PRECHARGE_1 1 +#define DRAM_CTRL_BLOCK_WRITE 17:17 +#define DRAM_CTRL_BLOCK_WRITE_DISABLE 0 +#define DRAM_CTRL_BLOCK_WRITE_ENABLE 1 +#define DRAM_CTRL_REFRESH_COMMAND 16:16 +#define DRAM_CTRL_REFRESH_COMMAND_10 0 +#define DRAM_CTRL_REFRESH_COMMAND_12 1 +#define DRAM_CTRL_SIZE 15:13 +#define DRAM_CTRL_SIZE_4 0 +#define DRAM_CTRL_SIZE_8 1 +#define DRAM_CTRL_SIZE_16 2 +#define DRAM_CTRL_SIZE_32 3 +#define DRAM_CTRL_SIZE_64 4 +#define DRAM_CTRL_SIZE_2 5 +#define DRAM_CTRL_COLUMN_SIZE 12:11 +#define DRAM_CTRL_COLUMN_SIZE_256 0 +#define DRAM_CTRL_COLUMN_SIZE_512 2 +#define DRAM_CTRL_COLUMN_SIZE_1024 3 +#define DRAM_CTRL_BLOCK_WRITE_TIME 10:10 +#define DRAM_CTRL_BLOCK_WRITE_TIME_1 0 +#define DRAM_CTRL_BLOCK_WRITE_TIME_2 1 +#define DRAM_CTRL_BLOCK_WRITE_PRECHARGE 9:9 +#define DRAM_CTRL_BLOCK_WRITE_PRECHARGE_4 0 +#define DRAM_CTRL_BLOCK_WRITE_PRECHARGE_1 1 +#define DRAM_CTRL_ACTIVE_PRECHARGE 8:8 +#define DRAM_CTRL_ACTIVE_PRECHARGE_6 0 +#define DRAM_CTRL_ACTIVE_PRECHARGE_7 1 +#define DRAM_CTRL_RESET 7:7 +#define DRAM_CTRL_RESET_ENABLE 0 +#define DRAM_CTRL_RESET_DISABLE 1 +#define DRAM_CTRL_REMAIN_ACTIVE 6:6 +#define DRAM_CTRL_REMAIN_ACTIVE_ENABLE 0 +#define DRAM_CTRL_REMAIN_ACTIVE_DISABLE 1 +#define DRAM_CTRL_BANKS 1:1 +#define DRAM_CTRL_BANKS_2 0 +#define DRAM_CTRL_BANKS_4 1 +#define DRAM_CTRL_WRITE_PRECHARGE 0:0 +#define DRAM_CTRL_WRITE_PRECHARGE_2 0 +#define DRAM_CTRL_WRITE_PRECHARGE_1 1 + +#define ARBITRATION_CTRL 0x000014 +#define ARBITRATION_CTRL_CPUMEM 29:29 +#define ARBITRATION_CTRL_CPUMEM_FIXED 0 +#define ARBITRATION_CTRL_CPUMEM_ROTATE 1 +#define ARBITRATION_CTRL_INTMEM 28:28 +#define ARBITRATION_CTRL_INTMEM_FIXED 0 +#define ARBITRATION_CTRL_INTMEM_ROTATE 1 +#define ARBITRATION_CTRL_USB 27:24 +#define ARBITRATION_CTRL_USB_OFF 0 +#define ARBITRATION_CTRL_USB_PRIORITY_1 1 +#define ARBITRATION_CTRL_USB_PRIORITY_2 2 +#define ARBITRATION_CTRL_USB_PRIORITY_3 3 +#define ARBITRATION_CTRL_USB_PRIORITY_4 4 +#define ARBITRATION_CTRL_USB_PRIORITY_5 5 +#define ARBITRATION_CTRL_USB_PRIORITY_6 6 +#define ARBITRATION_CTRL_USB_PRIORITY_7 7 +#define ARBITRATION_CTRL_PANEL 23:20 +#define ARBITRATION_CTRL_PANEL_OFF 0 +#define ARBITRATION_CTRL_PANEL_PRIORITY_1 1 +#define ARBITRATION_CTRL_PANEL_PRIORITY_2 2 +#define ARBITRATION_CTRL_PANEL_PRIORITY_3 3 +#define ARBITRATION_CTRL_PANEL_PRIORITY_4 4 +#define ARBITRATION_CTRL_PANEL_PRIORITY_5 5 +#define ARBITRATION_CTRL_PANEL_PRIORITY_6 6 +#define ARBITRATION_CTRL_PANEL_PRIORITY_7 7 +#define ARBITRATION_CTRL_ZVPORT 19:16 +#define ARBITRATION_CTRL_ZVPORT_OFF 0 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_1 1 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_2 2 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_3 3 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_4 4 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_5 5 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_6 6 +#define ARBITRATION_CTRL_ZVPORT_PRIORITY_7 7 +#define ARBITRATION_CTRL_CMD_INTPR 15:12 +#define ARBITRATION_CTRL_CMD_INTPR_OFF 0 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_1 1 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_2 2 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_3 3 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_4 4 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_5 5 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_6 6 +#define ARBITRATION_CTRL_CMD_INTPR_PRIORITY_7 7 +#define ARBITRATION_CTRL_DMA 11:8 +#define ARBITRATION_CTRL_DMA_OFF 0 +#define ARBITRATION_CTRL_DMA_PRIORITY_1 1 +#define ARBITRATION_CTRL_DMA_PRIORITY_2 2 +#define ARBITRATION_CTRL_DMA_PRIORITY_3 3 +#define ARBITRATION_CTRL_DMA_PRIORITY_4 4 +#define ARBITRATION_CTRL_DMA_PRIORITY_5 5 +#define ARBITRATION_CTRL_DMA_PRIORITY_6 6 +#define ARBITRATION_CTRL_DMA_PRIORITY_7 7 +#define ARBITRATION_CTRL_VIDEO 7:4 +#define ARBITRATION_CTRL_VIDEO_OFF 0 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_1 1 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_2 2 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_3 3 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_4 4 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_5 5 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_6 6 +#define ARBITRATION_CTRL_VIDEO_PRIORITY_7 7 +#define ARBITRATION_CTRL_CRT 3:0 +#define ARBITRATION_CTRL_CRT_OFF 0 +#define ARBITRATION_CTRL_CRT_PRIORITY_1 1 +#define ARBITRATION_CTRL_CRT_PRIORITY_2 2 +#define ARBITRATION_CTRL_CRT_PRIORITY_3 3 +#define ARBITRATION_CTRL_CRT_PRIORITY_4 4 +#define ARBITRATION_CTRL_CRT_PRIORITY_5 5 +#define ARBITRATION_CTRL_CRT_PRIORITY_6 6 +#define ARBITRATION_CTRL_CRT_PRIORITY_7 7 + +#define CMD_INTPR_CTRL 0x000018 +#define CMD_INTPR_CTRL_STATUS 31:31 +#define CMD_INTPR_CTRL_STATUS_STOPPED 0 +#define CMD_INTPR_CTRL_STATUS_RUNNING 1 +#define CMD_INTPR_CTRL_EXT 27:27 +#define CMD_INTPR_CTRL_EXT_LOCAL 0 +#define CMD_INTPR_CTRL_EXT_EXTERNAL 1 +#define CMD_INTPR_CTRL_CS 26:26 +#define CMD_INTPR_CTRL_CS_0 0 +#define CMD_INTPR_CTRL_CS_1 1 +#define CMD_INTPR_CTRL_ADDRESS 25:0 + +#define CMD_INTPR_CONDITIONS 0x00001C + +#define CMD_INTPR_RETURN 0x000020 +#define CMD_INTPR_RETURN_EXT 27:27 +#define CMD_INTPR_RETURN_EXT_LOCAL 0 +#define CMD_INTPR_RETURN_EXT_EXTERNAL 1 +#define CMD_INTPR_RETURN_CS 26:26 +#define CMD_INTPR_RETURN_CS_0 0 +#define CMD_INTPR_RETURN_CS_1 1 +#define CMD_INTPR_RETURN_ADDRESS 25:0 + +#define CMD_INTPR_STATUS 0x000024 +#define CMD_INTPR_STATUS_2D_MEMORY_FIFO 20:20 +#define CMD_INTPR_STATUS_2D_MEMORY_FIFO_NOT_EMPTY 0 +#define CMD_INTPR_STATUS_2D_MEMORY_FIFO_EMPTY 1 +#define CMD_INTPR_STATUS_COMMAND_FIFO 19:19 +#define CMD_INTPR_STATUS_COMMAND_FIFO_NOT_EMPTY 0 +#define CMD_INTPR_STATUS_COMMAND_FIFO_EMPTY 1 +#define CMD_INTPR_STATUS_CSC_STATUS 18:18 +#define CMD_INTPR_STATUS_CSC_STATUS_IDLE 0 +#define CMD_INTPR_STATUS_CSC_STATUS_BUSY 1 +#define CMD_INTPR_STATUS_MEMORY_DMA 17:17 +#define CMD_INTPR_STATUS_MEMORY_DMA_IDLE 0 +#define CMD_INTPR_STATUS_MEMORY_DMA_BUSY 1 +#define CMD_INTPR_STATUS_CRT_STATUS 16:16 +#define CMD_INTPR_STATUS_CRT_STATUS_CURRENT 0 +#define CMD_INTPR_STATUS_CRT_STATUS_PENDING 1 +#define CMD_INTPR_STATUS_CURRENT_FIELD 15:15 +#define CMD_INTPR_STATUS_CURRENT_FIELD_ODD 0 +#define CMD_INTPR_STATUS_CURRENT_FIELD_EVEN 1 +#define CMD_INTPR_STATUS_VIDEO_STATUS 14:14 +#define CMD_INTPR_STATUS_VIDEO_STATUS_CURRENT 0 +#define CMD_INTPR_STATUS_VIDEO_STATUS_PENDING 1 +#define CMD_INTPR_STATUS_PANEL_STATUS 13:13 +#define CMD_INTPR_STATUS_PANEL_STATUS_CURRENT 0 +#define CMD_INTPR_STATUS_PANEL_STATUS_PENDING 1 +#define CMD_INTPR_STATUS_CRT_SYNC 12:12 +#define CMD_INTPR_STATUS_CRT_SYNC_INACTIVE 0 +#define CMD_INTPR_STATUS_CRT_SYNC_ACTIVE 1 +#define CMD_INTPR_STATUS_PANEL_SYNC 11:11 +#define CMD_INTPR_STATUS_PANEL_SYNC_INACTIVE 0 +#define CMD_INTPR_STATUS_PANEL_SYNC_ACTIVE 1 +#define CMD_INTPR_STATUS_2D_SETUP 2:2 +#define CMD_INTPR_STATUS_2D_SETUP_IDLE 0 +#define CMD_INTPR_STATUS_2D_SETUP_BUSY 1 +#define CMD_INTPR_STATUS_2D_FIFO 1:1 +#define CMD_INTPR_STATUS_2D_FIFO_NOT_EMPTY 0 +#define CMD_INTPR_STATUS_2D_FIFO_EMPTY 1 +#define CMD_INTPR_STATUS_2D_ENGINE 0:0 +#define CMD_INTPR_STATUS_2D_ENGINE_IDLE 0 +#define CMD_INTPR_STATUS_2D_ENGINE_BUSY 1 + +#define RAW_INT_STATUS 0x000028 +#define RAW_INT_STATUS_USB_SLAVE_PLUG_IN 5:5 +#define RAW_INT_STATUS_USB_SLAVE_PLUG_IN_INACTIVE 0 +#define RAW_INT_STATUS_USB_SLAVE_PLUG_IN_ACTIVE 1 +#define RAW_INT_STATUS_USB_SLAVE_PLUG_IN_CLEAR 1 +#define RAW_INT_STATUS_ZVPORT 4:4 +#define RAW_INT_STATUS_ZVPORT_INACTIVE 0 +#define RAW_INT_STATUS_ZVPORT_ACTIVE 1 +#define RAW_INT_STATUS_ZVPORT_CLEAR 1 +#define RAW_INT_STATUS_CRT_VSYNC 3:3 +#define RAW_INT_STATUS_CRT_VSYNC_INACTIVE 0 +#define RAW_INT_STATUS_CRT_VSYNC_ACTIVE 1 +#define RAW_INT_STATUS_CRT_VSYNC_CLEAR 1 +#define RAW_INT_STATUS_USB_SLAVE 2:2 +#define RAW_INT_STATUS_USB_SLAVE_INACTIVE 0 +#define RAW_INT_STATUS_USB_SLAVE_ACTIVE 1 +#define RAW_INT_STATUS_USB_SLAVE_CLEAR 1 +#define RAW_INT_STATUS_PANEL_VSYNC 1:1 +#define RAW_INT_STATUS_PANEL_VSYNC_INACTIVE 0 +#define RAW_INT_STATUS_PANEL_VSYNC_ACTIVE 1 +#define RAW_INT_STATUS_PANEL_VSYNC_CLEAR 1 +#define RAW_INT_STATUS_CMD_INTPR 0:0 +#define RAW_INT_STATUS_CMD_INTPR_INACTIVE 0 +#define RAW_INT_STATUS_CMD_INTPR_ACTIVE 1 +#define RAW_INT_STATUS_CMD_INTPR_CLEAR 1 + +#define INT_STATUS 0x00002C +#define INT_STATUS_USB_SLAVE_PLUG_IN 31:31 +#define INT_STATUS_USB_SLAVE_PLUG_IN_INACTIVE 0 +#define INT_STATUS_USB_SLAVE_PLUG_IN_ACTIVE 1 +#define INT_STATUS_GPIO54 30:30 +#define INT_STATUS_GPIO54_INACTIVE 0 +#define INT_STATUS_GPIO54_ACTIVE 1 +#define INT_STATUS_GPIO53 29:29 +#define INT_STATUS_GPIO53_INACTIVE 0 +#define INT_STATUS_GPIO53_ACTIVE 1 +#define INT_STATUS_GPIO52 28:28 +#define INT_STATUS_GPIO52_INACTIVE 0 +#define INT_STATUS_GPIO52_ACTIVE 1 +#define INT_STATUS_GPIO51 27:27 +#define INT_STATUS_GPIO51_INACTIVE 0 +#define INT_STATUS_GPIO51_ACTIVE 1 +#define INT_STATUS_GPIO50 26:26 +#define INT_STATUS_GPIO50_INACTIVE 0 +#define INT_STATUS_GPIO50_ACTIVE 1 +#define INT_STATUS_GPIO49 25:25 +#define INT_STATUS_GPIO49_INACTIVE 0 +#define INT_STATUS_GPIO49_ACTIVE 1 +#define INT_STATUS_GPIO48 24:24 +#define INT_STATUS_GPIO48_INACTIVE 0 +#define INT_STATUS_GPIO48_ACTIVE 1 +#define INT_STATUS_I2C 23:23 +#define INT_STATUS_I2C_INACTIVE 0 +#define INT_STATUS_I2C_ACTIVE 1 +#define INT_STATUS_PWM 22:22 +#define INT_STATUS_PWM_INACTIVE 0 +#define INT_STATUS_PWM_ACTIVE 1 +#define INT_STATUS_DMA 20:20 +#define INT_STATUS_DMA_INACTIVE 0 +#define INT_STATUS_DMA_ACTIVE 1 +#define INT_STATUS_PCI 19:19 +#define INT_STATUS_PCI_INACTIVE 0 +#define INT_STATUS_PCI_ACTIVE 1 +#define INT_STATUS_I2S 18:18 +#define INT_STATUS_I2S_INACTIVE 0 +#define INT_STATUS_I2S_ACTIVE 1 +#define INT_STATUS_AC97 17:17 +#define INT_STATUS_AC97_INACTIVE 0 +#define INT_STATUS_AC97_ACTIVE 1 +#define INT_STATUS_USB_SLAVE 16:16 +#define INT_STATUS_USB_SLAVE_INACTIVE 0 +#define INT_STATUS_USB_SLAVE_ACTIVE 1 +#define INT_STATUS_UART1 13:13 +#define INT_STATUS_UART1_INACTIVE 0 +#define INT_STATUS_UART1_ACTIVE 1 +#define INT_STATUS_UART0 12:12 +#define INT_STATUS_UART0_INACTIVE 0 +#define INT_STATUS_UART0_ACTIVE 1 +#define INT_STATUS_CRT_VSYNC 11:11 +#define INT_STATUS_CRT_VSYNC_INACTIVE 0 +#define INT_STATUS_CRT_VSYNC_ACTIVE 1 +#define INT_STATUS_8051 10:10 +#define INT_STATUS_8051_INACTIVE 0 +#define INT_STATUS_8051_ACTIVE 1 +#define INT_STATUS_SSP1 9:9 +#define INT_STATUS_SSP1_INACTIVE 0 +#define INT_STATUS_SSP1_ACTIVE 1 +#define INT_STATUS_SSP0 8:8 +#define INT_STATUS_SSP0_INACTIVE 0 +#define INT_STATUS_SSP0_ACTIVE 1 +#define INT_STATUS_USB_HOST 6:6 +#define INT_STATUS_USB_HOST_INACTIVE 0 +#define INT_STATUS_USB_HOST_ACTIVE 1 +#define INT_STATUS_2D 3:3 +#define INT_STATUS_2D_INACTIVE 0 +#define INT_STATUS_2D_ACTIVE 1 +#define INT_STATUS_ZVPORT 2:2 +#define INT_STATUS_ZVPORT_INACTIVE 0 +#define INT_STATUS_ZVPORT_ACTIVE 1 +#define INT_STATUS_PANEL_VSYNC 1:1 +#define INT_STATUS_PANEL_VSYNC_INACTIVE 0 +#define INT_STATUS_PANEL_VSYNC_ACTIVE 1 +#define INT_STATUS_CMD_INTPR 0:0 +#define INT_STATUS_CMD_INTPR_INACTIVE 0 +#define INT_STATUS_CMD_INTPR_ACTIVE 1 + +#define INT_MASK 0x000030 +#define INT_MASK_USB_SLAVE_PLUG_IN 31:31 +#define INT_MASK_USB_SLAVE_PLUG_IN_DISABLE 0 +#define INT_MASK_USB_SLAVE_PLUG_IN_ENABLE 1 +#define INT_MASK_GPIO54 30:30 +#define INT_MASK_GPIO54_DISABLE 0 +#define INT_MASK_GPIO54_ENABLE 1 +#define INT_MASK_GPIO53 29:29 +#define INT_MASK_GPIO53_DISABLE 0 +#define INT_MASK_GPIO53_ENABLE 1 +#define INT_MASK_GPIO52 28:28 +#define INT_MASK_GPIO52_DISABLE 0 +#define INT_MASK_GPIO52_ENABLE 1 +#define INT_MASK_GPIO51 27:27 +#define INT_MASK_GPIO51_DISABLE 0 +#define INT_MASK_GPIO51_ENABLE 1 +#define INT_MASK_GPIO50 26:26 +#define INT_MASK_GPIO50_DISABLE 0 +#define INT_MASK_GPIO50_ENABLE 1 +#define INT_MASK_GPIO49 25:25 +#define INT_MASK_GPIO49_DISABLE 0 +#define INT_MASK_GPIO49_ENABLE 1 +#define INT_MASK_GPIO48 24:24 +#define INT_MASK_GPIO48_DISABLE 0 +#define INT_MASK_GPIO48_ENABLE 1 +#define INT_MASK_I2C 23:23 +#define INT_MASK_I2C_DISABLE 0 +#define INT_MASK_I2C_ENABLE 1 +#define INT_MASK_PWM 22:22 +#define INT_MASK_PWM_DISABLE 0 +#define INT_MASK_PWM_ENABLE 1 +#define INT_MASK_DMA 20:20 +#define INT_MASK_DMA_DISABLE 0 +#define INT_MASK_DMA_ENABLE 1 +#define INT_MASK_PCI 19:19 +#define INT_MASK_PCI_DISABLE 0 +#define INT_MASK_PCI_ENABLE 1 +#define INT_MASK_I2S 18:18 +#define INT_MASK_I2S_DISABLE 0 +#define INT_MASK_I2S_ENABLE 1 +#define INT_MASK_AC97 17:17 +#define INT_MASK_AC97_DISABLE 0 +#define INT_MASK_AC97_ENABLE 1 +#define INT_MASK_USB_SLAVE 16:16 +#define INT_MASK_USB_SLAVE_DISABLE 0 +#define INT_MASK_USB_SLAVE_ENABLE 1 +#define INT_MASK_UART1 13:13 +#define INT_MASK_UART1_DISABLE 0 +#define INT_MASK_UART1_ENABLE 1 +#define INT_MASK_UART0 12:12 +#define INT_MASK_UART0_DISABLE 0 +#define INT_MASK_UART0_ENABLE 1 +#define INT_MASK_CRT_VSYNC 11:11 +#define INT_MASK_CRT_VSYNC_DISABLE 0 +#define INT_MASK_CRT_VSYNC_ENABLE 1 +#define INT_MASK_8051 10:10 +#define INT_MASK_8051_DISABLE 0 +#define INT_MASK_8051_ENABLE 1 +#define INT_MASK_SSP1 9:9 +#define INT_MASK_SSP1_DISABLE 0 +#define INT_MASK_SSP1_ENABLE 1 +#define INT_MASK_SSP0 8:8 +#define INT_MASK_SSP0_DISABLE 0 +#define INT_MASK_SSP0_ENABLE 1 +#define INT_MASK_USB_HOST 6:6 +#define INT_MASK_USB_HOST_DISABLE 0 +#define INT_MASK_USB_HOST_ENABLE 1 +#define INT_MASK_2D 3:3 +#define INT_MASK_2D_DISABLE 0 +#define INT_MASK_2D_ENABLE 1 +#define INT_MASK_ZVPORT 2:2 +#define INT_MASK_ZVPORT_DISABLE 0 +#define INT_MASK_ZVPORT_ENABLE 1 +#define INT_MASK_PANEL_VSYNC 1:1 +#define INT_MASK_PANEL_VSYNC_DISABLE 0 +#define INT_MASK_PANEL_VSYNC_ENABLE 1 +#define INT_MASK_CMD_INTPR 0:0 +#define INT_MASK_CMD_INTPR_DISABLE 0 +#define INT_MASK_CMD_INTPR_ENABLE 1 + +#define DEBUG_CTRL 0x000034 +#define DEBUG_CTRL_MODULE 7:5 +#define DEBUG_CTRL_PARTITION 4:0 +#define DEBUG_CTRL_PARTITION_HIF 0 +#define DEBUG_CTRL_PARTITION_CPUMEM 1 +#define DEBUG_CTRL_PARTITION_PCI 2 +#define DEBUG_CTRL_PARTITION_CMD_INTPR 3 +#define DEBUG_CTRL_PARTITION_DISPLAY 4 +#define DEBUG_CTRL_PARTITION_ZVPORT 5 +#define DEBUG_CTRL_PARTITION_2D 6 +#define DEBUG_CTRL_PARTITION_MIF 8 +#define DEBUG_CTRL_PARTITION_USB_HOST 10 +#define DEBUG_CTRL_PARTITION_SSP0 12 +#define DEBUG_CTRL_PARTITION_SSP1 13 +#define DEBUG_CTRL_PARTITION_UART0 19 +#define DEBUG_CTRL_PARTITION_UART1 20 +#define DEBUG_CTRL_PARTITION_I2C 21 +#define DEBUG_CTRL_PARTITION_8051 23 +#define DEBUG_CTRL_PARTITION_AC97 24 +#define DEBUG_CTRL_PARTITION_I2S 25 +#define DEBUG_CTRL_PARTITION_INTMEM 26 +#define DEBUG_CTRL_PARTITION_DMA 27 +#define DEBUG_CTRL_PARTITION_SIMULATION 28 + +#define CURRENT_POWER_GATE 0x000038 +#define CURRENT_POWER_GATE_AC97_I2S 18:18 +#define CURRENT_POWER_GATE_AC97_I2S_DISABLE 0 +#define CURRENT_POWER_GATE_AC97_I2S_ENABLE 1 +#define CURRENT_POWER_GATE_8051 17:17 +#define CURRENT_POWER_GATE_8051_DISABLE 0 +#define CURRENT_POWER_GATE_8051_ENABLE 1 +#define CURRENT_POWER_GATE_PLL 16:16 +#define CURRENT_POWER_GATE_PLL_DISABLE 0 +#define CURRENT_POWER_GATE_PLL_ENABLE 1 +#define CURRENT_POWER_GATE_OSCILLATOR 15:15 +#define CURRENT_POWER_GATE_OSCILLATOR_DISABLE 0 +#define CURRENT_POWER_GATE_OSCILLATOR_ENABLE 1 +#define CURRENT_POWER_GATE_PLL_RECOVERY 14:13 +#define CURRENT_POWER_GATE_PLL_RECOVERY_32 0 +#define CURRENT_POWER_GATE_PLL_RECOVERY_64 1 +#define CURRENT_POWER_GATE_PLL_RECOVERY_96 2 +#define CURRENT_POWER_GATE_PLL_RECOVERY_128 3 +#define CURRENT_POWER_GATE_USB_SLAVE 12:12 +#define CURRENT_POWER_GATE_USB_SLAVE_DISABLE 0 +#define CURRENT_POWER_GATE_USB_SLAVE_ENABLE 1 +#define CURRENT_POWER_GATE_USB_HOST 11:11 +#define CURRENT_POWER_GATE_USB_HOST_DISABLE 0 +#define CURRENT_POWER_GATE_USB_HOST_ENABLE 1 +#define CURRENT_POWER_GATE_SSP0_SSP1 10:10 +#define CURRENT_POWER_GATE_SSP0_SSP1_DISABLE 0 +#define CURRENT_POWER_GATE_SSP0_SSP1_ENABLE 1 +#define CURRENT_POWER_GATE_UART1 8:8 +#define CURRENT_POWER_GATE_UART1_DISABLE 0 +#define CURRENT_POWER_GATE_UART1_ENABLE 1 +#define CURRENT_POWER_GATE_UART0 7:7 +#define CURRENT_POWER_GATE_UART0_DISABLE 0 +#define CURRENT_POWER_GATE_UART0_ENABLE 1 +#define CURRENT_POWER_GATE_GPIO_PWM_I2C 6:6 +#define CURRENT_POWER_GATE_GPIO_PWM_I2C_DISABLE 0 +#define CURRENT_POWER_GATE_GPIO_PWM_I2C_ENABLE 1 +#define CURRENT_POWER_GATE_ZVPORT 5:5 +#define CURRENT_POWER_GATE_ZVPORT_DISABLE 0 +#define CURRENT_POWER_GATE_ZVPORT_ENABLE 1 +#define CURRENT_POWER_GATE_CSC 4:4 +#define CURRENT_POWER_GATE_CSC_DISABLE 0 +#define CURRENT_POWER_GATE_CSC_ENABLE 1 +#define CURRENT_POWER_GATE_2D 3:3 +#define CURRENT_POWER_GATE_2D_DISABLE 0 +#define CURRENT_POWER_GATE_2D_ENABLE 1 +#define CURRENT_POWER_GATE_DISPLAY 2:2 +#define CURRENT_POWER_GATE_DISPLAY_DISABLE 0 +#define CURRENT_POWER_GATE_DISPLAY_ENABLE 1 +#define CURRENT_POWER_GATE_INTMEM 1:1 +#define CURRENT_POWER_GATE_INTMEM_DISABLE 0 +#define CURRENT_POWER_GATE_INTMEM_ENABLE 1 +#define CURRENT_POWER_GATE_HOST 0:0 +#define CURRENT_POWER_GATE_HOST_DISABLE 0 +#define CURRENT_POWER_GATE_HOST_ENABLE 1 + +#define CURRENT_POWER_CLOCK 0x00003C +#define CURRENT_POWER_CLOCK_P1XCLK 31:31 +#define CURRENT_POWER_CLOCK_P1XCLK_ENABLE 1 +#define CURRENT_POWER_CLOCK_P1XCLK_DISABLE 0 +#define CURRENT_POWER_CLOCK_PLLCLK_SELECT 30:30 +#define CURRENT_POWER_CLOCK_PLLCLK_SELECT_ENABLE 1 +#define CURRENT_POWER_CLOCK_PLLCLK_SELECT_DISABLE 0 +#define CURRENT_POWER_CLOCK_P2XCLK_SELECT 29:29 +#define CURRENT_POWER_CLOCK_P2XCLK_SELECT_288 0 +#define CURRENT_POWER_CLOCK_P2XCLK_SELECT_336 1 +#define CURRENT_POWER_CLOCK_P2XCLK_DIVIDER 28:27 +#define CURRENT_POWER_CLOCK_P2XCLK_DIVIDER_1 0 +#define CURRENT_POWER_CLOCK_P2XCLK_DIVIDER_3 1 +#define CURRENT_POWER_CLOCK_P2XCLK_DIVIDER_5 2 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT 26:24 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_0 0 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_1 1 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_2 2 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_3 3 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_4 4 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_5 5 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_6 6 +#define CURRENT_POWER_CLOCK_P2XCLK_SHIFT_7 7 +#define CURRENT_POWER_CLOCK_V2XCLK_SELECT 20:20 +#define CURRENT_POWER_CLOCK_V2XCLK_SELECT_288 0 +#define CURRENT_POWER_CLOCK_V2XCLK_SELECT_336 1 +#define CURRENT_POWER_CLOCK_V2XCLK_DIVIDER 19:19 +#define CURRENT_POWER_CLOCK_V2XCLK_DIVIDER_1 0 +#define CURRENT_POWER_CLOCK_V2XCLK_DIVIDER_3 1 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT 18:16 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_0 0 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_1 1 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_2 2 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_3 3 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_4 4 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_5 5 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_6 6 +#define CURRENT_POWER_CLOCK_V2XCLK_SHIFT_7 7 +#define CURRENT_POWER_CLOCK_MCLK_SELECT 12:12 +#define CURRENT_POWER_CLOCK_MCLK_SELECT_288 0 +#define CURRENT_POWER_CLOCK_MCLK_SELECT_336 1 +#define CURRENT_POWER_CLOCK_MCLK_DIVIDER 11:11 +#define CURRENT_POWER_CLOCK_MCLK_DIVIDER_1 0 +#define CURRENT_POWER_CLOCK_MCLK_DIVIDER_3 1 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT 10:8 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_0 0 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_1 1 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_2 2 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_3 3 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_4 4 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_5 5 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_6 6 +#define CURRENT_POWER_CLOCK_MCLK_SHIFT_7 7 +#define CURRENT_POWER_CLOCK_M2XCLK_SELECT 4:4 +#define CURRENT_POWER_CLOCK_M2XCLK_SELECT_288 0 +#define CURRENT_POWER_CLOCK_M2XCLK_SELECT_336 1 +#define CURRENT_POWER_CLOCK_M2XCLK_DIVIDER 3:3 +#define CURRENT_POWER_CLOCK_M2XCLK_DIVIDER_1 0 +#define CURRENT_POWER_CLOCK_M2XCLK_DIVIDER_3 1 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT 2:0 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_0 0 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_1 1 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_2 2 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_3 3 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_4 4 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_5 5 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_6 6 +#define CURRENT_POWER_CLOCK_M2XCLK_SHIFT_7 7 + +#define POWER_MODE0_GATE 0x000040 +#define POWER_MODE0_GATE_AC97_I2S 18:18 +#define POWER_MODE0_GATE_AC97_I2S_DISABLE 0 +#define POWER_MODE0_GATE_AC97_I2S_ENABLE 1 +#define POWER_MODE0_GATE_8051 17:17 +#define POWER_MODE0_GATE_8051_DISABLE 0 +#define POWER_MODE0_GATE_8051_ENABLE 1 +#define POWER_MODE0_GATE_USB_SLAVE 12:12 +#define POWER_MODE0_GATE_USB_SLAVE_DISABLE 0 +#define POWER_MODE0_GATE_USB_SLAVE_ENABLE 1 +#define POWER_MODE0_GATE_USB_HOST 11:11 +#define POWER_MODE0_GATE_USB_HOST_DISABLE 0 +#define POWER_MODE0_GATE_USB_HOST_ENABLE 1 +#define POWER_MODE0_GATE_SSP0_SSP1 10:10 +#define POWER_MODE0_GATE_SSP0_SSP1_DISABLE 0 +#define POWER_MODE0_GATE_SSP0_SSP1_ENABLE 1 +#define POWER_MODE0_GATE_UART1 8:8 +#define POWER_MODE0_GATE_UART1_DISABLE 0 +#define POWER_MODE0_GATE_UART1_ENABLE 1 +#define POWER_MODE0_GATE_UART0 7:7 +#define POWER_MODE0_GATE_UART0_DISABLE 0 +#define POWER_MODE0_GATE_UART0_ENABLE 1 +#define POWER_MODE0_GATE_GPIO_PWM_I2C 6:6 +#define POWER_MODE0_GATE_GPIO_PWM_I2C_DISABLE 0 +#define POWER_MODE0_GATE_GPIO_PWM_I2C_ENABLE 1 +#define POWER_MODE0_GATE_ZVPORT 5:5 +#define POWER_MODE0_GATE_ZVPORT_DISABLE 0 +#define POWER_MODE0_GATE_ZVPORT_ENABLE 1 +#define POWER_MODE0_GATE_CSC 4:4 +#define POWER_MODE0_GATE_CSC_DISABLE 0 +#define POWER_MODE0_GATE_CSC_ENABLE 1 +#define POWER_MODE0_GATE_2D 3:3 +#define POWER_MODE0_GATE_2D_DISABLE 0 +#define POWER_MODE0_GATE_2D_ENABLE 1 +#define POWER_MODE0_GATE_DISPLAY 2:2 +#define POWER_MODE0_GATE_DISPLAY_DISABLE 0 +#define POWER_MODE0_GATE_DISPLAY_ENABLE 1 +#define POWER_MODE0_GATE_INTMEM 1:1 +#define POWER_MODE0_GATE_INTMEM_DISABLE 0 +#define POWER_MODE0_GATE_INTMEM_ENABLE 1 +#define POWER_MODE0_GATE_HOST 0:0 +#define POWER_MODE0_GATE_HOST_DISABLE 0 +#define POWER_MODE0_GATE_HOST_ENABLE 1 + +#define POWER_MODE0_CLOCK 0x000044 +#define POWER_MODE0_CLOCK_PLL3_P1XCLK 31:31 +#define POWER_MODE0_CLOCK_PLL3_P1XCLK_ENABLE 1 +#define POWER_MODE0_CLOCK_PLL3_P1XCLK_DISABLE 0 +#define POWER_MODE0_CLOCK_PLL3 30:30 +#define POWER_MODE0_CLOCK_PLL3_ENABLE 1 +#define POWER_MODE0_CLOCK_PLL3_DISABLE 0 +#define POWER_MODE0_CLOCK_P2XCLK_SELECT 29:29 +#define POWER_MODE0_CLOCK_P2XCLK_SELECT_288 0 +#define POWER_MODE0_CLOCK_P2XCLK_SELECT_336 1 +#define POWER_MODE0_CLOCK_P2XCLK_DIVIDER 28:27 +#define POWER_MODE0_CLOCK_P2XCLK_DIVIDER_1 0 +#define POWER_MODE0_CLOCK_P2XCLK_DIVIDER_3 1 +#define POWER_MODE0_CLOCK_P2XCLK_DIVIDER_5 2 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT 26:24 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_0 0 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_1 1 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_2 2 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_3 3 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_4 4 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_5 5 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_6 6 +#define POWER_MODE0_CLOCK_P2XCLK_SHIFT_7 7 +#define POWER_MODE0_CLOCK_V2XCLK_SELECT 20:20 +#define POWER_MODE0_CLOCK_V2XCLK_SELECT_288 0 +#define POWER_MODE0_CLOCK_V2XCLK_SELECT_336 1 +#define POWER_MODE0_CLOCK_V2XCLK_DIVIDER 19:19 +#define POWER_MODE0_CLOCK_V2XCLK_DIVIDER_1 0 +#define POWER_MODE0_CLOCK_V2XCLK_DIVIDER_3 1 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT 18:16 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_0 0 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_1 1 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_2 2 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_3 3 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_4 4 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_5 5 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_6 6 +#define POWER_MODE0_CLOCK_V2XCLK_SHIFT_7 7 +#define POWER_MODE0_CLOCK_MCLK_SELECT 12:12 +#define POWER_MODE0_CLOCK_MCLK_SELECT_288 0 +#define POWER_MODE0_CLOCK_MCLK_SELECT_336 1 +#define POWER_MODE0_CLOCK_MCLK_DIVIDER 11:11 +#define POWER_MODE0_CLOCK_MCLK_DIVIDER_1 0 +#define POWER_MODE0_CLOCK_MCLK_DIVIDER_3 1 +#define POWER_MODE0_CLOCK_MCLK_SHIFT 10:8 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_0 0 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_1 1 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_2 2 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_3 3 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_4 4 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_5 5 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_6 6 +#define POWER_MODE0_CLOCK_MCLK_SHIFT_7 7 +#define POWER_MODE0_CLOCK_M2XCLK_SELECT 4:4 +#define POWER_MODE0_CLOCK_M2XCLK_SELECT_288 0 +#define POWER_MODE0_CLOCK_M2XCLK_SELECT_336 1 +#define POWER_MODE0_CLOCK_M2XCLK_DIVIDER 3:3 +#define POWER_MODE0_CLOCK_M2XCLK_DIVIDER_1 0 +#define POWER_MODE0_CLOCK_M2XCLK_DIVIDER_3 1 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT 2:0 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_0 0 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_1 1 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_2 2 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_3 3 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_4 4 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_5 5 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_6 6 +#define POWER_MODE0_CLOCK_M2XCLK_SHIFT_7 7 + +#define POWER_MODE1_GATE 0x000048 +#define POWER_MODE1_GATE_AC97_I2S 18:18 +#define POWER_MODE1_GATE_AC97_I2S_DISABLE 0 +#define POWER_MODE1_GATE_AC97_I2S_ENABLE 1 +#define POWER_MODE1_GATE_8051 17:17 +#define POWER_MODE1_GATE_8051_DISABLE 0 +#define POWER_MODE1_GATE_8051_ENABLE 1 +#define POWER_MODE1_GATE_USB_SLAVE 12:12 +#define POWER_MODE1_GATE_USB_SLAVE_DISABLE 0 +#define POWER_MODE1_GATE_USB_SLAVE_ENABLE 1 +#define POWER_MODE1_GATE_USB_HOST 11:11 +#define POWER_MODE1_GATE_USB_HOST_DISABLE 0 +#define POWER_MODE1_GATE_USB_HOST_ENABLE 1 +#define POWER_MODE1_GATE_SSP0_SSP1 10:10 +#define POWER_MODE1_GATE_SSP0_SSP1_DISABLE 0 +#define POWER_MODE1_GATE_SSP0_SSP1_ENABLE 1 +#define POWER_MODE1_GATE_UART1 8:8 +#define POWER_MODE1_GATE_UART1_DISABLE 0 +#define POWER_MODE1_GATE_UART1_ENABLE 1 +#define POWER_MODE1_GATE_UART0 7:7 +#define POWER_MODE1_GATE_UART0_DISABLE 0 +#define POWER_MODE1_GATE_UART0_ENABLE 1 +#define POWER_MODE1_GATE_GPIO_PWM_I2C 6:6 +#define POWER_MODE1_GATE_GPIO_PWM_I2C_DISABLE 0 +#define POWER_MODE1_GATE_GPIO_PWM_I2C_ENABLE 1 +#define POWER_MODE1_GATE_ZVPORT 5:5 +#define POWER_MODE1_GATE_ZVPORT_DISABLE 0 +#define POWER_MODE1_GATE_ZVPORT_ENABLE 1 +#define POWER_MODE1_GATE_CSC 4:4 +#define POWER_MODE1_GATE_CSC_DISABLE 0 +#define POWER_MODE1_GATE_CSC_ENABLE 1 +#define POWER_MODE1_GATE_2D 3:3 +#define POWER_MODE1_GATE_2D_DISABLE 0 +#define POWER_MODE1_GATE_2D_ENABLE 1 +#define POWER_MODE1_GATE_DISPLAY 2:2 +#define POWER_MODE1_GATE_DISPLAY_DISABLE 0 +#define POWER_MODE1_GATE_DISPLAY_ENABLE 1 +#define POWER_MODE1_GATE_INTMEM 1:1 +#define POWER_MODE1_GATE_INTMEM_DISABLE 0 +#define POWER_MODE1_GATE_INTMEM_ENABLE 1 +#define POWER_MODE1_GATE_HOST 0:0 +#define POWER_MODE1_GATE_HOST_DISABLE 0 +#define POWER_MODE1_GATE_HOST_ENABLE 1 + +#define POWER_MODE1_CLOCK 0x00004C +#define POWER_MODE1_CLOCK_PLL3_P1XCLK 31:31 +#define POWER_MODE1_CLOCK_PLL3_P1XCLK_ENABLE 1 +#define POWER_MODE1_CLOCK_PLL3_P1XCLK_DISABLE 0 +#define POWER_MODE1_CLOCK_PLL3 30:30 +#define POWER_MODE1_CLOCK_PLL3_ENABLE 1 +#define POWER_MODE1_CLOCK_PLL3_DISABLE 0 +#define POWER_MODE1_CLOCK_P2XCLK_SELECT 29:29 +#define POWER_MODE1_CLOCK_P2XCLK_SELECT_288 0 +#define POWER_MODE1_CLOCK_P2XCLK_SELECT_336 1 +#define POWER_MODE1_CLOCK_P2XCLK_DIVIDER 28:27 +#define POWER_MODE1_CLOCK_P2XCLK_DIVIDER_1 0 +#define POWER_MODE1_CLOCK_P2XCLK_DIVIDER_3 1 +#define POWER_MODE1_CLOCK_P2XCLK_DIVIDER_5 2 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT 26:24 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_0 0 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_1 1 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_2 2 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_3 3 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_4 4 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_5 5 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_6 6 +#define POWER_MODE1_CLOCK_P2XCLK_SHIFT_7 7 +#define POWER_MODE1_CLOCK_V2XCLK_SELECT 20:20 +#define POWER_MODE1_CLOCK_V2XCLK_SELECT_288 0 +#define POWER_MODE1_CLOCK_V2XCLK_SELECT_336 1 +#define POWER_MODE1_CLOCK_V2XCLK_DIVIDER 19:19 +#define POWER_MODE1_CLOCK_V2XCLK_DIVIDER_1 0 +#define POWER_MODE1_CLOCK_V2XCLK_DIVIDER_3 1 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT 18:16 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_0 0 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_1 1 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_2 2 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_3 3 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_4 4 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_5 5 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_6 6 +#define POWER_MODE1_CLOCK_V2XCLK_SHIFT_7 7 +#define POWER_MODE1_CLOCK_MCLK_SELECT 12:12 +#define POWER_MODE1_CLOCK_MCLK_SELECT_288 0 +#define POWER_MODE1_CLOCK_MCLK_SELECT_336 1 +#define POWER_MODE1_CLOCK_MCLK_DIVIDER 11:11 +#define POWER_MODE1_CLOCK_MCLK_DIVIDER_1 0 +#define POWER_MODE1_CLOCK_MCLK_DIVIDER_3 1 +#define POWER_MODE1_CLOCK_MCLK_SHIFT 10:8 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_0 0 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_1 1 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_2 2 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_3 3 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_4 4 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_5 5 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_6 6 +#define POWER_MODE1_CLOCK_MCLK_SHIFT_7 7 +#define POWER_MODE1_CLOCK_M2XCLK_SELECT 4:4 +#define POWER_MODE1_CLOCK_M2XCLK_SELECT_288 0 +#define POWER_MODE1_CLOCK_M2XCLK_SELECT_336 1 +#define POWER_MODE1_CLOCK_M2XCLK_DIVIDER 3:3 +#define POWER_MODE1_CLOCK_M2XCLK_DIVIDER_1 0 +#define POWER_MODE1_CLOCK_M2XCLK_DIVIDER_3 1 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT 2:0 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_0 0 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_1 1 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_2 2 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_3 3 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_4 4 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_5 5 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_6 6 +#define POWER_MODE1_CLOCK_M2XCLK_SHIFT_7 7 + +#define POWER_SLEEP_GATE 0x000050 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK 22:19 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_4096 0 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_2048 1 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_1024 2 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_512 3 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_256 4 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_128 5 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_64 6 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_32 7 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_16 8 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_8 9 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_4 10 +#define POWER_SLEEP_GATE_PLL_RECOVERY_CLOCK_2 11 +#define POWER_SLEEP_GATE_PLL_RECOVERY 14:13 +#define POWER_SLEEP_GATE_PLL_RECOVERY_32 0 +#define POWER_SLEEP_GATE_PLL_RECOVERY_64 1 +#define POWER_SLEEP_GATE_PLL_RECOVERY_96 2 +#define POWER_SLEEP_GATE_PLL_RECOVERY_128 3 + +#define POWER_MODE_CTRL 0x000054 +#define POWER_MODE_CTRL_SLEEP_STATUS 2:2 +#define POWER_MODE_CTRL_SLEEP_STATUS_INACTIVE 0 +#define POWER_MODE_CTRL_SLEEP_STATUS_ACTIVE 1 +#define POWER_MODE_CTRL_MODE 1:0 +#define POWER_MODE_CTRL_MODE_MODE0 0 +#define POWER_MODE_CTRL_MODE_MODE1 1 +#define POWER_MODE_CTRL_MODE_SLEEP 2 + +#define PCI_MASTER_BASE 0x000058 +#define PCI_MASTER_BASE_ADDRESS 31:20 + +#define ENDIAN_CTRL 0x00005C +#define ENDIAN_CTRL_ENDIAN 0:0 +#define ENDIAN_CTRL_ENDIAN_LITTLE 0 +#define ENDIAN_CTRL_ENDIAN_BIG 1 + +#define DEVICE_ID 0x000060 +#define DEVICE_ID_DEVICE_ID 31:16 +#define DEVICE_ID_REVISION_ID 7:0 + +#define PLL_CLOCK_COUNT 0x000064 +#define PLL_CLOCK_COUNT_COUNTER 15:0 + +#define SYSTEM_DRAM_CTRL 0x000068 +#define SYSTEM_DRAM_CTRL_READ_DELAY 2:0 +#define SYSTEM_DRAM_CTRL_READ_DELAY_OFF 0 +#define SYSTEM_DRAM_CTRL_READ_DELAY_0_5NS 1 +#define SYSTEM_DRAM_CTRL_READ_DELAY_1NS 2 +#define SYSTEM_DRAM_CTRL_READ_DELAY_1_5NS 3 +#define SYSTEM_DRAM_CTRL_READ_DELAY_2NS 4 +#define SYSTEM_DRAM_CTRL_READ_DELAY_2_5NS 5 + +#define SYSTEM_PLL3_CLOCK 0x000074 +#define SYSTEM_PLL3_CLOCK_M 7:0 +#define SYSTEM_PLL3_CLOCK_N 14:8 +#define SYSTEM_PLL3_CLOCK_DIVIDE 15:15 +#define SYSTEM_PLL3_CLOCK_DIVIDE_1 0 +#define SYSTEM_PLL3_CLOCK_DIVIDE_2 1 +#define SYSTEM_PLL3_CLOCK_INPUT 16:16 +#define SYSTEM_PLL3_CLOCK_INPUT_CRYSTAL 0 +#define SYSTEM_PLL3_CLOCK_INPUT_TEST 1 +#define SYSTEM_PLL3_CLOCK_POWER 17:17 +#define SYSTEM_PLL3_CLOCK_POWER_OFF 0 +#define SYSTEM_PLL3_CLOCK_POWER_ON 1 + + +#define CURRENT_POWER_PLLCLOCK 0x000074 +#define CURRENT_POWER_PLLCLOCK_TEST_OUTPUT 20:20 +#define CURRENT_POWER_PLLCLOCK_TEST_OUTPUT_ENABLE 1 +#define CURRENT_POWER_PLLCLOCK_TEST_OUTPUT_DISABLE 0 +#define CURRENT_POWER_PLLCLOCK_TESTMODE 19:18 +#define CURRENT_POWER_PLLCLOCK_TESTMODE_ENABLE 1 +#define CURRENT_POWER_PLLCLOCK_TESTMODE_DISABLE 0 +#define CURRENT_POWER_PLLCLOCK_POWER 17:17 +#define CURRENT_POWER_PLLCLOCK_POWER_DOWN 0 +#define CURRENT_POWER_PLLCLOCK_POWER_ON 1 +#define CURRENT_POWER_PLLCLOCK_INPUT_SELECT 16:16 +#define CURRENT_POWER_PLLCLOCK_INPUT_SELECT_TEST 1 +#define CURRENT_POWER_PLLCLOCK_INPUT_SELECT_CRYSTAL 0 +#define CURRENT_POWER_PLLCLOCK_DIVIDEBY2 15:15 +#define CURRENT_POWER_PLLCLOCK_DIVIDE_N 14:8 +#define CURRENT_POWER_PLLCLOCK_MULTIPLE_M 7:0 + +// Panel Graphics Control + +#define PANEL_DISPLAY_CTRL 0x080000 +#define PANEL_DISPLAY_CTRL_FPEN 27:27 +#define PANEL_DISPLAY_CTRL_FPEN_LOW 0 +#define PANEL_DISPLAY_CTRL_FPEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_VBIASEN 26:26 +#define PANEL_DISPLAY_CTRL_VBIASEN_LOW 0 +#define PANEL_DISPLAY_CTRL_VBIASEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_DATA 25:25 +#define PANEL_DISPLAY_CTRL_DATA_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DATA_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FPVDDEN 24:24 +#define PANEL_DISPLAY_CTRL_FPVDDEN_LOW 0 +#define PANEL_DISPLAY_CTRL_FPVDDEN_HIGH 1 +#define PANEL_DISPLAY_CTRL_PATTERN 23:23 +#define PANEL_DISPLAY_CTRL_PATTERN_4 0 +#define PANEL_DISPLAY_CTRL_PATTERN_8 1 +#define PANEL_DISPLAY_CTRL_TFT 22:21 +#define PANEL_DISPLAY_CTRL_TFT_24 0 +#define PANEL_DISPLAY_CTRL_TFT_9 1 +#define PANEL_DISPLAY_CTRL_TFT_12 2 +#define PANEL_DISPLAY_CTRL_DITHER 20:20 +#define PANEL_DISPLAY_CTRL_DITHER_DISABLE 0 +#define PANEL_DISPLAY_CTRL_DITHER_ENABLE 1 +#define PANEL_DISPLAY_CTRL_LCD 19:18 +#define PANEL_DISPLAY_CTRL_LCD_TFT 0 +#define PANEL_DISPLAY_CTRL_LCD_STN_8 2 +#define PANEL_DISPLAY_CTRL_LCD_STN_12 3 +#define PANEL_DISPLAY_CTRL_FIFO 17:16 +#define PANEL_DISPLAY_CTRL_FIFO_1 0 +#define PANEL_DISPLAY_CTRL_FIFO_3 1 +#define PANEL_DISPLAY_CTRL_FIFO_7 2 +#define PANEL_DISPLAY_CTRL_FIFO_11 3 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE 14:14 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE 13:13 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE 12:12 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH 0 +#define PANEL_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW 1 +#define PANEL_DISPLAY_CTRL_COLOR_KEY 9:9 +#define PANEL_DISPLAY_CTRL_COLOR_KEY_DISABLE 0 +#define PANEL_DISPLAY_CTRL_COLOR_KEY_ENABLE 1 +#define PANEL_DISPLAY_CTRL_TIMING 8:8 +#define PANEL_DISPLAY_CTRL_TIMING_DISABLE 0 +#define PANEL_DISPLAY_CTRL_TIMING_ENABLE 1 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR 7:7 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR_DOWN 0 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DIR_UP 1 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN 6:6 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_DISABLE 0 +#define PANEL_DISPLAY_CTRL_VERTICAL_PAN_ENABLE 1 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR 5:5 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR_RIGHT 0 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DIR_LEFT 1 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN 4:4 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_DISABLE 0 +#define PANEL_DISPLAY_CTRL_HORIZONTAL_PAN_ENABLE 1 +#define PANEL_DISPLAY_CTRL_GAMMA 3:3 +#define PANEL_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define PANEL_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define PANEL_DISPLAY_CTRL_PLANE 2:2 +#define PANEL_DISPLAY_CTRL_PLANE_DISABLE 0 +#define PANEL_DISPLAY_CTRL_PLANE_ENABLE 1 +#define PANEL_DISPLAY_CTRL_FORMAT 1:0 +#define PANEL_DISPLAY_CTRL_FORMAT_8 0 +#define PANEL_DISPLAY_CTRL_FORMAT_16 1 +#define PANEL_DISPLAY_CTRL_FORMAT_32 2 + +#define PANEL_PAN_CTRL 0x080004 +#define PANEL_PAN_CTRL_VERTICAL_PAN 31:24 +#define PANEL_PAN_CTRL_VERTICAL_VSYNC 21:16 +#define PANEL_PAN_CTRL_HORIZONTAL_PAN 15:8 +#define PANEL_PAN_CTRL_HORIZONTAL_VSYNC 5:0 + +#define PANEL_COLOR_KEY 0x080008 +#define PANEL_COLOR_KEY_MASK 31:16 +#define PANEL_COLOR_KEY_VALUE 15:0 + +#define PANEL_FB_ADDRESS 0x08000C +#define PANEL_FB_ADDRESS_STATUS 31:31 +#define PANEL_FB_ADDRESS_STATUS_CURRENT 0 +#define PANEL_FB_ADDRESS_STATUS_PENDING 1 +#define PANEL_FB_ADDRESS_EXT 27:27 +#define PANEL_FB_ADDRESS_EXT_LOCAL 0 +#define PANEL_FB_ADDRESS_EXT_EXTERNAL 1 +#define PANEL_FB_ADDRESS_CS 26:26 +#define PANEL_FB_ADDRESS_CS_0 0 +#define PANEL_FB_ADDRESS_CS_1 1 +#define PANEL_FB_ADDRESS_ADDRESS 25:0 + +#define PANEL_FB_WIDTH 0x080010 +#define PANEL_FB_WIDTH_WIDTH 29:16 +#define PANEL_FB_WIDTH_OFFSET 13:0 + +#define PANEL_WINDOW_WIDTH 0x080014 +#define PANEL_WINDOW_WIDTH_WIDTH 27:16 +#define PANEL_WINDOW_WIDTH_X 11:0 + +#define PANEL_WINDOW_HEIGHT 0x080018 +#define PANEL_WINDOW_HEIGHT_HEIGHT 27:16 +#define PANEL_WINDOW_HEIGHT_Y 11:0 + +#define PANEL_PLANE_TL 0x08001C +#define PANEL_PLANE_TL_TOP 26:16 +#define PANEL_PLANE_TL_LEFT 10:0 + +#define PANEL_PLANE_BR 0x080020 +#define PANEL_PLANE_BR_BOTTOM 26:16 +#define PANEL_PLANE_BR_RIGHT 10:0 + +#define PANEL_HORIZONTAL_TOTAL 0x080024 +#define PANEL_HORIZONTAL_TOTAL_TOTAL 27:16 +#define PANEL_HORIZONTAL_TOTAL_DISPLAY_END 11:0 + +#define PANEL_HORIZONTAL_SYNC 0x080028 +#define PANEL_HORIZONTAL_SYNC_WIDTH 23:16 +#define PANEL_HORIZONTAL_SYNC_START 11:0 + +#define PANEL_VERTICAL_TOTAL 0x08002C +#define PANEL_VERTICAL_TOTAL_TOTAL 26:16 +#define PANEL_VERTICAL_TOTAL_DISPLAY_END 10:0 + +#define PANEL_VERTICAL_SYNC 0x080030 +#define PANEL_VERTICAL_SYNC_HEIGHT 21:16 +#define PANEL_VERTICAL_SYNC_START 10:0 + +#define PANEL_CURRENT_LINE 0x080034 +#define PANEL_CURRENT_LINE_LINE 10:0 + +// Video Control + +#define VIDEO_DISPLAY_CTRL 0x080040 +#define VIDEO_DISPLAY_CTRL_FIFO 17:16 +#define VIDEO_DISPLAY_CTRL_FIFO_1 0 +#define VIDEO_DISPLAY_CTRL_FIFO_3 1 +#define VIDEO_DISPLAY_CTRL_FIFO_7 2 +#define VIDEO_DISPLAY_CTRL_FIFO_11 3 +#define VIDEO_DISPLAY_CTRL_BUFFER 15:15 +#define VIDEO_DISPLAY_CTRL_BUFFER_0 0 +#define VIDEO_DISPLAY_CTRL_BUFFER_1 1 +#define VIDEO_DISPLAY_CTRL_CAPTURE 14:14 +#define VIDEO_DISPLAY_CTRL_CAPTURE_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_CAPTURE_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER 13:13 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_DOUBLE_BUFFER_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP 12:12 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_BYTE_SWAP_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE 11:11 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE_NORMAL 0 +#define VIDEO_DISPLAY_CTRL_VERTICAL_SCALE_HALF 1 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE 10:10 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE_NORMAL 0 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_SCALE_HALF 1 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE 9:9 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE_REPLICATE 0 +#define VIDEO_DISPLAY_CTRL_VERTICAL_MODE_INTERPOLATE 1 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE 8:8 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE_REPLICATE 0 +#define VIDEO_DISPLAY_CTRL_HORIZONTAL_MODE_INTERPOLATE 1 +#define VIDEO_DISPLAY_CTRL_PIXEL 7:4 +#define VIDEO_DISPLAY_CTRL_GAMMA 3:3 +#define VIDEO_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_PLANE 2:2 +#define VIDEO_DISPLAY_CTRL_PLANE_DISABLE 0 +#define VIDEO_DISPLAY_CTRL_PLANE_ENABLE 1 +#define VIDEO_DISPLAY_CTRL_FORMAT 1:0 +#define VIDEO_DISPLAY_CTRL_FORMAT_8 0 +#define VIDEO_DISPLAY_CTRL_FORMAT_16 1 +#define VIDEO_DISPLAY_CTRL_FORMAT_32 2 +#define VIDEO_DISPLAY_CTRL_FORMAT_YUV 3 + +#define VIDEO_FB_0_ADDRESS 0x080044 +#define VIDEO_FB_0_ADDRESS_STATUS 31:31 +#define VIDEO_FB_0_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_FB_0_ADDRESS_STATUS_PENDING 1 +#define VIDEO_FB_0_ADDRESS_EXT 27:27 +#define VIDEO_FB_0_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_0_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_0_ADDRESS_CS 26:26 +#define VIDEO_FB_0_ADDRESS_CS_0 0 +#define VIDEO_FB_0_ADDRESS_CS_1 1 +#define VIDEO_FB_0_ADDRESS_ADDRESS 25:0 + +#define VIDEO_FB_WIDTH 0x080048 +#define VIDEO_FB_WIDTH_WIDTH 29:16 +#define VIDEO_FB_WIDTH_OFFSET 13:0 + +#define VIDEO_FB_0_LAST_ADDRESS 0x08004C +#define VIDEO_FB_0_LAST_ADDRESS_EXT 27:27 +#define VIDEO_FB_0_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_0_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_0_LAST_ADDRESS_CS 26:26 +#define VIDEO_FB_0_LAST_ADDRESS_CS_0 0 +#define VIDEO_FB_0_LAST_ADDRESS_CS_1 1 +#define VIDEO_FB_0_LAST_ADDRESS_ADDRESS 25:0 + +#define VIDEO_PLANE_TL 0x080050 +#define VIDEO_PLANE_TL_TOP 26:16 +#define VIDEO_PLANE_TL_LEFT 13:0 + +#define VIDEO_PLANE_BR 0x080054 +#define VIDEO_PLANE_BR_BOTTOM 26:16 +#define VIDEO_PLANE_BR_RIGHT 13:0 + +#define VIDEO_SCALE 0x080058 +#define VIDEO_SCALE_VERTICAL_MODE 31:31 +#define VIDEO_SCALE_VERTICAL_MODE_EXPAND 0 +#define VIDEO_SCALE_VERTICAL_MODE_SHRINK 1 +#define VIDEO_SCALE_VERTICAL_SCALE 27:16 +#define VIDEO_SCALE_HORIZONTAL_MODE 15:15 +#define VIDEO_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define VIDEO_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define VIDEO_SCALE_HORIZONTAL_SCALE 11:0 + +#define VIDEO_INITIAL_SCALE 0x08005C +#define VIDEO_INITIAL_SCALE_FB_1 27:16 +#define VIDEO_INITIAL_SCALE_FB_0 11:0 + +#define VIDEO_YUV_CONSTANTS 0x080060 +#define VIDEO_YUV_CONSTANTS_Y 31:24 +#define VIDEO_YUV_CONSTANTS_R 23:16 +#define VIDEO_YUV_CONSTANTS_G 15:8 +#define VIDEO_YUV_CONSTANTS_B 7:0 + +#define VIDEO_FB_1_ADDRESS 0x080064 +#define VIDEO_FB_1_ADDRESS_STATUS 31:31 +#define VIDEO_FB_1_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_FB_1_ADDRESS_STATUS_PENDING 1 +#define VIDEO_FB_1_ADDRESS_EXT 27:27 +#define VIDEO_FB_1_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_1_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_1_ADDRESS_CS 26:26 +#define VIDEO_FB_1_ADDRESS_CS_0 0 +#define VIDEO_FB_1_ADDRESS_CS_1 1 +#define VIDEO_FB_1_ADDRESS_ADDRESS 25:0 + +#define VIDEO_FB_1_LAST_ADDRESS 0x080068 +#define VIDEO_FB_1_LAST_ADDRESS_EXT 27:27 +#define VIDEO_FB_1_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_FB_1_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_FB_1_LAST_ADDRESS_CS 26:26 +#define VIDEO_FB_1_LAST_ADDRESS_CS_0 0 +#define VIDEO_FB_1_LAST_ADDRESS_CS_1 1 +#define VIDEO_FB_1_LAST_ADDRESS_ADDRESS 25:0 + +// Video Alpha Control + +#define VIDEO_ALPHA_DISPLAY_CTRL 0x080080 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT 28:28 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT_PER_PIXEL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_SELECT_ALPHA 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_ALPHA 27:24 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO 17:16 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_1 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_3 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_7 2 +#define VIDEO_ALPHA_DISPLAY_CTRL_FIFO_11 3 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE 11:11 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE_NORMAL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_SCALE_HALF 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE 10:10 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE_NORMAL 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_SCALE_HALF 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE 9:9 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE_REPLICATE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_VERT_MODE_INTERPOLATE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE 8:8 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE_REPLICATE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_HORZ_MODE_INTERPOLATE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_PIXEL 7:4 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY 3:3 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY_DISABLE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_CHROMA_KEY_ENABLE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE 2:2 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_DISABLE 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_PLANE_ENABLE 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT 1:0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_8 0 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_16 1 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4 2 +#define VIDEO_ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4_4_4 3 + +#define VIDEO_ALPHA_FB_ADDRESS 0x080084 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS 31:31 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS_CURRENT 0 +#define VIDEO_ALPHA_FB_ADDRESS_STATUS_PENDING 1 +#define VIDEO_ALPHA_FB_ADDRESS_EXT 27:27 +#define VIDEO_ALPHA_FB_ADDRESS_EXT_LOCAL 0 +#define VIDEO_ALPHA_FB_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_ALPHA_FB_ADDRESS_CS 26:26 +#define VIDEO_ALPHA_FB_ADDRESS_CS_0 0 +#define VIDEO_ALPHA_FB_ADDRESS_CS_1 1 +#define VIDEO_ALPHA_FB_ADDRESS_ADDRESS 25:0 + +#define VIDEO_ALPHA_FB_WIDTH 0x080088 +#define VIDEO_ALPHA_FB_WIDTH_WIDTH 29:16 +#define VIDEO_ALPHA_FB_WIDTH_OFFSET 13:0 + +#define VIDEO_ALPHA_FB_LAST_ADDRESS 0x08008C +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT 27:27 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT_LOCAL 0 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_EXT_EXTERNAL 1 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_CS 26:26 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_CS_0 0 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_CS_1 1 +#define VIDEO_ALPHA_FB_LAST_ADDRESS_ADDRESS 25:0 + +#define VIDEO_ALPHA_PLANE_TL 0x080090 +#define VIDEO_ALPHA_PLANE_TL_TOP 26:16 +#define VIDEO_ALPHA_PLANE_TL_LEFT 10:0 + +#define VIDEO_ALPHA_PLANE_BR 0x080094 +#define VIDEO_ALPHA_PLANE_BR_BOTTOM 26:16 +#define VIDEO_ALPHA_PLANE_BR_RIGHT 10:0 + +#define VIDEO_ALPHA_SCALE 0x080098 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE 31:31 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE_EXPAND 0 +#define VIDEO_ALPHA_SCALE_VERTICAL_MODE_SHRINK 1 +#define VIDEO_ALPHA_SCALE_VERTICAL_SCALE 27:16 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE 15:15 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE_EXPAND 0 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_MODE_SHRINK 1 +#define VIDEO_ALPHA_SCALE_HORIZONTAL_SCALE 11:0 + +#define VIDEO_ALPHA_INITIAL_SCALE 0x08009C +#define VIDEO_ALPHA_INITIAL_SCALE_FB 11:0 + +#define VIDEO_ALPHA_CHROMA_KEY 0x0800A0 +#define VIDEO_ALPHA_CHROMA_KEY_MASK 31:16 +#define VIDEO_ALPHA_CHROMA_KEY_VALUE 15:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_01 0x0800A4 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_1_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_01_0_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_23 0x0800A8 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_3_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_23_2_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_45 0x0800AC +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_5_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_45_4_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_67 0x0800B0 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_7_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_67_6_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_89 0x0800B4 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_9_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_89_8_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_AB 0x0800B8 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_B_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_AB_A_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_CD 0x0800BC +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_D_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_CD_C_BLUE 4:0 + +#define VIDEO_ALPHA_COLOR_LOOKUP_EF 0x0800C0 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_RED 31:27 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_GREEN 26:21 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_F_BLUE 20:16 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_RED 15:11 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_GREEN 10:5 +#define VIDEO_ALPHA_COLOR_LOOKUP_EF_E_BLUE 4:0 + +// Panel Cursor Control + +#define PANEL_HWC_ADDRESS 0x0800F0 +#define PANEL_HWC_ADDRESS_ENABLE 31:31 +#define PANEL_HWC_ADDRESS_ENABLE_DISABLE 0 +#define PANEL_HWC_ADDRESS_ENABLE_ENABLE 1 +#define PANEL_HWC_ADDRESS_EXT 27:27 +#define PANEL_HWC_ADDRESS_EXT_LOCAL 0 +#define PANEL_HWC_ADDRESS_EXT_EXTERNAL 1 +#define PANEL_HWC_ADDRESS_CS 26:26 +#define PANEL_HWC_ADDRESS_CS_0 0 +#define PANEL_HWC_ADDRESS_CS_1 1 +#define PANEL_HWC_ADDRESS_ADDRESS 25:0 + +#define PANEL_HWC_LOCATION 0x0800F4 +#define PANEL_HWC_LOCATION_TOP 27:27 +#define PANEL_HWC_LOCATION_TOP_INSIDE 0 +#define PANEL_HWC_LOCATION_TOP_OUTSIDE 1 +#define PANEL_HWC_LOCATION_Y 26:16 +#define PANEL_HWC_LOCATION_LEFT 11:11 +#define PANEL_HWC_LOCATION_LEFT_INSIDE 0 +#define PANEL_HWC_LOCATION_LEFT_OUTSIDE 1 +#define PANEL_HWC_LOCATION_X 10:0 + +#define PANEL_HWC_COLOR_12 0x0800F8 +#define PANEL_HWC_COLOR_12_2_RGB565 31:16 +#define PANEL_HWC_COLOR_12_1_RGB565 15:0 + +#define PANEL_HWC_COLOR_3 0x0800FC +#define PANEL_HWC_COLOR_3_RGB565 15:0 + +// Old Definitions +++ +#define PANEL_HWC_COLOR_01 0x0800F8 +#define PANEL_HWC_COLOR_01_1_RED 31:27 +#define PANEL_HWC_COLOR_01_1_GREEN 26:21 +#define PANEL_HWC_COLOR_01_1_BLUE 20:16 +#define PANEL_HWC_COLOR_01_0_RED 15:11 +#define PANEL_HWC_COLOR_01_0_GREEN 10:5 +#define PANEL_HWC_COLOR_01_0_BLUE 4:0 + +#define PANEL_HWC_COLOR_2 0x0800FC +#define PANEL_HWC_COLOR_2_RED 15:11 +#define PANEL_HWC_COLOR_2_GREEN 10:5 +#define PANEL_HWC_COLOR_2_BLUE 4:0 +// Old Definitions --- + +// Alpha Control + +#define ALPHA_DISPLAY_CTRL 0x080100 +#define ALPHA_DISPLAY_CTRL_SELECT 28:28 +#define ALPHA_DISPLAY_CTRL_SELECT_PER_PIXEL 0 +#define ALPHA_DISPLAY_CTRL_SELECT_ALPHA 1 +#define ALPHA_DISPLAY_CTRL_ALPHA 27:24 +#define ALPHA_DISPLAY_CTRL_FIFO 17:16 +#define ALPHA_DISPLAY_CTRL_FIFO_1 0 +#define ALPHA_DISPLAY_CTRL_FIFO_3 1 +#define ALPHA_DISPLAY_CTRL_FIFO_7 2 +#define ALPHA_DISPLAY_CTRL_FIFO_11 3 +#define ALPHA_DISPLAY_CTRL_PIXEL 7:4 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY 3:3 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY_DISABLE 0 +#define ALPHA_DISPLAY_CTRL_CHROMA_KEY_ENABLE 1 +#define ALPHA_DISPLAY_CTRL_PLANE 2:2 +#define ALPHA_DISPLAY_CTRL_PLANE_DISABLE 0 +#define ALPHA_DISPLAY_CTRL_PLANE_ENABLE 1 +#define ALPHA_DISPLAY_CTRL_FORMAT 1:0 +#define ALPHA_DISPLAY_CTRL_FORMAT_16 1 +#define ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4 2 +#define ALPHA_DISPLAY_CTRL_FORMAT_ALPHA_4_4_4_4 3 + +#define ALPHA_FB_ADDRESS 0x080104 +#define ALPHA_FB_ADDRESS_STATUS 31:31 +#define ALPHA_FB_ADDRESS_STATUS_CURRENT 0 +#define ALPHA_FB_ADDRESS_STATUS_PENDING 1 +#define ALPHA_FB_ADDRESS_EXT 27:27 +#define ALPHA_FB_ADDRESS_EXT_LOCAL 0 +#define ALPHA_FB_ADDRESS_EXT_EXTERNAL 1 +#define ALPHA_FB_ADDRESS_CS 26:26 +#define ALPHA_FB_ADDRESS_CS_0 0 +#define ALPHA_FB_ADDRESS_CS_1 1 +#define ALPHA_FB_ADDRESS_ADDRESS 25:0 + +#define ALPHA_FB_WIDTH 0x080108 +#define ALPHA_FB_WIDTH_WIDTH 29:16 +#define ALPHA_FB_WIDTH_OFFSET 13:0 + +#define ALPHA_PLANE_TL 0x08010C +#define ALPHA_PLANE_TL_TOP 26:16 +#define ALPHA_PLANE_TL_LEFT 10:0 + +#define ALPHA_PLANE_BR 0x080110 +#define ALPHA_PLANE_BR_BOTTOM 26:16 +#define ALPHA_PLANE_BR_RIGHT 10:0 + +#define ALPHA_CHROMA_KEY 0x080114 +#define ALPHA_CHROMA_KEY_MASK 31:16 +#define ALPHA_CHROMA_KEY_VALUE 15:0 + +#define ALPHA_COLOR_LOOKUP_01 0x080118 +#define ALPHA_COLOR_LOOKUP_01_1_RED 31:27 +#define ALPHA_COLOR_LOOKUP_01_1_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_01_1_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_01_0_RED 15:11 +#define ALPHA_COLOR_LOOKUP_01_0_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_01_0_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_23 0x08011C +#define ALPHA_COLOR_LOOKUP_23_3_RED 31:27 +#define ALPHA_COLOR_LOOKUP_23_3_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_23_3_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_23_2_RED 15:11 +#define ALPHA_COLOR_LOOKUP_23_2_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_23_2_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_45 0x080120 +#define ALPHA_COLOR_LOOKUP_45_5_RED 31:27 +#define ALPHA_COLOR_LOOKUP_45_5_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_45_5_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_45_4_RED 15:11 +#define ALPHA_COLOR_LOOKUP_45_4_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_45_4_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_67 0x080124 +#define ALPHA_COLOR_LOOKUP_67_7_RED 31:27 +#define ALPHA_COLOR_LOOKUP_67_7_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_67_7_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_67_6_RED 15:11 +#define ALPHA_COLOR_LOOKUP_67_6_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_67_6_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_89 0x080128 +#define ALPHA_COLOR_LOOKUP_89_9_RED 31:27 +#define ALPHA_COLOR_LOOKUP_89_9_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_89_9_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_89_8_RED 15:11 +#define ALPHA_COLOR_LOOKUP_89_8_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_89_8_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_AB 0x08012C +#define ALPHA_COLOR_LOOKUP_AB_B_RED 31:27 +#define ALPHA_COLOR_LOOKUP_AB_B_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_AB_B_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_AB_A_RED 15:11 +#define ALPHA_COLOR_LOOKUP_AB_A_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_AB_A_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_CD 0x080130 +#define ALPHA_COLOR_LOOKUP_CD_D_RED 31:27 +#define ALPHA_COLOR_LOOKUP_CD_D_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_CD_D_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_CD_C_RED 15:11 +#define ALPHA_COLOR_LOOKUP_CD_C_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_CD_C_BLUE 4:0 + +#define ALPHA_COLOR_LOOKUP_EF 0x080134 +#define ALPHA_COLOR_LOOKUP_EF_F_RED 31:27 +#define ALPHA_COLOR_LOOKUP_EF_F_GREEN 26:21 +#define ALPHA_COLOR_LOOKUP_EF_F_BLUE 20:16 +#define ALPHA_COLOR_LOOKUP_EF_E_RED 15:11 +#define ALPHA_COLOR_LOOKUP_EF_E_GREEN 10:5 +#define ALPHA_COLOR_LOOKUP_EF_E_BLUE 4:0 + +// CRT Graphics Control + +#define CRT_DISPLAY_CTRL 0x080200 +#define CRT_DISPLAY_CTRL_FIFO 17:16 +#define CRT_DISPLAY_CTRL_FIFO_1 0 +#define CRT_DISPLAY_CTRL_FIFO_3 1 +#define CRT_DISPLAY_CTRL_FIFO_7 2 +#define CRT_DISPLAY_CTRL_FIFO_11 3 +#define CRT_DISPLAY_CTRL_TV_PHASE 15:15 +#define CRT_DISPLAY_CTRL_TV_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_TV_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE 14:14 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_CLOCK_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE 13:13 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_VSYNC_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE 12:12 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_HIGH 0 +#define CRT_DISPLAY_CTRL_HSYNC_PHASE_ACTIVE_LOW 1 +#define CRT_DISPLAY_CTRL_BLANK 10:10 +#define CRT_DISPLAY_CTRL_BLANK_OFF 0 +#define CRT_DISPLAY_CTRL_BLANK_ON 1 +#define CRT_DISPLAY_CTRL_SELECT 9:9 +#define CRT_DISPLAY_CTRL_SELECT_PANEL 0 +#define CRT_DISPLAY_CTRL_SELECT_CRT 1 +#define CRT_DISPLAY_CTRL_TIMING 8:8 +#define CRT_DISPLAY_CTRL_TIMING_DISABLE 0 +#define CRT_DISPLAY_CTRL_TIMING_ENABLE 1 +#define CRT_DISPLAY_CTRL_PIXEL 7:4 +#define CRT_DISPLAY_CTRL_GAMMA 3:3 +#define CRT_DISPLAY_CTRL_GAMMA_DISABLE 0 +#define CRT_DISPLAY_CTRL_GAMMA_ENABLE 1 +#define CRT_DISPLAY_CTRL_PLANE 2:2 +#define CRT_DISPLAY_CTRL_PLANE_DISABLE 0 +#define CRT_DISPLAY_CTRL_PLANE_ENABLE 1 +#define CRT_DISPLAY_CTRL_FORMAT 1:0 +#define CRT_DISPLAY_CTRL_FORMAT_8 0 +#define CRT_DISPLAY_CTRL_FORMAT_16 1 +#define CRT_DISPLAY_CTRL_FORMAT_32 2 + +#define CRT_FB_ADDRESS 0x080204 +#define CRT_FB_ADDRESS_STATUS 31:31 +#define CRT_FB_ADDRESS_STATUS_CURRENT 0 +#define CRT_FB_ADDRESS_STATUS_PENDING 1 +#define CRT_FB_ADDRESS_EXT 27:27 +#define CRT_FB_ADDRESS_EXT_LOCAL 0 +#define CRT_FB_ADDRESS_EXT_EXTERNAL 1 +#define CRT_FB_ADDRESS_CS 26:26 +#define CRT_FB_ADDRESS_CS_0 0 +#define CRT_FB_ADDRESS_CS_1 1 +#define CRT_FB_ADDRESS_ADDRESS 25:0 + +#define CRT_FB_WIDTH 0x080208 +#define CRT_FB_WIDTH_WIDTH 29:16 +#define CRT_FB_WIDTH_OFFSET 13:0 + +#define CRT_HORIZONTAL_TOTAL 0x08020C +#define CRT_HORIZONTAL_TOTAL_TOTAL 27:16 +#define CRT_HORIZONTAL_TOTAL_DISPLAY_END 11:0 + +#define CRT_HORIZONTAL_SYNC 0x080210 +#define CRT_HORIZONTAL_SYNC_WIDTH 23:16 +#define CRT_HORIZONTAL_SYNC_START 11:0 + +#define CRT_VERTICAL_TOTAL 0x080214 +#define CRT_VERTICAL_TOTAL_TOTAL 26:16 +#define CRT_VERTICAL_TOTAL_DISPLAY_END 10:0 + +#define CRT_VERTICAL_SYNC 0x080218 +#define CRT_VERTICAL_SYNC_HEIGHT 21:16 +#define CRT_VERTICAL_SYNC_START 10:0 + +#define CRT_SIGNATURE_ANALYZER 0x08021C +#define CRT_SIGNATURE_ANALYZER_STATUS 31:16 +#define CRT_SIGNATURE_ANALYZER_ENABLE 3:3 +#define CRT_SIGNATURE_ANALYZER_ENABLE_DISABLE 0 +#define CRT_SIGNATURE_ANALYZER_ENABLE_ENABLE 1 +#define CRT_SIGNATURE_ANALYZER_RESET 2:2 +#define CRT_SIGNATURE_ANALYZER_RESET_NORMAL 0 +#define CRT_SIGNATURE_ANALYZER_RESET_RESET 1 +#define CRT_SIGNATURE_ANALYZER_SOURCE 1:0 +#define CRT_SIGNATURE_ANALYZER_SOURCE_RED 0 +#define CRT_SIGNATURE_ANALYZER_SOURCE_GREEN 1 +#define CRT_SIGNATURE_ANALYZER_SOURCE_BLUE 2 + +#define CRT_CURRENT_LINE 0x080220 +#define CRT_CURRENT_LINE_LINE 10:0 + +#define CRT_MONITOR_DETECT 0x080224 +#define CRT_MONITOR_DETECT_ENABLE 24:24 +#define CRT_MONITOR_DETECT_ENABLE_DISABLE 0 +#define CRT_MONITOR_DETECT_ENABLE_ENABLE 1 +#define CRT_MONITOR_DETECT_RED 23:16 +#define CRT_MONITOR_DETECT_GREEN 15:8 +#define CRT_MONITOR_DETECT_BLUE 7:0 + +// CRT Cursor Control + +#define CRT_HWC_ADDRESS 0x080230 +#define CRT_HWC_ADDRESS_ENABLE 31:31 +#define CRT_HWC_ADDRESS_ENABLE_DISABLE 0 +#define CRT_HWC_ADDRESS_ENABLE_ENABLE 1 +#define CRT_HWC_ADDRESS_EXT 27:27 +#define CRT_HWC_ADDRESS_EXT_LOCAL 0 +#define CRT_HWC_ADDRESS_EXT_EXTERNAL 1 +#define CRT_HWC_ADDRESS_CS 26:26 +#define CRT_HWC_ADDRESS_CS_0 0 +#define CRT_HWC_ADDRESS_CS_1 1 +#define CRT_HWC_ADDRESS_ADDRESS 25:0 + +#define CRT_HWC_LOCATION 0x080234 +#define CRT_HWC_LOCATION_TOP 27:27 +#define CRT_HWC_LOCATION_TOP_INSIDE 0 +#define CRT_HWC_LOCATION_TOP_OUTSIDE 1 +#define CRT_HWC_LOCATION_Y 26:16 +#define CRT_HWC_LOCATION_LEFT 11:11 +#define CRT_HWC_LOCATION_LEFT_INSIDE 0 +#define CRT_HWC_LOCATION_LEFT_OUTSIDE 1 +#define CRT_HWC_LOCATION_X 10:0 + +#define CRT_HWC_COLOR_12 0x080238 +#define CRT_HWC_COLOR_12_2_RGB565 31:16 +#define CRT_HWC_COLOR_12_1_RGB565 15:0 + +#define CRT_HWC_COLOR_3 0x08023C +#define CRT_HWC_COLOR_3_RGB565 15:0 + +// Old Definitions +++ +#define CRT_HWC_COLOR_01 0x080238 +#define CRT_HWC_COLOR_01_1_RED 31:27 +#define CRT_HWC_COLOR_01_1_GREEN 26:21 +#define CRT_HWC_COLOR_01_1_BLUE 20:16 +#define CRT_HWC_COLOR_01_0_RED 15:11 +#define CRT_HWC_COLOR_01_0_GREEN 10:5 +#define CRT_HWC_COLOR_01_0_BLUE 4:0 + +#define CRT_HWC_COLOR_2 0x08023C +#define CRT_HWC_COLOR_2_RED 15:11 +#define CRT_HWC_COLOR_2_GREEN 10:5 +#define CRT_HWC_COLOR_2_BLUE 4:0 +// Old Definitions --- + +// Palette RAM + +#define PANEL_PALETTE_RAM 0x080400 +#define VIDEO_PALETTE_RAM 0x080800 +#define CRT_PALETTE_RAM 0x080C00 + +// Power constants to use with setDPMS function. +typedef enum _DPMS_t +{ + DPMS_ON, + DPMS_STANDBY, + DPMS_SUSPEND, + DPMS_OFF +} +DPMS_t; + +//////////////////////////////////////////////////////////////////////////////// +// // +// D I S P L A Y C O N T R O L L E R // +// // +//////////////////////////////////////////////////////////////////////////////// + +// Display type constants to use with setMode function and others. +typedef enum _display_t +{ + PANEL = 0, + CRT = 1, +} +display_t; + +// Type of LCD display +typedef enum _lcd_display_t +{ + LCD_TFT = 0, + LCD_STN_8 = 2, + LCD_STN_12 = 3 +} +lcd_display_t; + +// Polarity constants. +typedef enum _polarity_t +{ + POSITIVE, + NEGATIVE, +} +polarity_t; + + +// Format of mode table record. +typedef struct _mode_table_t +{ + // Horizontal timing. + int horizontal_total; + int horizontal_display_end; + int horizontal_sync_start; + int horizontal_sync_width; + polarity_t horizontal_sync_polarity; + + // Vertical timing. + int vertical_total; + int vertical_display_end; + int vertical_sync_start; + int vertical_sync_height; + polarity_t vertical_sync_polarity; + + // Refresh timing. + long pixel_clock; + long horizontal_frequency; + long vertical_frequency; +/* + //Programe PLL3 + int M; + int N; + int bit15; + int bit31; +*/ +} +mode_table_t, *pmode_table_t; + +// Clock value structure. +typedef struct clock_select_t +{ + long mclk; + long test_clock; + int divider; + int shift; + + long multipleM; + int dividerN; + short divby2; +} +clock_select_t, *pclock_select_t; + +// Registers necessary to set mode. +typedef struct _reg_table_t +{ + unsigned long clock; + unsigned long control; + unsigned long fb_width; + unsigned long horizontal_total; + unsigned long horizontal_sync; + unsigned long vertical_total; + unsigned long vertical_sync; + unsigned long width; + unsigned long height; + display_t display; +} +reg_table_t, *preg_table_t; + +// Panel On/Off constants to use with panelPowerSequence. +typedef enum _panel_state_t +{ + PANEL_OFF, + PANEL_ON, +} +panel_state_t; + +// Structure used to initialize Panel hardware module +typedef struct +{ + unsigned long mask; // Holds flags indicating which register bitfields to init + unsigned long dp; // TFT dithering pattern + unsigned long tft; // TFT panel interface + unsigned long de; // Enable/disable TFT dithering + unsigned long lcd; // LCD type + unsigned long fifo_level; // FIFO request level + unsigned long cp; // Clock phase select + unsigned long format; // Panel graphics plane format +} init_panel, *pinit_panel; + +// Structure used to initialize Panel cursor hardware module +typedef struct +{ + unsigned long mask; // Holds flags indicating which register bitfields to init +} init_panel_hwc, *pinit_panel_hwc; + +// Structure used to initialize Alpha hardware module +typedef struct +{ + unsigned long mask; // Holds flags indicating which register bitfields to init + unsigned long fifo_level; // FIFO request level + unsigned long format; // Alpha plane format +} init_alpha, *pinit_alpha; + +// Structure used to initialize CRT hardware module +typedef struct +{ + unsigned long mask; // Holds flags indicating which register bitfields to init + unsigned long fifo_level; // FIFO request level + unsigned long tvp; // TV clock phase select + unsigned long cp; // CRT clock phase select + unsigned long blank; // CRT data blanking + unsigned long format; // CRT graphics plane format +} init_crt, *pinit_crt; + +// Structure used to initialize CRT cursor hardware module +typedef struct +{ + unsigned long mask; // Holds flags indicating which register bitfields to init +} init_crt_hwc, *pinit_crt_hwc; + +// Init flags and values used in init_panel, init_alpha, and init_crt structures +#define DISP_FIFO_LEVEL 0x00000001 // FIFO request level +#define DISP_FIFO_LEVEL_1 0x00000000 +#define DISP_FIFO_LEVEL_3 0x00010000 +#define DISP_FIFO_LEVEL_7 0x00020000 +#define DISP_FIFO_LEVEL_11 0x00030000 + +// Init flags and values used in init_panel structure +#define DISP_PANEL_DP 0x00000100 // TFT dithering pattern +#define DISP_PANEL_DP_4GRAY 0x00000000 +#define DISP_PANEL_DP_8GRAY 0x00800000 + +#define DISP_PANEL_TFT 0x00000200 // TFT panel interface +#define DISP_PANEL_TFT_24 0x00000000 +#define DISP_PANEL_TFT_9 0x00200000 +#define DISP_PANEL_TFT_12 0x00400000 + +#define DISP_PANEL_DE 0x00000400 // Enable/disable TFT dithering +#define DISP_PANEL_DE_DISABLE 0x00000000 +#define DISP_PANEL_DE_ENABLE 0x00100000 + +#define DISP_PANEL_LCD 0x00000800 // LCD type +#define DISP_PANEL_LCD_TFT 0x00000000 +#define DISP_PANEL_LCD_STN8 0x00080000 +#define DISP_PANEL_LCD_STN12 0x000C0000 + +#define DISP_PANEL_CP 0x00001000 // Clock phase select +#define DISP_PANEL_CP_HIGH 0x00000000 +#define DISP_PANEL_CP_LOW 0x00004000 + +#define DISP_PANEL_FORMAT 0x00002000 // Panel graphics plane format +#define DISP_PANEL_FORMAT_8 0x00000000 +#define DISP_PANEL_FORMAT_16 0x00000001 +#define DISP_PANEL_FORMAT_32 0x00000002 + +// Init flags and values used in init_alpha structure +#define DISP_ALPHA_FORMAT 0x00000100 // Alpha plane format +#define DISP_ALPHA_FORMAT_RGB565 0x00000001 +#define DISP_ALPHA_FORMAT_ALPHA44 0x00000002 +#define DISP_ALPHA_FORMAT_ALPHA4444 0x00000003 + +// Init flags and values used in init_crt structure +#define DISP_CRT_TVP 0x00000100 // TV clock phase select +#define DISP_CRT_TVP_HIGH 0x00000000 +#define DISP_CRT_TVP_LOW 0x00008000 + +#define DISP_CRT_CP 0x00000200 // CRT clock phase select +#define DISP_CRT_CP_HIGH 0x00000000 +#define DISP_CRT_CP_LOW 0x00004000 + +#define DISP_CRT_BLANK 0x00000400 // CRT data blanking +#define DISP_CRT_BLANK_OFF 0x00000000 +#define DISP_CRT_BLANK_ON 0x00000400 + +#define DISP_CRT_FORMAT 0x00000800 // CRT graphics plane format +#define DISP_CRT_FORMAT_8 0x00000000 +#define DISP_CRT_FORMAT_16 0x00000001 +#define DISP_CRT_FORMAT_32 0x00000002 + +#define DISP_MODE_8_BPP 0 // 8 bits per pixel i8RGB +#define DISP_MODE_16_BPP 1 // 16 bits per pixel RGB565 +#define DISP_MODE_32_BPP 2 // 32 bits per pixel RGB888 +#define DISP_MODE_YUV 3 // 16 bits per pixel YUV422 +#define DISP_MODE_ALPHA_8 4 // 8 bits per pixel a4i4RGB +#define DISP_MODE_ALPHA_16 5 // 16 bits per pixel a4RGB444 + +#define DISP_PAN_LEFT 0 // Pan left +#define DISP_PAN_RIGHT 1 // Pan right +#define DISP_PAN_UP 2 // Pan upwards +#define DISP_PAN_DOWN 3 // Pan downwards + +#define DISP_DPMS_QUERY -1 // Query DPMS value +#define DISP_DPMS_ON 0 // DPMS on +#define DISP_DPMS_STANDBY 1 // DPMS standby +#define DISP_DPMS_SUSPEND 2 // DPMS suspend +#define DISP_DPMS_OFF 3 // DPMS off + +#define DISP_DELAY_DEFAULT 0 // Default delay + +#define DISP_HVTOTAL_UNKNOWN -1 // Used in panelSetTiming, crtSetTiming if + // nHTotal, nVTotal not specified by user +#define DISP_HVTOTAL_SCALEFACTOR 1.25 // Used in panelSetTiming, crtSetTiming if + // nHTotal, nVTotal not specified by user + +#define VGX_SIGNAL_PANEL_VSYNC 100 // Panel VSYNC +#define VGX_SIGNAL_PANEL_PAN 101 // Panel auto panning complete +#define VGX_SIGNAL_CRT_VSYNC 102 // CRT VSYNC + +#define VSYNCTIMEOUT 10000 + +#define ALPHA_MODE_PER_PIXEL 0 // Use per-pixel alpha values +#define ALPHA_MODE_ALPHA 1 // Use alpha value specified in Alpha bitfield +#define ALPHA_COLOR_LUT_SIZE 16 // Number of colors in alpha/video alpha palette + +#define HWC_ON_SCREEN 0 // Cursor is within screen top/left boundary +#define HWC_OFF_SCREEN 1 // Cursor is outside screen top/left boundary +#define HWC_NUM_COLORS 3 // Number of cursor colors + diff --git a/drivers/video/smi/sm7xxhw.h b/drivers/video/smi/sm7xxhw.h new file mode 100755 index 0000000..fe70c82 --- /dev/null +++ b/drivers/video/smi/sm7xxhw.h @@ -0,0 +1,104 @@ +/* + * linux/drivers/video/sm7xxhw.h -- Silicon Motion SM7xx frame buffer device + * + * Copyright (C) 2006 Silicon Motion, Inc. + * Ge Wang, gewang@siliconmotion.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License version 2 or later. See the file COPYING in the main directory of + * this archive for more details. + */ + + +#define SM712_VIDEOMEMORYSIZE 0x00400000 /*Assume SM712 graphics chip has 4MB VRAM */ +#define SM722_VIDEOMEMORYSIZE 0x00800000 /*Assume SM722 graphics chip has 8MB VRAM */ + +#define dac_reg (0x3c8) +#define dac_val (0x3c9) + +#define smtc_mmiowb(dat,reg) writeb(dat, smtc_RegBaseAddress + reg) +#define smtc_mmioww(dat,reg) writew(dat, smtc_RegBaseAddress + reg) +#define smtc_mmiowl(dat,reg) writel(dat, smtc_RegBaseAddress + reg) + +#define smtc_mmiorb(reg) readb(smtc_RegBaseAddress + reg) +#define smtc_mmiorw(reg) readw(smtc_RegBaseAddress + reg) +#define smtc_mmiorl(reg) readl(smtc_RegBaseAddress + reg) + +#define SIZE_SR00_SR04 (0x04 - 0x00 + 1) +#define SIZE_SR10_SR24 (0x24 - 0x10 + 1) +#define SIZE_SR30_SR75 (0x75 - 0x30 + 1) +#define SIZE_SR80_SR93 (0x93 - 0x80 + 1) +#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1) +#define SIZE_GR00_GR08 (0x08 - 0x00 + 1) +#define SIZE_AR00_AR14 (0x14 - 0x00 + 1) +#define SIZE_CR00_CR18 (0x18 - 0x00 + 1) +#define SIZE_CR30_CR4D (0x4D - 0x30 + 1) +#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1) +#define SIZE_VPR (0x6C + 1) +#define SIZE_DPR (0x44 + 1) + + +static inline void smtc_crtcw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3d4); + smtc_mmiowb(val, 0x3d5); +} + +static inline unsigned int smtc_crtcr(int reg) +{ + smtc_mmiowb(reg, 0x3d4); + return smtc_mmiorb(0x3d5); +} + +static inline void smtc_grphw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3ce); + smtc_mmiowb(val, 0x3cf); +} + +static inline unsigned int smtc_grphr(int reg) +{ + smtc_mmiowb(reg, 0x3ce); + return smtc_mmiorb(0x3cf); +} + +static inline void smtc_attrw(int reg, int val) +{ + smtc_mmiorb(0x3da); + smtc_mmiowb(reg, 0x3c0); + smtc_mmiorb(0x3c1); + smtc_mmiowb(val, 0x3c0); +} + +static inline void smtc_seqw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3c4); + smtc_mmiowb(val, 0x3c5); +} + +static inline unsigned int smtc_seqr(int reg) +{ + smtc_mmiowb(reg, 0x3c4); + return smtc_mmiorb(0x3c5); +} + +// The next structure holds all information relevant for a specific video mode. +struct ModeInit +{ + int mmSizeX; + int mmSizeY; + int bpp; + int hz; + unsigned char Init_MISC; + unsigned char Init_SR00_SR04[SIZE_SR00_SR04]; + unsigned char Init_SR10_SR24[SIZE_SR10_SR24]; + unsigned char Init_SR30_SR75[SIZE_SR30_SR75]; + unsigned char Init_SR80_SR93[SIZE_SR80_SR93]; + unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF]; + unsigned char Init_GR00_GR08[SIZE_GR00_GR08]; + unsigned char Init_AR00_AR14[SIZE_AR00_AR14]; + unsigned char Init_CR00_CR18[SIZE_CR00_CR18]; + unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D]; + unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7]; +}; + diff --git a/drivers/video/smi/smtc2d.c b/drivers/video/smi/smtc2d.c new file mode 100755 index 0000000..c85ff37 --- /dev/null +++ b/drivers/video/smi/smtc2d.c @@ -0,0 +1,1372 @@ +/* + * linux/drivers/video/smtc2d.c -- Silicon Motion SM501 and SM7xx 2D drawing engine functions. + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Boyod boyod.yang@siliconmotion.com.cn + * + * This file is subject to the terms and conditions of the GNU General Public + * License version 2 or later. See the file COPYING in the main directory of + * this archive for more details. + * + */ + +/* + * Version 0.10.26192.21.01 + * - Add PowerPC support + * - Add 2D support for Lynx + * - Verified on 2.6.19.2 Boyod.yang + */ + +unsigned char smtc_de_busy = 0; +void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData) +{ + writel(nData, smtc_2DBaseAddress+nOffset) ; +} + +unsigned long SMTC_read2Dreg(unsigned long nOffset) +{ + readl(smtc_2DBaseAddress+nOffset) ; +} + + +void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData) +{ + writel(nData, smtc_2Ddataport+nOffset); +} + +/********************************************************************** + * + * deInit + * + * Purpose + * Drawing engine initialization. + * + **********************************************************************/ +void deInit(unsigned int nModeWidth, unsigned int nModeHeight, unsigned int bpp) +{ + + // Get current power configuration. + unsigned char gate, clock; + clock = smtc_seqr(0x21); + // Enable 2D Drawing Engine + smtc_seqw(0x21,clock& 0xF8); + + SMTC_write2Dreg(DE_CLIP_TL, + FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) | + FIELD_SET (0, DE_CLIP_TL, STATUS, DISABLE) | + FIELD_SET (0, DE_CLIP_TL, INHIBIT, OUTSIDE) | + FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0)); + + if (bpp>=24){ + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, nModeWidth*3) | + FIELD_VALUE(0, DE_PITCH, SOURCE, nModeWidth*3)); + }else{ + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, nModeWidth) | + FIELD_VALUE(0, DE_PITCH, SOURCE, nModeWidth)); + } + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, nModeWidth) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, nModeWidth)); + + switch (bpp) + { + case 8: + SMTC_write2Dreg(DE_STRETCH_FORMAT, + FIELD_SET (0, DE_STRETCH_FORMAT, PATTERN_XY, NORMAL) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_Y, 0) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, 0) | + FIELD_SET (0, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8) | + FIELD_SET (0, DE_STRETCH_FORMAT, ADDRESSING, XY) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, SOURCE_HEIGHT, 3)); + break; + case 24: + SMTC_write2Dreg(DE_STRETCH_FORMAT, + FIELD_SET (0, DE_STRETCH_FORMAT, PATTERN_XY, NORMAL) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_Y, 0) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, 0) | + FIELD_SET (0, DE_STRETCH_FORMAT, PIXEL_FORMAT, 24) | + FIELD_SET (0, DE_STRETCH_FORMAT, ADDRESSING, XY) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, SOURCE_HEIGHT, 3)); + break; + case 16: + default: + SMTC_write2Dreg(DE_STRETCH_FORMAT, + FIELD_SET (0, DE_STRETCH_FORMAT, PATTERN_XY, NORMAL) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_Y, 0) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, 0) | + FIELD_SET (0, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16) | + FIELD_SET (0, DE_STRETCH_FORMAT, ADDRESSING, XY) | + FIELD_VALUE(0, DE_STRETCH_FORMAT, SOURCE_HEIGHT, 3)); + break; + } + + SMTC_write2Dreg(DE_MASKS, + FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) | + FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF)); + SMTC_write2Dreg(DE_COLOR_COMPARE_MASK, + FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, 0xFFFFFF)); + SMTC_write2Dreg(DE_COLOR_COMPARE, + FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF)); +} + + +/********************************************************************** + * + * deSetClipRectangle + * + * Purpose + * Set drawing engine clip rectangle. + * + * Remarks + * Caller need to pass in valid rectangle parameter in device coordinate. + **********************************************************************/ +void deSetClipRectangle(int left, int top, int right, int bottom) +{ + /* Top left of clipping rectangle cannot be negative */ + if (top < 0) + { + top = 0; + } + + if (left < 0) + { + left = 0; + } + + SMTC_write2Dreg(DE_CLIP_TL, + FIELD_VALUE(0, DE_CLIP_TL, TOP, top) | + FIELD_SET (0, DE_CLIP_TL, STATUS, ENABLE) | + FIELD_SET (0, DE_CLIP_TL, INHIBIT, OUTSIDE) | + FIELD_VALUE(0, DE_CLIP_TL, LEFT, left)); + SMTC_write2Dreg(DE_CLIP_BR, + FIELD_VALUE(0, DE_CLIP_BR, BOTTOM, bottom) | + FIELD_VALUE(0, DE_CLIP_BR, RIGHT, right)); +} + + +void deVerticalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_height, + unsigned long nColor) +{ + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, nX) | + FIELD_VALUE(0, DE_DESTINATION, Y, nY)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, 1) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET (0, DE_CONTROL, STATUS, START) | + FIELD_SET (0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | + FIELD_SET (0, DE_CONTROL, MAJOR, Y) | + FIELD_SET (0, DE_CONTROL, STEP_X, NEGATIVE) | + FIELD_SET (0, DE_CONTROL, STEP_Y, POSITIVE) | + FIELD_SET (0, DE_CONTROL, LAST_PIXEL, OFF) | + FIELD_SET (0, DE_CONTROL, COMMAND, SHORT_STROKE) | + FIELD_SET (0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); + + smtc_de_busy = 1; +} + +void deHorizontalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_width, + unsigned long nColor) +{ + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, dst_pitch)); + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, nX) | + FIELD_VALUE(0, DE_DESTINATION, Y, nY)); + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, 1)); + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET (0, DE_CONTROL, STATUS, START) | + FIELD_SET (0, DE_CONTROL, DIRECTION, RIGHT_TO_LEFT) | + FIELD_SET (0, DE_CONTROL, MAJOR, X) | + FIELD_SET (0, DE_CONTROL, STEP_X, POSITIVE) | + FIELD_SET (0, DE_CONTROL, STEP_Y, NEGATIVE) | + FIELD_SET (0, DE_CONTROL, LAST_PIXEL, OFF) | + FIELD_SET (0, DE_CONTROL, COMMAND, SHORT_STROKE) | + FIELD_SET (0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); + + smtc_de_busy = 1; +} + + +void deLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX1, + unsigned long nY1, + unsigned long nX2, + unsigned long nY2, + unsigned long nColor) +{ + unsigned long nCommand = + FIELD_SET (0, DE_CONTROL, STATUS, START) | + FIELD_SET (0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | + FIELD_SET (0, DE_CONTROL, MAJOR, X) | + FIELD_SET (0, DE_CONTROL, STEP_X, POSITIVE) | + FIELD_SET (0, DE_CONTROL, STEP_Y, POSITIVE) | + FIELD_SET (0, DE_CONTROL, LAST_PIXEL, OFF) | + FIELD_SET (0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C); + unsigned long DeltaX; + unsigned long DeltaY; + + /* Calculate delta X */ + if (nX1 <= nX2) + { + DeltaX = nX2 - nX1; + } + else + { + DeltaX = nX1 - nX2; + nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE); + } + + /* Calculate delta Y */ + if (nY1 <= nY2) + { + DeltaY = nY2 - nY1; + } + else + { + DeltaY = nY1 - nY2; + nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE); + } + + /* Determine the major axis */ + if (DeltaX < DeltaY) + { + nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y); + } + + /* Vertical line? */ + if (nX1 == nX2) + deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor); + + /* Horizontal line? */ + else if (nY1 == nY2) + deHorizontalLine(dst_base, dst_pitch, nX1, nY1, DeltaX, nColor); + + /* Diagonal line? */ + else if (DeltaX == DeltaY) + { + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, 1) | + FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, 1) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(nCommand, DE_CONTROL, COMMAND, SHORT_STROKE)); + } + + /* Generic line */ + else + { + unsigned int k1, k2, et, w; + if (DeltaX < DeltaY) + { + k1 = 2 * DeltaX; + et = k1 - DeltaY; + k2 = et - DeltaY; + w = DeltaY + 1; + } + else + { + k1 = 2 * DeltaY; + et = k1 - DeltaX; + k2 = et - DeltaX; + w = DeltaX + 1; + } + + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, k1) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, k2)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, nX1) | + FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, w) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, et)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET(nCommand, DE_CONTROL, COMMAND, LINE_DRAW)); + } + + smtc_de_busy = 1; +} + + +void deFillRect(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long nColor) +{ + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, dst_base)); + + if (dst_pitch) + { + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, dst_pitch)); + } + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_SET (0, DE_CONTROL, STATUS, START) | + FIELD_SET (0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | + FIELD_SET (0, DE_CONTROL, LAST_PIXEL, OFF) | + FIELD_SET (0, DE_CONTROL, COMMAND, RECTANGLE_FILL) | + FIELD_SET (0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); + + smtc_de_busy = 1; +} + + +/********************************************************************** + * + * deRotatePattern + * + * Purpose + * Rotate the given pattern if necessary + * + * Parameters + * [in] + * pPattern - Pointer to DE_SURFACE structure containing + * pattern attributes + * patternX - X position (0-7) of pattern origin + * patternY - Y position (0-7) of pattern origin + * + * [out] + * pattern_dstaddr - Pointer to pre-allocated buffer containing rotated pattern + * + * + **********************************************************************/ +void deRotatePattern(unsigned char* pattern_dstaddr, + unsigned long pattern_src_addr, + unsigned long pattern_BPP, + unsigned long pattern_stride, + int patternX, + int patternY) +{ + unsigned int i; + unsigned long pattern_read_addr; + unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT]; + unsigned int x, y; + unsigned char* pjPatByte; + + if (pattern_dstaddr != NULL) + { + deWaitForNotBusy(); + + /* Load pattern from local video memory into pattern array */ + pattern_read_addr = pattern_src_addr; + + for (i = 0; i < (pattern_BPP * 2); i++) + { +// pattern[i] = memRead32(pattern_read_addr); removed by boyod + pattern_read_addr += 4; + } + + if (patternX || patternY) + { + /* Rotate pattern */ + pjPatByte = (unsigned char*)pattern; + + switch (pattern_BPP) + { + case 8: + { + for (y = 0; y < 8; y++) + { + unsigned char* pjBuffer = pattern_dstaddr + ((patternY + y) & 7) * 8; + for (x = 0; x < 8; x++) + { + pjBuffer[(patternX + x) & 7] = pjPatByte[x]; + } + pjPatByte += pattern_stride; + } + break; + } + + case 16: + { + for (y = 0; y < 8; y++) + { + unsigned short* pjBuffer = (unsigned short*) pattern_dstaddr + ((patternY + y) & 7) * 8; + for (x = 0; x < 8; x++) + { + pjBuffer[(patternX + x) & 7] = ((unsigned short*) pjPatByte)[x]; + } + pjPatByte += pattern_stride; + } + break; + } + + case 32: + { + for (y = 0; y < 8; y++) + { + unsigned long* pjBuffer = (unsigned long*) pattern_dstaddr + ((patternY + y) & 7) * 8; + for (x = 0; x < 8; x++) + { + pjBuffer[(patternX + x) & 7] = ((unsigned long*) pjPatByte)[x]; + } + pjPatByte += pattern_stride; + } + break; + } + } + } + else + { + /* Don't rotate, just copy pattern into pattern_dstaddr */ + for (i = 0; i < (pattern_BPP * 2); i++) + { + ((unsigned long *)pattern_dstaddr)[i] = pattern[i]; + } + } + + } +} + + +/********************************************************************** + * + * deMonoPatternFill + * + * Purpose + * Copy the specified monochrome pattern into the destination surface + * + * Remarks + * Pattern size must be 8x8 pixel. + * Pattern color depth must be same as destination bitmap or monochrome. +**********************************************************************/ +void deMonoPatternFill(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dstX, + unsigned long dstY, + unsigned long dst_width, + unsigned long dst_height, + unsigned long pattern_FGcolor, + unsigned long pattern_BGcolor, + unsigned long pattern_low, + unsigned long pattern_high) +{ + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_PITCH, FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, pattern_FGcolor)); + + SMTC_write2Dreg(DE_BACKGROUND, + FIELD_VALUE(0, DE_BACKGROUND, COLOR, pattern_BGcolor)); + + SMTC_write2Dreg(DE_MONO_PATTERN_LOW, + FIELD_VALUE(0, DE_MONO_PATTERN_LOW, PATTERN, pattern_low)); + + SMTC_write2Dreg(DE_MONO_PATTERN_HIGH, + FIELD_VALUE(0, DE_MONO_PATTERN_HIGH, PATTERN, pattern_high)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dstX) | + FIELD_VALUE(0, DE_DESTINATION, Y, dstY)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_VALUE(0, DE_CONTROL, ROP, 0xF0) | + FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | + FIELD_SET(0, DE_CONTROL, PATTERN, MONO) | + FIELD_SET(0, DE_CONTROL, STATUS, START)); + + smtc_de_busy = 1; +} /* deMonoPatternFill() */ + + +/********************************************************************** + * + * deColorPatternFill + * + * Purpose + * Copy the specified pattern into the destination surface + * + * Parameters + * [in] + * pDestSurface - Pointer to DE_SURFACE structure containing + * destination surface attributes + * nX - X coordinate of destination surface to be filled + * nY - Y coordinate of destination surface to be filled + * dst_width - Width (in pixels) of area to be filled + * dst_height - Height (in lines) of area to be filled + * pPattern - Pointer to DE_SURFACE structure containing + * pattern attributes + * pPatternOrigin - Pointer to Point structure containing pattern origin + * pMonoInfo - Pointer to mono_pattern_info structure + * pClipRect - Pointer to Rect structure describing clipping + * rectangle; NULL if no clipping required + * + * [out] + * None + * + * Remarks + * Pattern size must be 8x8 pixel. + * Pattern color depth must be same as destination bitmap. +**********************************************************************/ +void deColorPatternFill(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long pattern_src_addr, + unsigned long pattern_stride, + int PatternOriginX, + int PatternOriginY) +{ + unsigned int i; + unsigned long de_data_port_write_addr; + unsigned char ajPattern[PATTERN_WIDTH * PATTERN_HEIGHT * 4]; + unsigned long de_ctrl = 0; + + deWaitForNotBusy(); + + de_ctrl = FIELD_SET(0, DE_CONTROL, PATTERN, COLOR); + + SMTC_write2Dreg(DE_CONTROL, de_ctrl); + + /* Rotate pattern if necessary */ + deRotatePattern(ajPattern, pattern_src_addr, dst_BPP, pattern_stride, PatternOriginX, PatternOriginY); + + /* Load pattern to 2D Engine Data Port */ + de_data_port_write_addr = 0; + + for (i = 0; i < (dst_BPP * 2); i++) + { + SMTC_write2Ddataport(de_data_port_write_addr, ((unsigned long *)ajPattern)[i]); + de_data_port_write_addr += 4; + } + + deWaitForNotBusy(); + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + SMTC_write2Dreg(DE_CONTROL, + FIELD_VALUE(0, DE_CONTROL, ROP, 0xF0) | + FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | + FIELD_SET(0, DE_CONTROL, PATTERN, COLOR) | + FIELD_SET(0, DE_CONTROL, STATUS, START)); + + smtc_de_busy = 1; +} /* deColorPatternFill() */ + + +/********************************************************************** + * + * deCopy + * + * Purpose + * Copy a rectangular area of the source surface to a destination surface + * + * Remarks + * Source bitmap must have the same color depth (BPP) as the destination bitmap. + * +**********************************************************************/ +void deCopy(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long src_base, + unsigned long src_pitch, + unsigned long src_X, + unsigned long src_Y, + pTransparent pTransp, + unsigned char nROP2) +{ + unsigned long nDirection = 0; + unsigned long nTransparent = 0; + unsigned long opSign = 1; // Direction of ROP2 operation: 1 = Left to Right, (-1) = Right to Left + unsigned long xWidth = 192 / (dst_BPP / 8); // xWidth is in pixels + unsigned long de_ctrl = 0; + + deWaitForNotBusy(); + + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS, src_base)); + + if (dst_pitch && src_pitch) + { + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, src_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, src_pitch)); + } + + /* Set transparent bits if necessary */ + if (pTransp != NULL) + { + nTransparent = pTransp->match | pTransp->select | pTransp->control; + + /* Set color compare register */ + SMTC_write2Dreg(DE_COLOR_COMPARE, + FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, pTransp->color)); + } + + /* Determine direction of operation */ + if (src_Y < dst_Y) + { + /* +----------+ + |S | + | +----------+ + | | | | + | | | | + +---|------+ | + | D| + +----------+ */ + + nDirection = BOTTOM_TO_TOP; + } + else if (src_Y > dst_Y) + { + /* +----------+ + |D | + | +----------+ + | | | | + | | | | + +---|------+ | + | S| + +----------+ */ + + nDirection = TOP_TO_BOTTOM; + } + else + { + /* src_Y == dst_Y */ + + if (src_X <= dst_X) + { + /* +------+---+------+ + |S | | D| + | | | | + | | | | + | | | | + +------+---+------+ */ + + nDirection = RIGHT_TO_LEFT; + } + else + { + /* src_X > dst_X */ + + /* +------+---+------+ + |D | | S| + | | | | + | | | | + | | | | + +------+---+------+ */ + + nDirection = LEFT_TO_RIGHT; + } + } + + if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) + { + src_X += dst_width - 1; + src_Y += dst_height - 1; + dst_X += dst_width - 1; + dst_Y += dst_height - 1; + opSign = (-1); + } + + + if (dst_BPP>=24){ + src_X*=3; + src_Y*=3; + dst_X*=3; + dst_Y*=3; + dst_width*=3; + if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) + { + src_X += 2; + dst_X += 2; + } + } + + /* Workaround for 192 byte hw bug */ + if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) + { + /* Perform the ROP2 operation in chunks of (xWidth * dst_height) */ + while (1) + { + deWaitForNotBusy(); + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, xWidth) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) | + nTransparent | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | + ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION, RIGHT_TO_LEFT) + : FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT)) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + SMTC_write2Dreg(DE_CONTROL, de_ctrl); + + src_X += (opSign * xWidth); + dst_X += (opSign * xWidth); + dst_width -= xWidth; + + if (dst_width <= 0) + { + /* ROP2 operation is complete */ + break; + } + + if (xWidth > dst_width) + { + xWidth = dst_width; + } + } + } + else + { + deWaitForNotBusy(); + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) | + nTransparent | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | + ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION, RIGHT_TO_LEFT) + : FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT)) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + SMTC_write2Dreg(DE_CONTROL, de_ctrl); + } + + smtc_de_busy = 1; +} + + +/********************************************************************** + * + * deSrcCopyHost + * + * Purpose + * Copy a rectangular area of the source surface in system memory to + * a destination surface in video memory + * + * Remarks + * Source bitmap must have the same color depth (BPP) as the destination bitmap. + * +**********************************************************************/ +void deSrcCopyHost(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long src_base, + unsigned long src_stride, + unsigned long src_X, + unsigned long src_Y, + pTransparent pTransp, + unsigned char nROP2) +{ + int nBytes_per_scan; + int nBytes8_per_scan; + int nBytes_remain; + int nLong; + unsigned long nTransparent = 0; + unsigned long de_ctrl = 0; + unsigned long i; + int j; + unsigned long ulSrc; + unsigned long de_data_port_write_addr; + unsigned char abyRemain[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + unsigned char *pSrcBuffer; + + pSrcBuffer = (unsigned char*)(src_base + src_Y * src_stride + src_X * (dst_BPP / 8)); + + nBytes_per_scan = dst_width * (dst_BPP / 8); + nBytes8_per_scan = (nBytes_per_scan + 7) & ~7; + nBytes_remain = nBytes_per_scan & 7; + nLong = nBytes_per_scan & ~7; + + /* Program 2D Drawing Engine */ + deWaitForNotBusy(); + + /* Set transparent bits if necessary */ + if (pTransp != NULL) + { + nTransparent = pTransp->match | pTransp->select | pTransp->control; + + /* Set color compare register */ + SMTC_write2Dreg(DE_COLOR_COMPARE, + FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, pTransp->color)); + } + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS, 0)); + + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, 0) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_width) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_width)); + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, dst_width) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, dst_width)); + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) | + nTransparent | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + SMTC_write2Dreg(DE_CONTROL, de_ctrl); + + /* Write bitmap/image data (line by line) to 2D Engine data port */ + de_data_port_write_addr = 0; + + for (i = 1; i < dst_height; i++) + { + for (j = 0; j < (nBytes8_per_scan / 4); j++) + { + memcpy(&ulSrc, (pSrcBuffer + (j * 4)), 4); + SMTC_write2Ddataport(de_data_port_write_addr, ulSrc); + } + + pSrcBuffer += src_stride; + } + + /* Special handling for last line of bitmap */ + if (nLong) + { + for (j = 0; j < (nLong / 4); j++) + { + memcpy(&ulSrc, (pSrcBuffer + (j * 4)), 4); + SMTC_write2Ddataport(de_data_port_write_addr, ulSrc); + } + } + + if (nBytes_remain) + { + memcpy(abyRemain, (pSrcBuffer + nLong), nBytes_remain); + SMTC_write2Ddataport(de_data_port_write_addr, *(unsigned long*)abyRemain); + SMTC_write2Ddataport(de_data_port_write_addr, *(unsigned long*)(abyRemain + 4)); + } + + smtc_de_busy = 1; +} + + +/********************************************************************** + * + * deMonoSrcCopyHost + * + * Purpose + * Copy a rectangular area of the monochrome source surface in + * system memory to a destination surface in video memory + * + * Parameters + * [in] + * pSrcSurface - Pointer to DE_SURFACE structure containing + * source surface attributes + * pSrcBuffer - Pointer to source buffer (system memory) + * containing monochrome image + * src_X - X coordinate of source surface + * src_Y - Y coordinate of source surface + * pDestSurface - Pointer to DE_SURFACE structure containing + * destination surface attributes + * dst_X - X coordinate of destination surface + * dst_Y - Y coordinate of destination surface + * dst_width - Width (in pixels) of the area to be copied + * dst_height - Height (in lines) of the area to be copied + * nFgColor - Foreground color + * nBgColor - Background color + * pClipRect - Pointer to Rect structure describing clipping + * rectangle; NULL if no clipping required + * pTransp - Pointer to Transparent structure containing + * transparency settings; NULL if no transparency + * required + * + * [out] + * None + * + * Returns + * DDK_OK - function is successful + * DDK_ERROR_NULL_PSRCSURFACE - pSrcSurface is NULL + * DDK_ERROR_NULL_PDESTSURFACE - pDestSurface is NULL + * +**********************************************************************/ +void deMonoSrcCopyHost(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long src_base, + unsigned long src_stride, + unsigned long src_X, + unsigned long src_Y, + unsigned long nFgColor, + unsigned long nBgColor, + pTransparent pTransp) +{ + int nLeft_bits_off; + int nBytes_per_scan; + int nBytes4_per_scan; + int nBytes_remain; + int nLong; + unsigned long nTransparent = 0; + unsigned long de_ctrl = 0; + unsigned long de_data_port_write_addr; + unsigned long i; + int j; + unsigned long ulSrc; + unsigned char * pSrcBuffer; + + pSrcBuffer = (unsigned char *)src_base+(src_Y * src_stride) + (src_X / 8); + nLeft_bits_off = (src_X & 0x07); + nBytes_per_scan = (dst_width + nLeft_bits_off + 7) / 8; + nBytes4_per_scan = (nBytes_per_scan + 3) & ~3; + nBytes_remain = nBytes_per_scan & 3; + nLong = nBytes_per_scan & ~3; + + deWaitForNotBusy(); + + /* Set transparent bits if necessary */ + if (pTransp != NULL) + { + nTransparent = pTransp->match | pTransp->select | pTransp->control; + + /* Set color compare register */ + SMTC_write2Dreg(DE_COLOR_COMPARE, + FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, pTransp->color)); + } + + /* Program 2D Drawing Engine */ + + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, dst_base)); + + SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS, 0)); + + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, dst_pitch) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, dst_pitch)); + + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, nLeft_bits_off) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | + FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); + + SMTC_write2Dreg(DE_FOREGROUND, + FIELD_VALUE(0, DE_FOREGROUND, COLOR, nFgColor)); + + SMTC_write2Dreg(DE_BACKGROUND, + FIELD_VALUE(0, DE_BACKGROUND, COLOR, nBgColor)); + + de_ctrl = 0x0000000C | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) | + FIELD_SET(0, DE_CONTROL, HOST, MONO) | + nTransparent | + FIELD_SET(0, DE_CONTROL, STATUS, START); + SMTC_write2Dreg(DE_CONTROL, de_ctrl); + + /* Write bitmap/image data (line by line) to 2D Engine data port */ + de_data_port_write_addr = 0; + + for (i = 1; i < dst_height; i++) + { + for (j = 0; j < (nBytes4_per_scan / 4); j++) + { + memcpy(&ulSrc, (pSrcBuffer + (j * 4)), 4); + SMTC_write2Ddataport(de_data_port_write_addr, ulSrc); + } + + pSrcBuffer += src_stride; + } + + /* Special handling for last line of bitmap */ + if (nLong) + { + for (j = 0; j < (nLong / 4); j++) + { + memcpy(&ulSrc, (pSrcBuffer + (j * 4)), 4); + SMTC_write2Ddataport(de_data_port_write_addr, ulSrc); + } + } + + if (nBytes_remain) + { + memcpy(&ulSrc, (pSrcBuffer + nLong), nBytes_remain); + SMTC_write2Ddataport(de_data_port_write_addr, ulSrc); + } + + smtc_de_busy = 1; +} + +/* + * This function sets the pixel format that will apply to the 2D Engine. + */ +void deSetPixelFormat( + unsigned long bpp +) +{ + unsigned long de_format; + + de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT); + + switch (bpp) + { + case 8: + de_format = FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8); + break; + default: + case 16: + de_format = FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16); + break; + case 32: + de_format = FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32); + break; + } + + SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format); +} + + + +/* + * System memory to Video memory monochrome expansion. + * Source is monochrome image in system memory. + * This function expands the monochrome data to color image in video memory. + */ +long deSystemMem2VideoMemMonoBlt( +unsigned char *pSrcbuf, /* pointer to start of source buffer in system memory */ +long srcDelta, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */ +unsigned long startBit, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */ +unsigned long dBase, /* Address of destination: offset in frame buffer */ +unsigned long dPitch, /* Pitch value of destination surface in BYTE */ +unsigned long bpp, /* Color depth of destination surface */ +unsigned long dx, +unsigned long dy, /* Starting coordinate of destination surface */ +unsigned long width, +unsigned long height, /* width and height of rectange in pixel value */ +unsigned long fColor, /* Foreground color (corresponding to a 1 in the monochrome data */ +unsigned long bColor, /* Background color (corresponding to a 0 in the monochrome data */ +unsigned long rop2) /* ROP value */ +{ + unsigned long bytePerPixel; + unsigned long ulBytesPerScan; + unsigned long ul4BytesPerScan; + unsigned long ulBytesRemain; + unsigned long de_ctrl = 0; + unsigned char ajRemain[4]; + long i, j; + + bytePerPixel = bpp/8; + + startBit &= 7; /* Just make sure the start bit is within legal range */ + ulBytesPerScan = (width + startBit + 7) / 8; + ul4BytesPerScan = ulBytesPerScan & ~3; + ulBytesRemain = ulBytesPerScan & 3; + + if (smtc_de_busy) + deWaitForNotBusy(); + + /* 2D Source Base. + Use 0 for HOST Blt. + */ + SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0); + + /* 2D Destination Base. + It is an address offset (128 bit aligned) from the beginning of frame buffer. + */ + SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase); + + + if (dPitch) + { + /* Program pitch (distance between the 1st points of two adjacent lines). + Note that input pitch is BYTE value, but the 2D Pitch register uses + pixel values. Need Byte to pixel convertion. + */ + SMTC_write2Dreg(DE_PITCH, + FIELD_VALUE(0, DE_PITCH, DESTINATION, dPitch/bytePerPixel) | + FIELD_VALUE(0, DE_PITCH, SOURCE, dPitch/bytePerPixel)); + + /* Screen Window width in Pixels. + 2D engine uses this value to calculate the linear address in frame buffer for a given point. + */ + SMTC_write2Dreg(DE_WINDOW_WIDTH, + FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, (dPitch/bytePerPixel)) | + FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, (dPitch/bytePerPixel))); + } + /* Note: For 2D Source in Host Write, only X_K1 field is needed, and Y_K2 field is not used. + For mono bitmap, use startBit for X_K1. */ + SMTC_write2Dreg(DE_SOURCE, + FIELD_SET (0, DE_SOURCE, WRAP, DISABLE) | + FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) | + FIELD_VALUE(0, DE_SOURCE, Y_K2, 0)); + + SMTC_write2Dreg(DE_DESTINATION, + FIELD_SET (0, DE_DESTINATION, WRAP, DISABLE) | + FIELD_VALUE(0, DE_DESTINATION, X, dx) | + FIELD_VALUE(0, DE_DESTINATION, Y, dy)); + + SMTC_write2Dreg(DE_DIMENSION, + FIELD_VALUE(0, DE_DIMENSION, X, width) | + FIELD_VALUE(0, DE_DIMENSION, Y_ET, height)); + + SMTC_write2Dreg(DE_FOREGROUND, fColor); + SMTC_write2Dreg(DE_BACKGROUND, bColor); + + if (bpp) + deSetPixelFormat(bpp); + /* Set the pixel format of the destination */ + + + de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | + FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | + FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) | + FIELD_SET(0, DE_CONTROL, HOST, MONO) | + FIELD_SET(0, DE_CONTROL, STATUS, START); + + SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency()); + + /* Write MONO data (line by line) to 2D Engine data port */ + for (i=0; i> _F_START(f)) +#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f)) + + +//////////////////////////////////////////////////////////////////////////////// +// // +// Global macros // +// // +//////////////////////////////////////////////////////////////////////////////// + +#define FIELD_GET(x, reg, field) \ +( \ + _F_NORMALIZE((x), reg ## _ ## field) \ +) + +#define FIELD_SET(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \ +) + +#define FIELD_VALUE(x, reg, field, value) \ +( \ + (x & ~_F_MASK(reg ## _ ## field)) \ + | _F_DENORMALIZE(value, reg ## _ ## field) \ +) + +#define FIELD_CLEAR(reg, field) \ +( \ + ~ _F_MASK(reg ## _ ## field) \ +) + + +//////////////////////////////////////////////////////////////////////////////// +// // +// Field Macros // +// // +//////////////////////////////////////////////////////////////////////////////// + +#define FIELD_START(field) (0 ? field) +#define FIELD_END(field) (1 ? field) +#define FIELD_SIZE(field) (1 + FIELD_END(field) - FIELD_START(field)) +#define FIELD_MASK(field) (((1 << (FIELD_SIZE(field)-1)) | ((1 << (FIELD_SIZE(field)-1)) - 1)) << FIELD_START(field)) +#define FIELD_NORMALIZE(reg, field) (((reg) & FIELD_MASK(field)) >> FIELD_START(field)) +#define FIELD_DENORMALIZE(field, value) (((value) << FIELD_START(field)) & FIELD_MASK(field)) + +#define FIELD_INIT(reg, field, value) FIELD_DENORMALIZE(reg ## _ ## field, \ + reg ## _ ## field ## _ ## value) +#define FIELD_INIT_VAL(reg, field, value) \ + (FIELD_DENORMALIZE(reg ## _ ## field, value)) +#define FIELD_VAL_SET(x, r, f, v) x = x & ~FIELD_MASK(r ## _ ## f) \ + | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) + + + + + +#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b))) + +// Transparent info definition +typedef struct +{ + unsigned long match; // Matching pixel is OPAQUE/TRANSPARENT + unsigned long select; // Transparency controlled by SOURCE/DESTINATION + unsigned long control; // ENABLE/DISABLE transparency + unsigned long color; // Transparent color +} Transparent, *pTransparent; + +#define PIXEL_DEPTH_1_BP 0 // 1 bit per pixel +#define PIXEL_DEPTH_8_BPP 1 // 8 bits per pixel +#define PIXEL_DEPTH_16_BPP 2 // 16 bits per pixel +#define PIXEL_DEPTH_32_BPP 3 // 32 bits per pixel +#define PIXEL_DEPTH_YUV422 8 // 16 bits per pixel YUV422 +#define PIXEL_DEPTH_YUV420 9 // 16 bits per pixel YUV420 + +#define PATTERN_WIDTH 8 +#define PATTERN_HEIGHT 8 + +#define TOP_TO_BOTTOM 0 +#define BOTTOM_TO_TOP 1 +#define RIGHT_TO_LEFT BOTTOM_TO_TOP +#define LEFT_TO_RIGHT TOP_TO_BOTTOM + +// Constants used in Transparent structure +#define MATCH_OPAQUE 0x00000000 +#define MATCH_TRANSPARENT 0x00000400 +#define SOURCE 0x00000000 +#define DESTINATION 0x00000200 + +// 2D registers. + +#define DE_SOURCE 0x000000 +#define DE_SOURCE_WRAP 31:31 +#define DE_SOURCE_WRAP_DISABLE 0 +#define DE_SOURCE_WRAP_ENABLE 1 +#define DE_SOURCE_X_K1 29:16 +#define DE_SOURCE_Y_K2 15:0 + +#define DE_DESTINATION 0x000004 +#define DE_DESTINATION_WRAP 31:31 +#define DE_DESTINATION_WRAP_DISABLE 0 +#define DE_DESTINATION_WRAP_ENABLE 1 +#define DE_DESTINATION_X 28:16 +#define DE_DESTINATION_Y 15:0 + +#define DE_DIMENSION 0x000008 +#define DE_DIMENSION_X 28:16 +#define DE_DIMENSION_Y_ET 15:0 + +#define DE_CONTROL 0x00000C +#define DE_CONTROL_STATUS 31:31 +#define DE_CONTROL_STATUS_STOP 0 +#define DE_CONTROL_STATUS_START 1 +#define DE_CONTROL_PATTERN 30:30 +#define DE_CONTROL_PATTERN_MONO 0 +#define DE_CONTROL_PATTERN_COLOR 1 +#define DE_CONTROL_UPDATE_DESTINATION_X 29:29 +#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0 +#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1 +#define DE_CONTROL_QUICK_START 28:28 +#define DE_CONTROL_QUICK_START_DISABLE 0 +#define DE_CONTROL_QUICK_START_ENABLE 1 +#define DE_CONTROL_DIRECTION 27:27 +#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0 +#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1 +#define DE_CONTROL_MAJOR 26:26 +#define DE_CONTROL_MAJOR_X 0 +#define DE_CONTROL_MAJOR_Y 1 +#define DE_CONTROL_STEP_X 25:25 +#define DE_CONTROL_STEP_X_POSITIVE 1 +#define DE_CONTROL_STEP_X_NEGATIVE 0 +#define DE_CONTROL_STEP_Y 24:24 +#define DE_CONTROL_STEP_Y_POSITIVE 1 +#define DE_CONTROL_STEP_Y_NEGATIVE 0 +#define DE_CONTROL_STRETCH 23:23 +#define DE_CONTROL_STRETCH_DISABLE 0 +#define DE_CONTROL_STRETCH_ENABLE 1 +#define DE_CONTROL_HOST 22:22 +#define DE_CONTROL_HOST_COLOR 0 +#define DE_CONTROL_HOST_MONO 1 +#define DE_CONTROL_LAST_PIXEL 21:21 +#define DE_CONTROL_LAST_PIXEL_OFF 0 +#define DE_CONTROL_LAST_PIXEL_ON 1 +#define DE_CONTROL_COMMAND 20:16 +#define DE_CONTROL_COMMAND_BITBLT 0 +#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1 +#define DE_CONTROL_COMMAND_DE_TILE 2 +#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3 +#define DE_CONTROL_COMMAND_ALPHA_BLEND 4 +#define DE_CONTROL_COMMAND_RLE_STRIP 5 +#define DE_CONTROL_COMMAND_SHORT_STROKE 6 +#define DE_CONTROL_COMMAND_LINE_DRAW 7 +#define DE_CONTROL_COMMAND_HOST_WRITE 8 +#define DE_CONTROL_COMMAND_HOST_READ 9 +#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10 +#define DE_CONTROL_COMMAND_ROTATE 11 +#define DE_CONTROL_COMMAND_FONT 12 +#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15 +#define DE_CONTROL_ROP_SELECT 15:15 +#define DE_CONTROL_ROP_SELECT_ROP3 0 +#define DE_CONTROL_ROP_SELECT_ROP2 1 +#define DE_CONTROL_ROP2_SOURCE 14:14 +#define DE_CONTROL_ROP2_SOURCE_BITMAP 0 +#define DE_CONTROL_ROP2_SOURCE_PATTERN 1 +#define DE_CONTROL_MONO_DATA 13:12 +#define DE_CONTROL_MONO_DATA_NOT_PACKED 0 +#define DE_CONTROL_MONO_DATA_8_PACKED 1 +#define DE_CONTROL_MONO_DATA_16_PACKED 2 +#define DE_CONTROL_MONO_DATA_32_PACKED 3 +#define DE_CONTROL_REPEAT_ROTATE 11:11 +#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0 +#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1 +#define DE_CONTROL_TRANSPARENCY_MATCH 10:10 +#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0 +#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1 +#define DE_CONTROL_TRANSPARENCY_SELECT 9:9 +#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0 +#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1 +#define DE_CONTROL_TRANSPARENCY 8:8 +#define DE_CONTROL_TRANSPARENCY_DISABLE 0 +#define DE_CONTROL_TRANSPARENCY_ENABLE 1 +#define DE_CONTROL_ROP 7:0 + +// Pseudo fields. + +#define DE_CONTROL_SHORT_STROKE_DIR 27:24 +#define DE_CONTROL_SHORT_STROKE_DIR_225 0 +#define DE_CONTROL_SHORT_STROKE_DIR_135 1 +#define DE_CONTROL_SHORT_STROKE_DIR_315 2 +#define DE_CONTROL_SHORT_STROKE_DIR_45 3 +#define DE_CONTROL_SHORT_STROKE_DIR_270 4 +#define DE_CONTROL_SHORT_STROKE_DIR_90 5 +#define DE_CONTROL_SHORT_STROKE_DIR_180 8 +#define DE_CONTROL_SHORT_STROKE_DIR_0 10 +#define DE_CONTROL_ROTATION 25:24 +#define DE_CONTROL_ROTATION_0 0 +#define DE_CONTROL_ROTATION_270 1 +#define DE_CONTROL_ROTATION_90 2 +#define DE_CONTROL_ROTATION_180 3 + +#define DE_PITCH 0x000010 +#define DE_PITCH_DESTINATION 28:16 +#define DE_PITCH_SOURCE 12:0 + +#define DE_FOREGROUND 0x000014 +#define DE_FOREGROUND_COLOR 31:0 + +#define DE_BACKGROUND 0x000018 +#define DE_BACKGROUND_COLOR 31:0 + +#define DE_STRETCH_FORMAT 0x00001C +#define DE_STRETCH_FORMAT_PATTERN_XY 30:30 +#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0 +#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1 +#define DE_STRETCH_FORMAT_PATTERN_Y 29:27 +#define DE_STRETCH_FORMAT_PATTERN_X 25:23 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21:20 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3 +#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2 +#define DE_STRETCH_FORMAT_ADDRESSING 19:16 +#define DE_STRETCH_FORMAT_ADDRESSING_XY 0 +#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15 +#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11:0 + +#define DE_COLOR_COMPARE 0x000020 +#define DE_COLOR_COMPARE_COLOR 23:0 + +#define DE_COLOR_COMPARE_MASK 0x000024 +#define DE_COLOR_COMPARE_MASK_MASKS 23:0 + +#define DE_MASKS 0x000028 +#define DE_MASKS_BYTE_MASK 31:16 +#define DE_MASKS_BIT_MASK 15:0 + +#define DE_CLIP_TL 0x00002C +#define DE_CLIP_TL_TOP 31:16 +#define DE_CLIP_TL_STATUS 13:13 +#define DE_CLIP_TL_STATUS_DISABLE 0 +#define DE_CLIP_TL_STATUS_ENABLE 1 +#define DE_CLIP_TL_INHIBIT 12:12 +#define DE_CLIP_TL_INHIBIT_OUTSIDE 0 +#define DE_CLIP_TL_INHIBIT_INSIDE 1 +#define DE_CLIP_TL_LEFT 11:0 + +#define DE_CLIP_BR 0x000030 +#define DE_CLIP_BR_BOTTOM 31:16 +#define DE_CLIP_BR_RIGHT 12:0 + +#define DE_MONO_PATTERN_LOW 0x000034 +#define DE_MONO_PATTERN_LOW_PATTERN 31:0 + +#define DE_MONO_PATTERN_HIGH 0x000038 +#define DE_MONO_PATTERN_HIGH_PATTERN 31:0 + +#define DE_WINDOW_WIDTH 0x00003C +#define DE_WINDOW_WIDTH_DESTINATION 28:16 +#define DE_WINDOW_WIDTH_SOURCE 12:0 + +#define DE_WINDOW_SOURCE_BASE 0x000040 +#define DE_WINDOW_SOURCE_BASE_EXT 27:27 +#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0 +#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_SOURCE_BASE_CS 26:26 +#define DE_WINDOW_SOURCE_BASE_CS_0 0 +#define DE_WINDOW_SOURCE_BASE_CS_1 1 +#define DE_WINDOW_SOURCE_BASE_ADDRESS 25:0 + +#define DE_WINDOW_DESTINATION_BASE 0x000044 +#define DE_WINDOW_DESTINATION_BASE_EXT 27:27 +#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0 +#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1 +#define DE_WINDOW_DESTINATION_BASE_CS 26:26 +#define DE_WINDOW_DESTINATION_BASE_CS_0 0 +#define DE_WINDOW_DESTINATION_BASE_CS_1 1 +#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25:0 + +#define DE_ALPHA 0x000048 +#define DE_ALPHA_VALUE 7:0 + +#define DE_WRAP 0x00004C +#define DE_WRAP_X 31:16 +#define DE_WRAP_Y 15:0 + +#define DE_STATUS 0x000050 +#define DE_STATUS_CSC 1:1 +#define DE_STATUS_CSC_CLEAR 0 +#define DE_STATUS_CSC_NOT_ACTIVE 0 +#define DE_STATUS_CSC_ACTIVE 1 +#define DE_STATUS_2D 0:0 +#define DE_STATUS_2D_CLEAR 0 +#define DE_STATUS_2D_NOT_ACTIVE 0 +#define DE_STATUS_2D_ACTIVE 1 + +// Color Space Conversion registers. + +#define CSC_Y_SOURCE_BASE 0x0000C8 +#define CSC_Y_SOURCE_BASE_EXT 27:27 +#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_Y_SOURCE_BASE_CS 26:26 +#define CSC_Y_SOURCE_BASE_CS_0 0 +#define CSC_Y_SOURCE_BASE_CS_1 1 +#define CSC_Y_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_CONSTANTS 0x0000CC +#define CSC_CONSTANTS_Y 31:24 +#define CSC_CONSTANTS_R 23:16 +#define CSC_CONSTANTS_G 15:8 +#define CSC_CONSTANTS_B 7:0 + +#define CSC_Y_SOURCE_X 0x0000D0 +#define CSC_Y_SOURCE_X_INTEGER 26:16 +#define CSC_Y_SOURCE_X_FRACTION 15:3 + +#define CSC_Y_SOURCE_Y 0x0000D4 +#define CSC_Y_SOURCE_Y_INTEGER 27:16 +#define CSC_Y_SOURCE_Y_FRACTION 15:3 + +#define CSC_U_SOURCE_BASE 0x0000D8 +#define CSC_U_SOURCE_BASE_EXT 27:27 +#define CSC_U_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_U_SOURCE_BASE_CS 26:26 +#define CSC_U_SOURCE_BASE_CS_0 0 +#define CSC_U_SOURCE_BASE_CS_1 1 +#define CSC_U_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_V_SOURCE_BASE 0x0000DC +#define CSC_V_SOURCE_BASE_EXT 27:27 +#define CSC_V_SOURCE_BASE_EXT_LOCAL 0 +#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1 +#define CSC_V_SOURCE_BASE_CS 26:26 +#define CSC_V_SOURCE_BASE_CS_0 0 +#define CSC_V_SOURCE_BASE_CS_1 1 +#define CSC_V_SOURCE_BASE_ADDRESS 25:0 + +#define CSC_SOURCE_DIMENSION 0x0000E0 +#define CSC_SOURCE_DIMENSION_X 31:16 +#define CSC_SOURCE_DIMENSION_Y 15:0 + +#define CSC_SOURCE_PITCH 0x0000E4 +#define CSC_SOURCE_PITCH_Y 31:16 +#define CSC_SOURCE_PITCH_UV 15:0 + +#define CSC_DESTINATION 0x0000E8 +#define CSC_DESTINATION_WRAP 31:31 +#define CSC_DESTINATION_WRAP_DISABLE 0 +#define CSC_DESTINATION_WRAP_ENABLE 1 +#define CSC_DESTINATION_X 27:16 +#define CSC_DESTINATION_Y 11:0 + +#define CSC_DESTINATION_DIMENSION 0x0000EC +#define CSC_DESTINATION_DIMENSION_X 31:16 +#define CSC_DESTINATION_DIMENSION_Y 15:0 + +#define CSC_DESTINATION_PITCH 0x0000F0 +#define CSC_DESTINATION_PITCH_X 31:16 +#define CSC_DESTINATION_PITCH_Y 15:0 + +#define CSC_SCALE_FACTOR 0x0000F4 +#define CSC_SCALE_FACTOR_HORIZONTAL 31:16 +#define CSC_SCALE_FACTOR_VERTICAL 15:0 + +#define CSC_DESTINATION_BASE 0x0000F8 +#define CSC_DESTINATION_BASE_EXT 27:27 +#define CSC_DESTINATION_BASE_EXT_LOCAL 0 +#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1 +#define CSC_DESTINATION_BASE_CS 26:26 +#define CSC_DESTINATION_BASE_CS_0 0 +#define CSC_DESTINATION_BASE_CS_1 1 +#define CSC_DESTINATION_BASE_ADDRESS 25:0 + +#define CSC_CONTROL 0x0000FC +#define CSC_CONTROL_STATUS 31:31 +#define CSC_CONTROL_STATUS_STOP 0 +#define CSC_CONTROL_STATUS_START 1 +#define CSC_CONTROL_SOURCE_FORMAT 30:28 +#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1 +#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2 +#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3 +#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4 +#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5 +#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6 +#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7 +#define CSC_CONTROL_DESTINATION_FORMAT 27:26 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0 +#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1 +#define CSC_CONTROL_HORIZONTAL_FILTER 25:25 +#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0 +#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1 +#define CSC_CONTROL_VERTICAL_FILTER 24:24 +#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0 +#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1 +#define CSC_CONTROL_BYTE_ORDER 23:23 +#define CSC_CONTROL_BYTE_ORDER_YUYV 0 +#define CSC_CONTROL_BYTE_ORDER_UYVY 1 + +#define DE_DATA_PORT_501 0x110000 +#define DE_DATA_PORT_712 0x400000 +#define DE_DATA_PORT_722 0x6000 + +extern char *smtc_RegBaseAddress; // point to virtual Memory Map IO starting address +extern char *smtc_VRAMBaseAddress; // point to virtual video memory starting address +extern unsigned char smtc_de_busy; + +extern unsigned long memRead32(unsigned long nOffset); +extern void memWrite32(unsigned long nOffset, unsigned long nData); +unsigned long SMTC_read2Dreg(unsigned long nOffset); + + + +/* 2D functions */ +extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight, unsigned int bpp); + +extern void deWaitForNotBusy(void); + +extern void deSetClipRectangle(int left, int top, int right, int bottom); + +extern void deVerticalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_height, + unsigned long nColor); + +extern void deHorizontalLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX, + unsigned long nY, + unsigned long dst_width, + unsigned long nColor); + +extern void deLine(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long nX1, + unsigned long nY1, + unsigned long nX2, + unsigned long nY2, + unsigned long nColor); + +extern void deFillRect(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long nColor); + +extern void deRotatePattern(unsigned char* pattern_dstaddr, + unsigned long pattern_src_addr, + unsigned long pattern_BPP, + unsigned long pattern_stride, + int patternX, + int patternY); + +extern void deMonoPatternFill(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dstX, + unsigned long dstY, + unsigned long dst_width, + unsigned long dst_height, + unsigned long pattern_FGcolor, + unsigned long pattern_BGcolor, + unsigned long pattern_low, + unsigned long pattern_high); + +extern void deColorPatternFill(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long pattern_src_addr, + unsigned long pattern_stride, + int PatternOriginX, + int PatternOriginY); + +extern void deCopy(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long src_base, + unsigned long src_pitch, + unsigned long src_X, + unsigned long src_Y, + pTransparent pTransp, + unsigned char nROP2); + +extern void deSrcCopyHost(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long src_base, + unsigned long src_stride, + unsigned long src_X, + unsigned long src_Y, + pTransparent pTransp, + unsigned char nROP2); + +extern void deMonoSrcCopyHost(unsigned long dst_base, + unsigned long dst_pitch, + unsigned long dst_BPP, + unsigned long dst_X, + unsigned long dst_Y, + unsigned long dst_width, + unsigned long dst_height, + unsigned long src_base, + unsigned long src_stride, + unsigned long src_X, + unsigned long src_Y, + unsigned long nFgColor, + unsigned long nBgColor, + pTransparent pTransp); + +/* + * System memory to Video memory monochrome expansion. + * Source is monochrome image in system memory. + * This function expands the monochrome data to color image in video memory. + */ +long deSystemMem2VideoMemMonoBlt( +unsigned char *pSrcbuf, /* pointer to start of source buffer in system memory */ +long srcDelta, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */ +unsigned long startBit, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */ +unsigned long dBase, /* Address of destination: offset in frame buffer */ +unsigned long dPitch, /* Pitch value of destination surface in BYTE */ +unsigned long bpp, /* Color depth of destination surface */ +unsigned long dx, +unsigned long dy, /* Starting coordinate of destination surface */ +unsigned long width, +unsigned long height, /* width and height of rectange in pixel value */ +unsigned long fColor, /* Foreground color (corresponding to a 1 in the monochrome data */ +unsigned long bColor, /* Background color (corresponding to a 0 in the monochrome data */ +unsigned long rop2); /* ROP value */ + +unsigned long deGetTransparency(); +void deSetPixelFormat( + unsigned long bpp +); + + + + +extern void deLoadPattern(unsigned char* pattern, unsigned long write_addr); + diff --git a/drivers/video/smi/smtcfb.c b/drivers/video/smi/smtcfb.c new file mode 100755 index 0000000..9cc4d01 --- /dev/null +++ b/drivers/video/smi/smtcfb.c @@ -0,0 +1,1261 @@ +/* + * linux/drivers/video/smtcfb.c -- Silicon Motion SM501 and SM7xx frame buffer device + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Ge Wang, gewang@siliconmotion.com + * Boyod boyod.yang@siliconmotion.com.cn + * + * This file is subject to the terms and conditions of the GNU General Public + * License version 2 or later. See the file COPYING in the main directory of + * this archive for more details. +* +* +* Version 0.10.26192.21.01 + - Add PowerPC/Big endian support + - Add 2D support for Lynx + - Verified on 2.6.19.2 Boyod.yang + +* Version 0.09.2621.00.01 + - Only support Linux Kernel's version 2.6.21. Boyod.yang + +* Version 0.09 + - Only support Linux Kernel's version 2.6.12. Boyod.yang + +*/ + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_PM +#include +#endif + +#include +#include +#include + +#include "smtcfb.h" +#include "smtc2d.h" + +#ifdef DEBUG +#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg) +#else +#define smdbg(format, arg...) +#endif + +#define DEFAULT_VIDEO_MODE "800x600-16@60" +#ifdef __BIG_ENDIAN +struct screen_info screen_info; +#endif + + + +/* + * globals + */ + +static char *mode_option __devinitdata = DEFAULT_VIDEO_MODE; + +/* +* Private structure +*/ +struct smtcfb_info { + /* + * The following is a pointer to be passed into the + * functions below. The modules outside the main + * voyager.c driver have no knowledge as to what + * is within this structure. + */ + struct fb_info fb; + struct display_switch *dispsw; + struct pci_dev *dev; + signed int currcon; + + struct { + u8 red, green, blue; + } palette[NR_RGB]; + + u_int palette_size; +}; + +struct par_info { + /* + * Hardware + */ + u16 chipID; + unsigned char __iomem *m_pMMIO; + char __iomem *m_pLFB; + char *m_pDPR; + char *m_pVPR; + char *m_pCPR; + + u_int width; + u_int height; + u_int hz; + u_long BaseAddressInVRAM; + u8 chipRevID; +}; + +struct vesa_mode_table { + char mode_index[6]; + u16 lfb_width; + u16 lfb_height; + u16 lfb_depth; +}; + + +static struct vesa_mode_table vesa_mode[] = +{ + {"0x301", 640, 480, 8}, + {"0x303", 800, 600, 8}, + {"0x305", 1024, 768, 8}, + {"0x307", 1280, 1024, 8}, + + {"0x311", 640, 480, 16}, + {"0x314", 800, 600, 16}, + {"0x317", 1024, 768, 16}, + {"0x31A", 1280, 1024, 16}, + + {"0x312", 640, 480, 24}, + {"0x315", 800, 600, 24}, + {"0x318", 1024, 768, 24}, + {"0x31B", 1280, 1024, 24}, + +}; + +char __iomem *smtc_RegBaseAddress; // Memory Map IO starting address +char __iomem *smtc_VRAMBaseAddress; // video memory starting address + + +char *smtc_2DBaseAddress; // 2D engine starting address +char *smtc_2Ddataport ; // 2D data port offset +short smtc_2Dacceleration = 0; //default no 2D acceleration + +static u32 colreg[17]; +static struct par_info hw; // hardware information + +#if defined(CONFIG_FB_SM7XX_DUALHEAD) + +static u32 colreg2[17]; +static struct par_info hw2; // hardware information for second display (CRT) +struct smtcfb_info smtcfb_info2; //fb_info for second display (CRT) + +#endif //CONFIG_FB_SM501_DUALHEAD + +u16 smtc_ChipIDs[] = { + 0x710, + 0x712, + 0x720 +}; + +int sm712be_flag; + +int numSMTCchipIDs = sizeof(smtc_ChipIDs)/sizeof(u16); + +void deWaitForNotBusy(void) +{ + unsigned long i = 0x1000000; + while (i--) + { + if ((smtc_seqr(0x16) & 0x18) == 0x10) + break; + } + smtc_de_busy = 0; +} + + +static void sm712_set_timing(struct smtcfb_info *sfb,struct par_info *ppar_info) +{ + int i=0,j=0; + u32 m_nScreenStride; + + smdbg("\nppar_info->width = %d ppar_info->height = %d sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n", + ppar_info->width, ppar_info->height, sfb->fb.var.bits_per_pixel , ppar_info->hz); + + for (j=0;j < numVGAModes;j++) { + if (VGAMode[j].mmSizeX == ppar_info->width && + VGAMode[j].mmSizeY == ppar_info->height && + VGAMode[j].bpp == sfb->fb.var.bits_per_pixel && + VGAMode[j].hz == ppar_info->hz) + { + smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY = %d VGAMode[j].bpp = %d VGAMode[j].hz=%d\n", + VGAMode[j].mmSizeX , VGAMode[j].mmSizeY, VGAMode[j].bpp, VGAMode[j].hz); + smdbg("VGAMode index=%d\n",j); + + smtc_mmiowb(0x0,0x3c6); + + smtc_seqw(0,0x1); + + smtc_mmiowb(VGAMode[j].Init_MISC,0x3c2); + + for (i=0;im_pVPR+0x0C); + writel(0x0,ppar_info->m_pVPR+0x40); + + // set data width + m_nScreenStride = (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64; + switch (sfb->fb.var.bits_per_pixel) + { + case 8: + writel(0x0,ppar_info->m_pVPR+0x0); + break; + case 16: + writel(0x00020000,ppar_info->m_pVPR+0x0); + break; + case 24: + writel(0x00040000,ppar_info->m_pVPR+0x0); + break; + case 32: + writel(0x00030000,ppar_info->m_pVPR+0x0); + break; + } + writel((u32)(((m_nScreenStride + 2) << 16) | m_nScreenStride),ppar_info->m_pVPR+0x10); + +} + + +static void sm712_setpalette(int regno, unsigned red, unsigned green, unsigned blue, struct fb_info *info) +{ + struct par_info *cur_par = (struct par_info*)info->par; + + if (cur_par->BaseAddressInVRAM) + smtc_seqw(0x66,(smtc_seqr(0x66) & 0xC3) | 0x20);//second display palette for dual head. Enable CRT RAM, 6-bit RAM + else + smtc_seqw(0x66,(smtc_seqr(0x66) & 0xC3) | 0x10); //primary display palette. Enable LCD RAM only, 6-bit RAM + smtc_mmiowb(regno, dac_reg); + smtc_mmiowb(red >> 10, dac_val); + smtc_mmiowb(green >> 10, dac_val); + smtc_mmiowb(blue >> 10, dac_val); +} + + +static void smtc_set_timing(struct smtcfb_info *sfb,struct par_info *ppar_info) +{ + switch (ppar_info->chipID) + { + case 0x710: + case 0x712: + case 0x720: + sm712_set_timing(sfb,ppar_info); + break; + } +} + +static struct fb_var_screeninfo smtcfb_var = { + .xres = 1024, + .yres = 600, + .xres_virtual = 1024, + .yres_virtual = 600, + .bits_per_pixel = 16, + .red = { 16, 8, 0 }, + .green = { 8, 8, 0 }, + .blue = { 0, 8, 0 }, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static struct fb_fix_screeninfo smtcfb_fix = { + .id = "sm712fb", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .line_length = 800*3, + .accel = FB_ACCEL_SMI_LYNX, +}; + +/* chan_to_field + * + * convert a colour value into a field position + * + * from pxafb.c +*/ + +static inline unsigned int chan_to_field(unsigned int chan, + struct fb_bitfield *bf) +{ + chan &= 0xffff; + chan >>= 16 - bf->length; + return chan << bf->offset; +} + +static int smtcfb_blank(int blank_mode, struct fb_info *info) +{ + /* clear DPMS setting */ + switch (blank_mode) { + case FB_BLANK_UNBLANK: + /* Screen On: HSync: On, VSync : On */ + smtc_seqw(0x01,(smtc_seqr(0x01)&(~0x20))); + smtc_seqw(0x6a,0x16); + smtc_seqw(0x6b,0x02); + smtc_seqw(0x21,(smtc_seqr(0x21)&(~0x77))); + smtc_seqw(0x22,(smtc_seqr(0x22)&(~0x30))); + smtc_seqw(0x23,(smtc_seqr(0x23)&(~0xc0))); + smtc_seqw(0x24,(smtc_seqr(0x24)|0x01)); + smtc_seqw(0x31,(smtc_seqr(0x31)|0x03)); + break; + case FB_BLANK_NORMAL: + /* Screen On: HSync: On, VSync : On */ + smtc_seqw(0x01,(smtc_seqr(0x01)&(~0x20))); + smtc_seqw(0x6a,0x16); + smtc_seqw(0x6b,0x02); + smtc_seqw(0x22,(smtc_seqr(0x22)&(~0x30))); + smtc_seqw(0x23,(smtc_seqr(0x23)&(~0xc0))); + smtc_seqw(0x24,(smtc_seqr(0x24)|0x01)); + smtc_seqw(0x31,(smtc_seqr(0x31)&(~0x07)|0x00)); + break; + case FB_BLANK_VSYNC_SUSPEND: + /* Screen On: HSync: On, VSync : Off */ + smtc_seqw(0x01,(smtc_seqr(0x01)|0x20)); + smtc_seqw(0x20,(smtc_seqr(0x20)&(~0xB0))); + smtc_seqw(0x6a,0x0c); + smtc_seqw(0x6b,0x02); + smtc_seqw(0x21,(smtc_seqr(0x21)|0x88)); + smtc_seqw(0x22,(smtc_seqr(0x22)&(~0x30)| 0x20)); + smtc_seqw(0x23,(smtc_seqr(0x23)&(~0xc0)| 0x20)); + smtc_seqw(0x24,(smtc_seqr(0x24)&(~0x01))); + smtc_seqw(0x31,(smtc_seqr(0x31)&(~0x07)|0x00)); + smtc_seqw(0x34,(smtc_seqr(0x34)|0x80)); + break; + case FB_BLANK_HSYNC_SUSPEND: + /* Screen On: HSync: Off, VSync : On */ + smtc_seqw(0x01,(smtc_seqr(0x01)|0x20)); + smtc_seqw(0x20,(smtc_seqr(0x20)&(~0xB0))); + smtc_seqw(0x6a,0x0c); + smtc_seqw(0x6b,0x02); + smtc_seqw(0x21,(smtc_seqr(0x21)|0x88)); + smtc_seqw(0x22,(smtc_seqr(0x22)&(~0x30)| 0x10)); + smtc_seqw(0x23,(smtc_seqr(0x23)&(~0xc0)| 0xD8)); + smtc_seqw(0x24,(smtc_seqr(0x24)&(~0x01))); + smtc_seqw(0x31,(smtc_seqr(0x31)&(~0x07)|0x00)); + smtc_seqw(0x34,(smtc_seqr(0x34)|0x80)); + break; + case FB_BLANK_POWERDOWN: + /* Screen On: HSync: Off, VSync : Off */ + smtc_seqw(0x01,(smtc_seqr(0x01)|0x20)); + smtc_seqw(0x20,(smtc_seqr(0x20)&(~0xB0))); + smtc_seqw(0x6a,0x0c); + smtc_seqw(0x6b,0x02); + smtc_seqw(0x21,(smtc_seqr(0x21)|0x88)); + smtc_seqw(0x22,(smtc_seqr(0x22)&(~0x30)| 0x30)); + smtc_seqw(0x23,(smtc_seqr(0x23)&(~0xc0)| 0xD8)); + smtc_seqw(0x24,(smtc_seqr(0x24)&(~0x01))); + smtc_seqw(0x31,(smtc_seqr(0x31)&(~0x07)|0x00)); + smtc_seqw(0x34,(smtc_seqr(0x34)|0x80)); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned trans, struct fb_info *info) +{ + struct smtcfb_info *sfb = (struct smtcfb_info *)info; + u32 *pal,val; + + if (regno > 255) + return 1; + + switch (sfb->fb.fix.visual) { + case FB_VISUAL_DIRECTCOLOR: + case FB_VISUAL_TRUECOLOR: + /* 16/32 bit true-colour, use pseuo-palette for 16 base color*/ + if (regno < 16) { + if (sfb->fb.var.bits_per_pixel==16) { + u32 *pal = sfb->fb.pseudo_palette; + val = chan_to_field(red, &sfb->fb.var.red); + val |= chan_to_field(green, &sfb->fb.var.green); + val |= chan_to_field(blue, &sfb->fb.var.blue); +#ifdef __BIG_ENDIAN + pal[regno] =( (red & 0xf800) >> 8) | ((green & 0xe000) >> 13) |((green & 0x1c00) << 3) | ((blue & 0xf800) >> 3); +#else + pal[regno] = val; +#endif + } + else{ + u32 *pal = sfb->fb.pseudo_palette; + val = chan_to_field(red, &sfb->fb.var.red); + val |= chan_to_field(green, &sfb->fb.var.green); + val |= chan_to_field(blue, &sfb->fb.var.blue); +#ifdef __BIG_ENDIAN + val = (val& 0xff00ff00>>8)|(val& 0x00ff00ff<<8); +#endif + pal[regno] = val; + } + } + break; + + case FB_VISUAL_PSEUDOCOLOR: + /* color depth 8 bit*/ + sm712_setpalette(regno,red,green,blue, info); + break; + + default: + return 1; /* unknown type */ + } + + return 0; + + +} + +static ssize_t +smtcfb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + unsigned long p = *ppos; + +// struct inode *inode = file->f_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; + int fbidx = iminor(inode); + struct fb_info *info = registered_fb[fbidx]; + + u32 *buffer, *dst; + u32 __iomem *src; + int c, i, cnt = 0, err = 0; + unsigned long total_size; + + if (!info || ! info->screen_base) + return -ENODEV; + + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; + + total_size = info->screen_size; + + if (total_size == 0) + total_size = info->fix.smem_len; + + if (p >= total_size) + return 0; + + if (count >= total_size) + count = total_size; + + if (count + p > total_size) + count = total_size - p; + + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, + GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + src = (u32 __iomem *) (info->screen_base + p); + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + while (count) { + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; + dst = buffer; + for (i = c >> 2; i--; ){ + *dst = fb_readl(src++); + *dst = (*dst & 0xff00ff00>>8)|(*dst & 0x00ff00ff<<8); + dst++; + } + if (c & 3) { + u8 *dst8 = (u8 *) dst; + u8 __iomem *src8 = (u8 __iomem *) src; + + for (i = c & 3; i--;){ + if (i&1){ + *dst8++ = fb_readb(++src8); + } + else{ + *dst8++ = fb_readb(--src8); + src8 +=2; + } + } + src = (u32 __iomem *) src8; + } + + if (copy_to_user(buf, buffer, c)) { + err = -EFAULT; + break; + } + *ppos += c; + buf += c; + cnt += c; + count -= c; + } + + kfree(buffer); + + return (err) ? err : cnt; +} + + + +static ssize_t +smtcfb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + unsigned long p = *ppos; +// struct inode *inode = file->f_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; + int fbidx = iminor(inode); + struct fb_info *info = registered_fb[fbidx]; + u32 *buffer, *src; + u32 __iomem *dst; + int c, i, cnt = 0, err = 0; + unsigned long total_size; + + if (!info || !info->screen_base) + return -ENODEV; + + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; + + + total_size = info->screen_size; + + if (total_size == 0) + total_size = info->fix.smem_len; + + if (p > total_size) + return -EFBIG; + + if (count > total_size) { + err = -EFBIG; + count = total_size; + } + + if (count + p > total_size) { + if (!err) + err = -ENOSPC; + + count = total_size - p; + } + + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, + GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + dst = (u32 __iomem *) (info->screen_base + p); + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + while (count) { + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; + src = buffer; + + if (copy_from_user(src, buf, c)) { + err = -EFAULT; + break; + } + + for (i = c >> 2; i--; ){ + fb_writel( (*src& 0xff00ff00>>8)|(*src& 0x00ff00ff<<8), dst++); + src++; + } + if (c & 3) { + u8 *src8 = (u8 *) src; + u8 __iomem *dst8 = (u8 __iomem *) dst; + + for (i = c & 3; i--; ){ + if (i&1){ + fb_writeb(*src8++, ++dst8); + } + else{ + fb_writeb(*src8++, --dst8); + dst8 +=2; + } + } + dst = (u32 __iomem *) dst8; + } + + *ppos += c; + buf += c; + cnt += c; + count -= c; + } + + kfree(buffer); + + return (cnt) ? cnt : err; +} + +#include "smtc2d.c" + +static void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) +{ + struct par_info *p = (struct par_info*)info->par; + + if (smtc_2Dacceleration) + { + if (!area->width || !area->height) + return; + + deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel, + area->dx, area->dy, area->width, area->height, + p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC); + + } + else + + cfb_copyarea(info, area); +} + +static void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) +{ + struct par_info *p = (struct par_info*)info->par; + + if (smtc_2Dacceleration) + { + if (!rect->width || !rect->height) + return; + if (info->var.bits_per_pixel>=24) + deFillRect(p->BaseAddressInVRAM, 0, rect->dx*3, rect->dy*3, rect->width*3, rect->height, rect->color); + else + deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy, rect->width, rect->height, rect->color); + } + else + + cfb_fillrect(info, rect); +} + +static void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image) +{ + struct par_info *p = (struct par_info*)info->par; + u32 size, bg_col = 0, fg_col = 0; + if (smtc_2Dacceleration) + { + if (image->depth == 1){ + if (smtc_de_busy) + deWaitForNotBusy(); + + switch (info->var.bits_per_pixel) { + case 8: + bg_col = image->bg_color; + fg_col = image->fg_color; + break; + case 16: + bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; + fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color]; + break; + case 32: + bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; + fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color]; + break; + } + deSystemMem2VideoMemMonoBlt( + image->data, /* pointer to start of source buffer in system memory */ + image->width/8, /* Pitch value (in bytes) of the source buffer, +ive means top down and -ive mean button up */ + 0, /* Mono data can start at any bit in a byte, this value should be 0 to 7 */ + p->BaseAddressInVRAM, /* Address of destination: offset in frame buffer */ + 0, /* Pitch value of destination surface in BYTE */ + 0, /* Color depth of destination surface */ + image->dx, + image->dy, /* Starting coordinate of destination surface */ + image->width, + image->height, /* width and height of rectange in pixel value */ + fg_col, /* Foreground color (corresponding to a 1 in the monochrome data */ + bg_col, /* Background color (corresponding to a 0 in the monochrome data */ + 0x0C) /* ROP value */; + } + else + cfb_imageblit(info, image); + } + else + cfb_imageblit(info, image); +} + +static struct fb_ops smtcfb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = smtc_setcolreg, + .fb_blank = smtcfb_blank, + .fb_fillrect = smtcfb_fillrect, + .fb_imageblit = smtcfb_imageblit, + .fb_copyarea = smtcfb_copyarea, +#ifdef __BIG_ENDIAN + .fb_read = smtcfb_read, + .fb_write = smtcfb_write, +#endif +}; + + +void smtcfb_setmode(struct smtcfb_info *sfb) +{ + switch (sfb->fb.var.bits_per_pixel) { + //kylin + case 32: + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length= sfb->fb.var.xres * 4; + sfb->fb.var.red.length = 8; + sfb->fb.var.green.length = 8; + sfb->fb.var.blue.length = 8; + sfb->fb.var.red.offset = 16; + sfb->fb.var.green.offset= 8; + sfb->fb.var.blue.offset = 0; + + break; + case 8: + sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; + sfb->fb.fix.line_length= sfb->fb.var.xres ; + sfb->fb.var.red.offset = 5; + sfb->fb.var.red.length = 3; + sfb->fb.var.green.offset= 2; + sfb->fb.var.green.length= 3; + sfb->fb.var.blue.offset = 0; + sfb->fb.var.blue.length = 2; + break; + case 24: + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length= sfb->fb.var.xres * 3; + sfb->fb.var.red.length = 8; + sfb->fb.var.green.length=8; + sfb->fb.var.blue.length = 8; + + + sfb->fb.var.red.offset = 16; + sfb->fb.var.green.offset= 8; + sfb->fb.var.blue.offset = 0; + + break; + case 16: + default: + sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + sfb->fb.fix.line_length= sfb->fb.var.xres * 2; + + sfb->fb.var.red.length = 5; + sfb->fb.var.green.length= 6; + sfb->fb.var.blue.length = 5; + + sfb->fb.var.red.offset = 11; + sfb->fb.var.green.offset= 5; + sfb->fb.var.blue.offset = 0; + + break; + } + + hw.width = sfb->fb.var.xres; + hw.height = sfb->fb.var.yres; + hw.hz = 60; + smtc_set_timing(sfb, &hw); + if (smtc_2Dacceleration) + { + printk("2D acceleration enabled!\n"); + deInit(sfb->fb.var.xres, sfb->fb.var.yres, sfb->fb.var.bits_per_pixel); /* Init smtc drawing engine */ + } +} + + +#if defined(CONFIG_FB_SM7XX_DUALHEAD) +void smtc_head2_init(struct smtcfb_info *sfb) +{ + smtcfb_info2 = *sfb; + smtcfb_info2.fb.pseudo_palette = &colreg2; + smtcfb_info2.fb.par = &hw2; + sprintf(smtcfb_info2.fb.fix.id, "sm%Xfb2", hw.chipID); + hw2.chipID = hw.chipID; + hw2.chipRevID = hw.chipRevID; + hw2.width = smtcfb_info2.fb.var.xres; + hw2.height = smtcfb_info2.fb.var.yres; + hw2.hz = 60; + hw2.m_pMMIO = smtc_RegBaseAddress; + hw2.BaseAddressInVRAM = smtcfb_info2.fb.fix.smem_len/2; /*hard code 2nd head starting from half VRAM size postion */ + smtcfb_info2.fb.screen_base = hw2.m_pLFB = smtc_VRAMBaseAddress+hw2.BaseAddressInVRAM; + +// sm712crtSetMode(hw2.width, hw2.height, 0, hw2.hz, smtcfb_info2.fb.var.bits_per_pixel); + writel(hw2.BaseAddressInVRAM >> 3,hw2.m_pVPR+0x10); +} +#endif + + +/* + * Alloc struct smtcfb_info and assign the default value + */ +static struct smtcfb_info * __devinit smtc_alloc_fb_info(struct pci_dev *dev, char *name) +{ + struct smtcfb_info *sfb; + + sfb = kmalloc(sizeof(struct smtcfb_info), GFP_KERNEL); + + if (!sfb) + return NULL; + + memset(sfb, 0, sizeof(struct smtcfb_info)); + + sfb->currcon = -1; + sfb->dev = dev; + + /*** Init sfb->fb with default value ***/ + sfb->fb.flags = FBINFO_FLAG_DEFAULT; + sfb->fb.fbops = &smtcfb_ops; + sfb->fb.var = smtcfb_var; + sfb->fb.fix = smtcfb_fix; + + strcpy(sfb->fb.fix.id, name); + + sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS; + sfb->fb.fix.type_aux = 0; + sfb->fb.fix.xpanstep = 0; + sfb->fb.fix.ypanstep = 0; + sfb->fb.fix.ywrapstep = 0; + sfb->fb.fix.accel = FB_ACCEL_SMI_LYNX; + + sfb->fb.var.nonstd = 0; + sfb->fb.var.activate = FB_ACTIVATE_NOW; + sfb->fb.var.height = -1; + sfb->fb.var.width = -1; + sfb->fb.var.accel_flags = FB_ACCELF_TEXT; /* text mode acceleration */ + sfb->fb.var.vmode = FB_VMODE_NONINTERLACED; + sfb->fb.par = &hw; + sfb->fb.pseudo_palette = colreg; + + return sfb; +} + +/* + * Unmap in the memory mapped IO registers + * + */ + +static void __devinit smtc_unmap_mmio(struct smtcfb_info *sfb) +{ + if (sfb && smtc_RegBaseAddress) + { + smtc_RegBaseAddress = NULL; + } +} + +/* + * Map in the screen memory + * + */ +static int __devinit smtc_map_smem(struct smtcfb_info *sfb, struct pci_dev *dev, u_long smem_len) +{ + if(sfb->fb.var.bits_per_pixel == 32) + { + #ifdef __BIG_ENDIAN + sfb->fb.fix.smem_start = pci_resource_start(dev, 0) + 0x800000; + #else + sfb->fb.fix.smem_start = pci_resource_start(dev, 0); + #endif + } + else + { + sfb->fb.fix.smem_start = pci_resource_start(dev, 0); + } + + sfb->fb.fix.smem_len = smem_len; + + sfb->fb.screen_base = smtc_VRAMBaseAddress; + + if (!sfb->fb.screen_base) + { + printk("%s: unable to map screen memory\n",sfb->fb.fix.id); + return -ENOMEM; + } + + return 0; +} + + +/* + * Unmap in the screen memory + * + */ +static void __devinit smtc_unmap_smem(struct smtcfb_info *sfb) +{ + if (sfb && sfb->fb.screen_base) + { + iounmap(sfb->fb.screen_base); + sfb->fb.screen_base = NULL; + } +} + +/* + * We need to wake up the LynxEM+, and make sure its in linear memory mode. + */ +static inline void __devinit sm7xx_init_hw(void) +{ + outb_p(0x18, 0x3c4); + outb_p(0x11, 0x3c5); +} + + + + +static void __devinit smtc_free_fb_info(struct smtcfb_info *sfb) +{ + if (sfb) { + fb_alloc_cmap(&sfb->fb.cmap, 0, 0); + kfree(sfb); + } +} + +static int __init smtcfb_init(void) +{ + struct smtcfb_info *sfb; + u_long smem_size= 0x00800000; //default 8MB + char name[16]; + int err; + unsigned long pFramebufferPhysical; + unsigned long pRegPhysical=0; + struct pci_dev *pdev = NULL; + + + + printk("Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n"); + + int i = 0; + + do { + pdev = pci_find_device(0x126f,smtc_ChipIDs[i], pdev); + if (pdev == NULL) + { + i++; + } + else + { + hw.chipID = smtc_ChipIDs[i]; + break; + } + } while (i< numSMTCchipIDs); + + err = pci_enable_device(pdev); // enable SMTC chip + + if (err) + { + return err; + } + err = -ENOMEM; + + sprintf(name, "sm%Xfb", hw.chipID); + + sfb = smtc_alloc_fb_info(pdev, name); + + if (!sfb) + { + goto failed; + } + + sm7xx_init_hw(); + +/*get mode parameter from screen_info*/ + if(screen_info.lfb_width != 0) + { + sfb->fb.var.xres = screen_info.lfb_width; + sfb->fb.var.yres = screen_info.lfb_height; + sfb->fb.var.bits_per_pixel = screen_info.lfb_depth; + } + else + { + sfb->fb.var.xres = SCREEN_X_RES; // default resolution 1024x600 16bit mode + sfb->fb.var.yres = SCREEN_Y_RES; + sfb->fb.var.bits_per_pixel = SCREEN_BPP; + } + + + smdbg("\nsfb->fb.var.bits_per_pixel = %d sm712be_flag = %d\n", sfb->fb.var.bits_per_pixel, sm712be_flag); +#ifdef __BIG_ENDIAN + if(sm712be_flag == 1 && sfb->fb.var.bits_per_pixel == 24) + { + sfb->fb.var.bits_per_pixel = screen_info.lfb_depth =32; + } +#endif + // Map address and memory detection + pFramebufferPhysical = pci_resource_start(pdev,0); + pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID); + + switch (hw.chipID) + { + + case 0x710: + case 0x712: + sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000; + sfb->fb.fix.mmio_len = 0x00400000; + smem_size = SM712_VIDEOMEMORYSIZE; +#ifdef __BIG_ENDIAN +// hw.m_pLFB = smtc_VRAMBaseAddress = ioremap(pFramebufferPhysical, 0x00a00000); + hw.m_pLFB = smtc_VRAMBaseAddress = ioremap(pFramebufferPhysical, 0x00c00000); +#else + hw.m_pLFB = smtc_VRAMBaseAddress = ioremap(pFramebufferPhysical, 0x00800000); +#endif + hw.m_pMMIO = smtc_RegBaseAddress = smtc_VRAMBaseAddress + 0x00700000; + smtc_2DBaseAddress = hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000; + smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712; + hw.m_pVPR = hw.m_pLFB + 0x0040c000; + if(sfb->fb.var.bits_per_pixel == 32) + { +#ifdef __BIG_ENDIAN + smtc_VRAMBaseAddress += 0x800000; + hw.m_pLFB += 0x800000; + printk("\nsmtc_VRAMBaseAddress=0x%X hw.m_pLFB=0x%X\n", smtc_VRAMBaseAddress, hw.m_pLFB); +#endif + } + if (!smtc_RegBaseAddress) + { + printk("%s: unable to map memory mapped IO\n",sfb->fb.fix.id); + return -ENOMEM; + } + +/* + smtc_seqw(0x62,0x7A); + smtc_seqw(0x6a,0x0c); + smtc_seqw(0x6b,0x02); + + //LynxEM+ memory detection + *(u32 *)(smtc_VRAMBaseAddress + 4) = 0xAA551133; + if (*(u32 *)(smtc_VRAMBaseAddress + 4) != 0xAA551133) + { + + smem_size = 0x00200000; + // Program the MCLK to 130 MHz + smtc_seqw(0x6a,0x12); + smtc_seqw(0x6b,0x02); + smtc_seqw(0x62,0x3e); + } +*/ + smtc_seqw(0x6a,0x16); //set MCLK = 14.31818 * (0x16 / 0x2) + smtc_seqw(0x6b,0x02); + smtc_seqw(0x62,0x3e); + smtc_seqw(0x17,0x20); //enable PCI burst + //enabel word swap + if(sfb->fb.var.bits_per_pixel == 32) + { +#ifdef __BIG_ENDIAN + smtc_seqw(0x17,0x30); +#endif + } + +#ifdef CONFIG_FB_SM7XX_ACCEL + smtc_2Dacceleration = 1; +#endif + + break; + + case 0x720: + sfb->fb.fix.mmio_start = pFramebufferPhysical; + sfb->fb.fix.mmio_len = 0x00200000; + smem_size = SM722_VIDEOMEMORYSIZE; + smtc_2DBaseAddress = hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000); + hw.m_pLFB = smtc_VRAMBaseAddress = smtc_2DBaseAddress + 0x00200000; + hw.m_pMMIO = smtc_RegBaseAddress = smtc_2DBaseAddress + 0x000c0000; + smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722; + hw.m_pVPR = smtc_2DBaseAddress + 0x800; + + smtc_seqw(0x62,0xff); + smtc_seqw(0x6a,0x0d); + smtc_seqw(0x6b,0x02); + smtc_2Dacceleration = 0; + break; + default: + printk("No valid Silicon Motion display chip was detected!\n"); + smtc_free_fb_info(sfb); + return err; + } + + + //can support 32 bpp + if (15 == sfb->fb.var.bits_per_pixel) + sfb->fb.var.bits_per_pixel = 16; + //else if (32==sfb->fb.var.bits_per_pixel) + // sfb->fb.var.bits_per_pixel = 24; + + sfb->fb.var.xres_virtual = sfb->fb.var.xres; + + sfb->fb.var.yres_virtual = sfb->fb.var.yres; + err = smtc_map_smem(sfb, pdev, smem_size); + if (err) + { + goto failed; + } + + smtcfb_setmode(sfb); + hw.BaseAddressInVRAM = 0; //Primary display starting from 0 postion + sfb->fb.par = &hw; + + err = register_framebuffer(&sfb->fb); + if (err < 0) + { + goto failed; + } + + printk("Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete.\n", + hw.chipID, hw.chipRevID, sfb->fb.var.xres, sfb->fb.var.yres, sfb->fb.var.bits_per_pixel); + +#if defined(CONFIG_FB_SM7XX_DUALHEAD) + smtc_head2_init(sfb); + err = register_framebuffer(&smtcfb_info2.fb); + + if (err < 0) + { + printk("Silicon Motion, Inc. second head init fail\n"); + goto failed; //if second head display fails, also fails the primary display + } + + printk("Silicon Motion SM%X Rev%X secondary display mode %dx%d-%d Init Complete.\n", + hw.chipID, hw.chipRevID, hw2.width, hw2.height, smtcfb_info2.fb.var.bits_per_pixel); + +#endif + + return 0; + +failed: + printk("Silicon Motion, Inc. primary display init fail\n"); + smtc_unmap_smem(sfb); + smtc_unmap_mmio(sfb); + smtc_free_fb_info(sfb); + + return err; +} + +static void __exit smtcfb_exit(void){} + +module_init(smtcfb_init); +module_exit(smtcfb_exit); + + +//#ifndef MODULE +/** + * sm712be_setup - process command line options + * @options: string of options + * Returns zero. + * +*/ +static int __init sm712be_setup(char *options) +{ + int retval = 0; + sm712be_flag = 0; + if (!options || !*options) + { + retval = 1; + smdbg("\n No sm712be parameter\n", __LINE__); + } + if (!retval && strstr(options, "enable")) + { + sm712be_flag = 1; + } + smdbg("\nsm712be_setup = %s sm712be_flag = %d\n", options, sm712be_flag); + return 1; +} + +__setup("sm712be=", sm712be_setup); + +//#endif + +#ifdef __BIG_ENDIAN +/** + * sm712vga_setup - process command line options, get vga parameter + * @options: string of options + * Returns zero. + * +*/ +static int __init sm712vga_setup(char *options) +{ + int retval = 0; + int index ; + sm712be_flag = 0; + + if (!options || !*options) + { + retval = 1; + smdbg("\n No vga parameter\n", __LINE__); + } + + screen_info.lfb_width = 0; + screen_info.lfb_height = 0; + screen_info.lfb_depth = 0; + + for (index = 0; index < (sizeof(vesa_mode) / sizeof(struct vesa_mode_table)); index++) + { + if(strstr(options, vesa_mode[index].mode_index)) + { + screen_info.lfb_width = vesa_mode[index].lfb_width; + screen_info.lfb_height = vesa_mode[index].lfb_height; + screen_info.lfb_depth = vesa_mode[index].lfb_depth; + } + } + smdbg("\nsm712vga_setup = %s\n", options); + return 1; +} + +__setup("vga=", sm712vga_setup); +#endif + +MODULE_AUTHOR("Siliconmotion "); +MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/video/smi/smtcfb.h b/drivers/video/smi/smtcfb.h new file mode 100755 index 0000000..9933b62 --- /dev/null +++ b/drivers/video/smi/smtcfb.h @@ -0,0 +1,795 @@ +/* + * linux/drivers/video/smtcfb.h -- Silicon Motion SM501 and SM7xx frame buffer device + * + * Copyright (C) 2006 Silicon Motion Technology Corp. + * Ge Wang, gewang@siliconmotion.com + * Boyod boyod.yang@siliconmotion.com.cn + * + * This file is subject to the terms and conditions of the GNU General Public + * License version 2 or later. See the file COPYING in the main directory of + * this archive for more details. + */ + +#define SMTC_LINUX_FB_VERSION "version 0.11.2619.21.01 July 27, 2008" + +#define NR_PALETTE 256 +#define NR_RGB 2 + +#define FB_ACCEL_SMI_LYNX 88 + + + +#ifdef __BIG_ENDIAN +#define PC_VGA 0 +#else +#define PC_VGA 1 +#endif + +#define SCREEN_X_RES 1024 +#define SCREEN_Y_RES 600 +#define SCREEN_BPP 16 + +#ifndef FIELD_OFFSET +#define FIELD_OFSFET(type, field) ((unsigned long) (PUCHAR) &(((type *)0)->field)) +#endif + +#define SM712_VIDEOMEMORYSIZE 0x00400000 /*Assume SM712 graphics chip has 4MB VRAM */ +#define SM722_VIDEOMEMORYSIZE 0x00800000 /*Assume SM722 graphics chip has 8MB VRAM */ + +#define dac_reg (0x3c8) +#define dac_val (0x3c9) + +extern char *smtc_RegBaseAddress; +#define smtc_mmiowb(dat,reg) writeb(dat, smtc_RegBaseAddress + reg) +#define smtc_mmioww(dat,reg) writew(dat, smtc_RegBaseAddress + reg) +#define smtc_mmiowl(dat,reg) writel(dat, smtc_RegBaseAddress + reg) + +#define smtc_mmiorb(reg) readb(smtc_RegBaseAddress + reg) +#define smtc_mmiorw(reg) readw(smtc_RegBaseAddress + reg) +#define smtc_mmiorl(reg) readl(smtc_RegBaseAddress + reg) + +#define SIZE_SR00_SR04 (0x04 - 0x00 + 1) +#define SIZE_SR10_SR24 (0x24 - 0x10 + 1) +#define SIZE_SR30_SR75 (0x75 - 0x30 + 1) +#define SIZE_SR80_SR93 (0x93 - 0x80 + 1) +#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1) +#define SIZE_GR00_GR08 (0x08 - 0x00 + 1) +#define SIZE_AR00_AR14 (0x14 - 0x00 + 1) +#define SIZE_CR00_CR18 (0x18 - 0x00 + 1) +#define SIZE_CR30_CR4D (0x4D - 0x30 + 1) +#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1) +#define SIZE_VPR (0x6C + 1) +#define SIZE_DPR (0x44 + 1) + + +static inline void smtc_crtcw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3d4); + smtc_mmiowb(val, 0x3d5); +} + +static inline unsigned int smtc_crtcr(int reg) +{ + smtc_mmiowb(reg, 0x3d4); + return smtc_mmiorb(0x3d5); +} + +static inline void smtc_grphw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3ce); + smtc_mmiowb(val, 0x3cf); +} + +static inline unsigned int smtc_grphr(int reg) +{ + smtc_mmiowb(reg, 0x3ce); + return smtc_mmiorb(0x3cf); +} + +static inline void smtc_attrw(int reg, int val) +{ + smtc_mmiorb(0x3da); + smtc_mmiowb(reg, 0x3c0); + smtc_mmiorb(0x3c1); + smtc_mmiowb(val, 0x3c0); +} + +static inline void smtc_seqw(int reg, int val) +{ + smtc_mmiowb(reg, 0x3c4); + smtc_mmiowb(val, 0x3c5); +} + +static inline unsigned int smtc_seqr(int reg) +{ + smtc_mmiowb(reg, 0x3c4); + return smtc_mmiorb(0x3c5); +} + +// The next structure holds all information relevant for a specific video mode. + + +struct ModeInit +{ + int mmSizeX; + int mmSizeY; + int bpp; + int hz; + unsigned char Init_MISC; + unsigned char Init_SR00_SR04[SIZE_SR00_SR04]; + unsigned char Init_SR10_SR24[SIZE_SR10_SR24]; + unsigned char Init_SR30_SR75[SIZE_SR30_SR75]; + unsigned char Init_SR80_SR93[SIZE_SR80_SR93]; + unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF]; + unsigned char Init_GR00_GR08[SIZE_GR00_GR08]; + unsigned char Init_AR00_AR14[SIZE_AR00_AR14]; + unsigned char Init_CR00_CR18[SIZE_CR00_CR18]; + unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D]; + unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7]; +}; + + + +/********************************************************************** + SM712 Mode table. + **********************************************************************/ +struct ModeInit VGAMode[] = +{ + { + /* mode#0: 640 x 480 16Bpp 60Hz */ + 640, 480, 16, 60, + /* Init_MISC */ + 0xE3, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, + }, + }, + { + /* mode#1: 640 x 480 24Bpp 60Hz */ + 640, 480, 24, 60, + /* Init_MISC */ + 0xE3, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, + }, + }, + { + /* mode#0: 640 x 480 32Bpp 60Hz */ + 640, 480, 32, 60, + /* Init_MISC */ + 0xE3, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, + 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, + 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, + 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, + 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, + 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, + 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, + 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, + }, + }, + + {/* mode#2: 800 x 600 16Bpp 60Hz */ + 800, 600, 16, 60, + /* Init_MISC */ + 0x2B, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, + 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, + 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, + }, + }, + {/* mode#3: 800 x 600 24Bpp 60Hz */ + 800,600,24,60, + 0x2B, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36, + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, + 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, + 0x02, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36, + 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, + }, + }, + {/* mode#7: 800 x 600 32Bpp 60Hz */ + 800, 600, 32, 60, + /* Init_MISC */ + 0x2B, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, + 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, + 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, + 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, + 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, + 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, + 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, + 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, + 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, + }, + }, + + { /* mode#4: 1024 x 600 16Bpp 60Hz We use 1024x768 table to light 1024x600 panel for lemote*/ + 1024,600,16,60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x00, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20, + 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x00, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22, + 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02, + 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00, + 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + { /* mode#5: 1024 x 768 24Bpp 60Hz */ + 1024,768,24,60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x30, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + { /* mode#4: 1024 x 768 32Bpp 60Hz */ + 1024,768,32,60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x32, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, + 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + { /* mode#6: 320 x 240 16Bpp 60Hz */ + 320,240,16,60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x32, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, + 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, + + { /* mode#8: 320 x 240 32Bpp 60Hz */ + 320,240,32,60, + /* Init_MISC */ + 0xEB, + { /* Init_SR0_SR4 */ + 0x03, 0x01, 0x0F, 0x03, 0x0E, + }, + { /* Init_SR10_SR24 */ + 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, + 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC4, 0x32, 0x02, 0x01, 0x01, + }, + { /* Init_SR30_SR75 */ + 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, + 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, + 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, + 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, + 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, + 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, + 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, + 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, + }, + { /* Init_SR80_SR93 */ + 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, + 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, + 0x00, 0x00, 0x00, 0x00, + }, + { /* Init_SRA0_SRAF */ + 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, + 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, + }, + { /* Init_GR00_GR08 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, + 0xFF, + }, + { /* Init_AR00_AR14 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x41, 0x00, 0x0F, 0x00, 0x00, + }, + { /* Init_CR00_CR18 */ + 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, + 0xFF, + }, + { /* Init_CR30_CR4D */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, + 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, + 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, + 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, + }, + { /* Init_CR90_CRA7 */ + 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, + 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, + }, + }, +}; + +#define numVGAModes sizeof(VGAMode)/sizeof(struct ModeInit) + diff --git a/include/asm-mips/clock.h b/include/asm-mips/clock.h new file mode 100644 index 0000000..9442f3b --- /dev/null +++ b/include/asm-mips/clock.h @@ -0,0 +1,62 @@ +#ifndef __ASM_MIPS_CLOCK_H +#define __ASM_MIPS_CLOCK_H + +#include +#include +#include +#include + +struct clk; + +struct clk_ops { + void (*init)(struct clk *clk); + void (*enable)(struct clk *clk); + void (*disable)(struct clk *clk); + void (*recalc)(struct clk *clk); + int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); + long (*round_rate)(struct clk *clk, unsigned long rate); +}; + +struct clk { + struct list_head node; + const char *name; + int id; + struct module *owner; + + struct clk *parent; + struct clk_ops *ops; + + struct kref kref; + + unsigned long rate; + unsigned long flags; +}; + +#define CLK_ALWAYS_ENABLED (1 << 0) +#define CLK_RATE_PROPAGATES (1 << 1) + +/* Should be defined by processor-specific code */ +void arch_init_clk_ops(struct clk_ops **, int type); + +int clk_init(void); + +int __clk_enable(struct clk *); +void __clk_disable(struct clk *); + +void clk_recalc_rate(struct clk *); + +int clk_register(struct clk *); +void clk_unregister(struct clk *); + +/* the exported API, in addition to clk_set_rate */ +/** + * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter + * @clk: clock source + * @rate: desired clock rate in Hz + * @algo_id: algorithm id to be passed down to ops->set_rate + * + * Returns success (0) or negative errno. + */ +int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id); + +#endif /* __ASM_MIPS_CLOCK_H */ diff --git a/include/asm-mips/mach-lemote/dma-coherence.h b/include/asm-mips/mach-lemote/dma-coherence.h index 7e91477..bf3604a 100644 --- a/include/asm-mips/mach-lemote/dma-coherence.h +++ b/include/asm-mips/mach-lemote/dma-coherence.h @@ -27,7 +27,18 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr) { +#ifdef CONFIG_64BIT +#ifdef CONFIG_MACH_LM2F + if(dma_addr > 0x8fffffff) + return dma_addr; + else + return dma_addr & 0x0fffffff; +#else return dma_addr & 0x7fffffff; +#endif +#else + return dma_addr & 0x7fffffff; +#endif } static inline void plat_unmap_dma_mem(dma_addr_t dma_addr) diff --git a/include/asm-mips/mc146818rtc.h b/include/asm-mips/mc146818rtc.h index 68b4da6..137e0f1 100644 --- a/include/asm-mips/mc146818rtc.h +++ b/include/asm-mips/mc146818rtc.h @@ -13,4 +13,12 @@ #include +#define lock_cmos_prefix(reg) do {} while (0) +#define lock_cmos_suffix(reg) do {} while (0) +#define lock_cmos(reg) +#define unlock_cmos() +#define do_i_have_lock_cmos() 0 +#define current_lock_cmos_reg() 0 + + #endif /* _ASM_MC146818RTC_H */ diff --git a/include/asm-mips/mips-boards/bonito64.h b/include/asm-mips/mips-boards/bonito64.h index a0f04bb..9e70093 100644 --- a/include/asm-mips/mips-boards/bonito64.h +++ b/include/asm-mips/mips-boards/bonito64.h @@ -26,7 +26,7 @@ /* offsets from base register */ #define BONITO(x) (x) -#elif defined(CONFIG_LEMOTE_FULONG) +#elif defined(CONFIG_LEMOTE_FULONG) ||defined(CONFIG_LEMOTE_FULONG2F) ||defined(CONFIG_LEMOTE_2FNOTEBOOK) #define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x))) #define BONITO_IRQ_BASE 32 diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index fe7a88e..4691c02 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -157,7 +157,17 @@ typedef struct { unsigned long pgprot; } pgprot_t; #ifdef CONFIG_FLATMEM +#ifdef CONFIG_MACH_LM2F +#define pfn_valid(pfn) \ +({ \ + (max_mapnr > (0x10000000 >> PAGE_SHIFT)) ? \ + (((pfn) >= ARCH_PFN_OFFSET && (pfn) < (0x10000000 >> PAGE_SHIFT)) || \ + (((pfn) >=(0x90000000 >> PAGE_SHIFT) && (pfn) < max_mapnr))) : \ + ((pfn) >= ARCH_PFN_OFFSET && (pfn) < max_mapnr); \ + }) +#else #define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < max_mapnr) +#endif #elif defined(CONFIG_SPARSEMEM) diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 4c37c4e..887d44f 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h @@ -117,6 +117,24 @@ .endm #else .macro get_saved_sp /* Uniprocessor variation */ +#ifdef CONFIG_CPU_LOONGSON2 + move k0,ra + jal 2008f + nop + 2008: + jal 2008f + nop + 2008: + jal 2008f + nop + 2008: + jal 2008f + nop + 2008: + move ra,k0 + li k0,3 + mtc0 k0,$22 +#endif #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(kernelsp) #else diff --git a/include/asm-mips/suspend.h b/include/asm-mips/suspend.h index 2562f8f..06763c1 100644 --- a/include/asm-mips/suspend.h +++ b/include/asm-mips/suspend.h @@ -1,6 +1,11 @@ #ifndef __ASM_SUSPEND_H #define __ASM_SUSPEND_H +#include /* Somewhen... Maybe :-) */ +static inline int arch_prepare_suspend(void) +{ + return 0; +} #endif /* __ASM_SUSPEND_H */ diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h index d3bd5c5..40ac337 100644 --- a/include/asm-mips/time.h +++ b/include/asm-mips/time.h @@ -63,7 +63,7 @@ static inline int mips_clockevent_init(void) /* * Initialize the count register as a clocksource */ -#ifdef CONFIG_CEVT_R4K +#ifdef CONFIG_CSRC_R4K extern int init_mips_clocksource(void); #else static inline int init_mips_clocksource(void) @@ -76,4 +76,8 @@ extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock); extern void clockevent_set_clock(struct clock_event_device *cd, unsigned int clock); +#define get_wallclock() mach_get_cmos_time() +#define set_wallclock(x) mach_set_rtc_mmss(x) + + #endif /* _ASM_TIME_H */ diff --git a/include/linux/console_splash.h b/include/linux/console_splash.h new file mode 100644 index 0000000..c448dd2 --- /dev/null +++ b/include/linux/console_splash.h @@ -0,0 +1,13 @@ +#ifndef _LINUX_CONSOLE_SPLASH_H_ +#define _LINUX_CONSOLE_SPLASH_H_ 1 + +/* A structure used by the framebuffer splash code (drivers/video/fbsplash.c) */ +struct vc_splash { + __u8 bg_color; /* The color that is to be treated as transparent */ + __u8 state; /* Current splash state: 0 = off, 1 = on */ + __u16 tx, ty; /* Top left corner coordinates of the text field */ + __u16 twidth, theight; /* Width and height of the text field */ + char* theme; +}; + +#endif diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index b03f80a..2c9e3cf 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h @@ -19,6 +19,7 @@ struct vt_struct; #define NPAR 16 +#include struct vc_data { unsigned short vc_num; /* Console number */ @@ -107,6 +108,8 @@ struct vc_data { struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */ unsigned long vc_uni_pagedir; unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ + + struct vc_splash vc_splash; /* additional information is in vt_kern.h */ }; diff --git a/include/linux/fb.h b/include/linux/fb.h index 531ccd5..c8fa7f4 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -10,6 +10,13 @@ struct dentry; #define FB_MAX 32 /* sufficient for now */ +struct fb_splash_iowrapper +{ + unsigned short vc; /* Virtual console */ + unsigned char origin; /* Point of origin of the request */ + void *data; +}; + /* ioctls 0x46 is 'F' */ #define FBIOGET_VSCREENINFO 0x4600 @@ -37,7 +44,15 @@ struct dentry; #define FBIOGET_HWCINFO 0x4616 #define FBIOPUT_MODEINFO 0x4617 #define FBIOGET_DISPINFO 0x4618 +#define FBIOSPLASH_SETCFG _IOWR('F', 0x19, struct fb_splash_iowrapper) +#define FBIOSPLASH_GETCFG _IOR('F', 0x1A, struct fb_splash_iowrapper) +#define FBIOSPLASH_SETSTATE _IOWR('F', 0x1B, struct fb_splash_iowrapper) +#define FBIOSPLASH_GETSTATE _IOR('F', 0x1C, struct fb_splash_iowrapper) +#define FBIOSPLASH_SETPIC _IOWR('F', 0x1D, struct fb_splash_iowrapper) +#define FB_SPLASH_THEME_LEN 128 /* Maximum lenght of a theme name */ +#define FB_SPLASH_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */ +#define FB_SPLASH_IO_ORIG_USER 1 /* User ioctl origin */ #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ @@ -847,6 +862,9 @@ struct fb_info { #define FBINFO_STATE_SUSPENDED 1 u32 state; /* Hardware state i.e suspend */ void *fbcon_par; /* fbcon use-only private area */ + + struct fb_image splash; + /* From here on everything is device dependent */ void *par; }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f1624b3..e545fb1 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1632,6 +1632,10 @@ #define PCI_VENDOR_ID_SATSAGEM 0x1267 #define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016 +#define PCI_VENDOR_ID_SILICON_MOTION 0x126f +#define PCI_DEVICE_ID_SM501_VOYAGER_GX_REV_AA 0x0501 +#define PCI_DEVICE_ID_SM501_VOYAGER_GX_REV_B 0x0510 + #define PCI_VENDOR_ID_ENSONIQ 0x1274 #define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880 #define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000 diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 2ce8207..6971a19 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -1,7 +1,7 @@ #ifndef _LINUX_SUSPEND_H #define _LINUX_SUSPEND_H -#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64) +#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64) || defined(CONFIG_MIPS) #include #endif #include diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index d0437f3..0e06c9c 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -163,6 +163,7 @@ enum KERN_MAX_LOCK_DEPTH=74, KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */ KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */ + KERN_FBSPLASH=77, /* string: path to fbsplash helper */ }; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 50ec088..53eaeaf 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -114,6 +114,9 @@ static int ngroups_max = NGROUPS_MAX; #ifdef CONFIG_MODULES extern char modprobe_path[]; #endif +#ifdef CONFIG_FB_SPLASH +extern char fbsplash_path[]; +#endif #ifdef CONFIG_CHR_DEV_SG extern int sg_big_buff; #endif @@ -500,6 +503,17 @@ static struct ctl_table kern_table[] = { .strategy = &sysctl_string, }, #endif +#ifdef CONFIG_FB_SPLASH + { + .ctl_name = KERN_FBSPLASH, + .procname = "fbsplash", + .data = &fbsplash_path, + .maxlen = KMOD_PATH_LEN, + .mode = 0644, + .proc_handler = &proc_dostring, + .strategy = &sysctl_string, + }, +#endif #ifdef CONFIG_CHR_DEV_SG { .ctl_name = KERN_SG_BIG_BUFF, diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index c487025..b5a35e8 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3107,7 +3107,11 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area, return VM_FAULT_SIGBUS; } else { vaddr = runtime->dma_area + offset; +#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + page = virt_to_page(CAC_ADDR(vaddr)); +#else page = virt_to_page(vaddr); +#endif } get_page(page); vmf->page = page; @@ -3222,6 +3226,12 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) substream = pcm_file->substream; snd_assert(substream != NULL, return -ENXIO); +#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + /* all mmap using uncached mode */ + area->vm_page_prot = pgprot_noncached(area->vm_page_prot); + area->vm_flags |= ( VM_RESERVED | VM_IO); +#endif + offset = area->vm_pgoff << PAGE_SHIFT; switch (offset) { case SNDRV_PCM_MMAP_OFFSET_STATUS: diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c index cefd228..dcefd94 100644 --- a/sound/core/sgbuf.c +++ b/sound/core/sgbuf.c @@ -91,12 +91,20 @@ void *snd_malloc_sgbuf_pages(struct device *device, } sgbuf->table[i].buf = tmpb.area; sgbuf->table[i].addr = tmpb.addr; +#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + sgbuf->page_table[i] = virt_to_page(CAC_ADDR(tmpb.area)); +#else sgbuf->page_table[i] = virt_to_page(tmpb.area); +#endif sgbuf->pages++; } sgbuf->size = size; +#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP | VM_IO, pgprot_noncached(PAGE_KERNEL)); +#else dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, PAGE_KERNEL); +#endif if (! dmab->area) goto _failed; return dmab->area; diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 31f52d3..0b7913c 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -258,7 +258,7 @@ config SND_CS5530 config SND_CS5535AUDIO tristate "CS5535/CS5536 Audio" - depends on X86 && !X86_64 + depends on SND select SND_PCM select SND_AC97_CODEC help diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 8c49a00..cbbb0b2 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -518,11 +518,24 @@ static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, int mask = (kcontrol->private_value >> 16) & 0xff; int shift = (kcontrol->private_value >> 8) & 0x0f; int rshift = (kcontrol->private_value >> 12) & 0x0f; +#if 1 + int max = mask; +#endif uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = shift == rshift ? 1 : 2; uinfo->value.integer.min = 0; +#if 1 + { + int reg = kcontrol->private_value & 0xff; + if (reg == AC97_MASTER && mask != 1) { + max = (mask * 90) /100; + } + } + uinfo->value.integer.max = max; +#else uinfo->value.integer.max = mask; +#endif return 0; } @@ -606,8 +619,13 @@ AC97_SINGLE("PC Speaker Playback Switch", AC97_PC_BEEP, 15, 1, 1), AC97_SINGLE("PC Speaker Playback Volume", AC97_PC_BEEP, 1, 15, 1) }; +#ifndef __no_noise_on_play_mic__ +static const struct snd_kcontrol_new snd_ac97_controls_mic_boost = + AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 5, 1, 0); +#else static const struct snd_kcontrol_new snd_ac97_controls_mic_boost = AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 6, 1, 0); +#endif static const char* std_rec_sel[] = {"Mic", "CD", "Video", "Aux", "Line", "Mix", "Mix Mono", "Phone"}; @@ -1309,6 +1327,9 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97) unsigned int idx; unsigned char max; +#ifndef __no_noise_on_play_mic__ + ac97->flags |= AC97_HAS_NO_PHONE|AC97_HAS_NO_PC_BEEP; +#endif /* build master controls */ /* AD claims to remove this control from AD1887, although spec v2.2 does not allow this */ if (snd_ac97_try_volume_mix(ac97, AC97_MASTER)) { @@ -1369,12 +1390,14 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97) return err; } +#if 0 /* build master mono controls */ if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_MONO)) { if ((err = snd_ac97_cmix_new(card, "Master Mono Playback", AC97_MASTER_MONO, 0, ac97)) < 0) return err; } +#endif /* build master tone controls */ if (!(ac97->flags & AC97_HAS_NO_TONE)) {