Commit ff914453 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/rmk/linux-2.6-arm

* master.kernel.org:/home/rmk/linux-2.6-arm: (22 commits)
  [ARM] 3559/1: S3C2442: core and serial port
  [ARM] 3557/1: S3C24XX: centralise and cleanup uart registration
  [ARM] 3558/1: SMDK24XX: LED platform devices
  [ARM] 3534/1: add spi support to lubbock platform
  [ARM] 3554/1: ARM: Fix dyntick locking
  [ARM] 3553/1: S3C24XX: earlier print of cpu idcode info
  [ARM] 3552/1: S3C24XX: Move VA of GPIO for low-level debug
  [ARM] 3551/1: S3C24XX: PM code failes to compile with CONFIG_DCACHE_WRITETHROUGH
  [ARM] 3550/1: OSIRIS: fix serial port map for 1:1
  [ARM] 3548/1: Fix the ARMv6 CPU id in compressed/head.S
  [ARM] 3335/1: Old-abi Thumb sys_syscall broken
  [ARM] 3467/1: [3/3] Support for Philips PNX4008 platform: defconfig
  [ARM] 3466/1: [2/3] Support for Philips PNX4008 platform: chip support
  [ARM] 3465/1: [1/3] Support for Philips PNX4008 platform: headers
  [ARM] 3407/1: lpd7x: documetation update
  [ARM] 3406/1: lpd7x: compilation fix for smc91x
  [ARM] 3405/1: lpd7a40x: CPLD ssp driver
  [ARM] 3404/1: lpd7a40x: AMBA CLCD support
  [ARM] 3403/1: lpd7a40x: updated default configurations
  [ARM] 3402/1: lpd7a40x: serial driver bug fix
  ...
parents 25f42b6a 96ce2385
README on the ADC/Touchscreen Controller
========================================
The LH79524 and LH7A404 include a built-in Analog to Digital
controller (ADC) that is used to process input from a touchscreen.
The driver only implements a four-wire touch panel protocol.
The touchscreen driver is maintenance free except for the pen-down or
touch threshold. Some resistive displays and board combinations may
require tuning of this threshold. The driver exposes some of it's
internal state in the sys filesystem. If the kernel is configured
with it, CONFIG_SYSFS, and sysfs is mounted at /sys, there will be a
directory
/sys/devices/platform/adc-lh7.0
containing these files.
-r--r--r-- 1 root root 4096 Jan 1 00:00 samples
-rw-r--r-- 1 root root 4096 Jan 1 00:00 threshold
-r--r--r-- 1 root root 4096 Jan 1 00:00 threshold_range
The threshold is the current touch threshold. It defaults to 750 on
most targets.
# cat threshold
750
The threshold_range contains the range of valid values for the
threshold. Values outside of this range will be silently ignored.
# cat threshold_range
0 1023
To change the threshold, write a value to the threshold file.
# echo 500 > threshold
# cat threshold
500
The samples file contains the most recently sampled values from the
ADC. There are 12. Below are typical of the last sampled values when
the pen has been released. The first two and last two samples are for
detecting whether or not the pen is down. The third through sixth are
X coordinate samples. The seventh through tenth are Y coordinate
samples.
# cat samples
1023 1023 0 0 0 0 530 529 530 529 1023 1023
To determine a reasonable threshold, press on the touch panel with an
appropriate stylus and read the values from samples.
# cat samples
1023 676 92 103 101 102 855 919 922 922 1023 679
The first and eleventh samples are discarded. Thus, the important
values are the second and twelfth which are used to determine if the
pen is down. When both are below the threshold, the driver registers
that the pen is down. When either is above the threshold, it
registers then pen is up.
README on the LCD Panels
========================
Configuration options for several LCD panels, available from Logic PD,
are included in the kernel source. This README will help you
understand the configuration data and give you some guidance for
adding support for other panels if you wish.
lcd-panels.h
------------
There is no way, at present, to detect which panel is attached to the
system at runtime. Thus the kernel configuration is static. The file
arch/arm/mach-ld7a40x/lcd-panels.h (or similar) defines all of the
panel specific parameters.
It should be possible for this data to be shared among several device
families. The current layout may be insufficiently general, but it is
amenable to improvement.
PIXEL_CLOCK
-----------
The panel data sheets will give a range of acceptable pixel clocks.
The fundamental LCDCLK input frequency is divided down by a PCD
constant in field '.tim2'. It may happen that it is impossible to set
the pixel clock within this range. A clock which is too slow will
tend to flicker. For the highest quality image, set the clock as high
as possible.
MARGINS
-------
These values may be difficult to glean from the panel data sheet. In
the case of the Sharp panels, the upper margin is explicitly called
out as a specific number of lines from the top of the frame. The
other values may not matter as much as the panels tend to
automatically center the image.
Sync Sense
----------
The sense of the hsync and vsync pulses may be called out in the data
sheet. On one panel, the sense of these pulses determine the height
of the visible region on the panel. Most of the Sharp panels use
negative sense sync pulses set by the TIM2_IHS and TIM2_IVS bits in
'.tim2'.
Pel Layout
----------
The Sharp color TFT panels are all configured for 16 bit direct color
modes. The amba-lcd driver sets the pel mode to 565 for 5 bits of
each red and blue and 6 bits of green.
...@@ -270,6 +270,11 @@ config ARCH_AT91RM9200 ...@@ -270,6 +270,11 @@ config ARCH_AT91RM9200
Say Y here if you intend to run this kernel on an Atmel Say Y here if you intend to run this kernel on an Atmel
AT91RM9200-based board. AT91RM9200-based board.
config ARCH_PNX4008
bool "Philips Nexperia PNX4008 Mobile"
help
This enables support for Philips PNX4008 mobile platform.
endchoice endchoice
source "arch/arm/mach-clps711x/Kconfig" source "arch/arm/mach-clps711x/Kconfig"
......
...@@ -116,6 +116,7 @@ endif ...@@ -116,6 +116,7 @@ endif
machine-$(CONFIG_ARCH_REALVIEW) := realview machine-$(CONFIG_ARCH_REALVIEW) := realview
machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200 machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200
machine-$(CONFIG_ARCH_EP93XX) := ep93xx machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_PNX4008) := pnx4008
ifeq ($(CONFIG_ARCH_EBSA110),y) ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line. # This is what happens if you forget the IOCS16 line.
......
...@@ -605,8 +605,8 @@ proc_types: ...@@ -605,8 +605,8 @@ proc_types:
b __armv4_mmu_cache_off b __armv4_mmu_cache_off
b __armv4_mmu_cache_flush b __armv4_mmu_cache_flush
.word 0x00070000 @ ARMv6 .word 0x0007b000 @ ARMv6
.word 0x000f0000 .word 0x0007f000
b __armv4_mmu_cache_on b __armv4_mmu_cache_on
b __armv4_mmu_cache_off b __armv4_mmu_cache_off
b __armv6_mmu_cache_flush b __armv6_mmu_cache_flush
......
# #
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# Linux kernel version: 2.6.12-rc1-bk2 # Linux kernel version: 2.6.12
# Mon Mar 28 00:06:33 2005 # Thu Nov 3 14:15:32 2005
# #
CONFIG_ARM=y CONFIG_ARM=y
CONFIG_MMU=y CONFIG_MMU=y
...@@ -17,6 +17,7 @@ CONFIG_EXPERIMENTAL=y ...@@ -17,6 +17,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
# #
# General setup # General setup
...@@ -36,6 +37,8 @@ CONFIG_EMBEDDED=y ...@@ -36,6 +37,8 @@ CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_BASE_FULL=y CONFIG_BASE_FULL=y
CONFIG_FUTEX=y CONFIG_FUTEX=y
# CONFIG_EPOLL is not set # CONFIG_EPOLL is not set
...@@ -71,6 +74,7 @@ CONFIG_BASE_SMALL=0 ...@@ -71,6 +74,7 @@ CONFIG_BASE_SMALL=0
# CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7952X is not set
CONFIG_ARCH_LH7A40X=y CONFIG_ARCH_LH7A40X=y
# CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_VERSATILE is not set # CONFIG_ARCH_VERSATILE is not set
...@@ -84,6 +88,7 @@ CONFIG_ARCH_LH7A40X=y ...@@ -84,6 +88,7 @@ CONFIG_ARCH_LH7A40X=y
CONFIG_MACH_LPD7A400=y CONFIG_MACH_LPD7A400=y
# CONFIG_MACH_LPD7A404 is not set # CONFIG_MACH_LPD7A404 is not set
CONFIG_ARCH_LH7A400=y CONFIG_ARCH_LH7A400=y
CONFIG_LPD7A40X_CPLD_SSP=y
# CONFIG_LH7A40X_CONTIGMEM is not set # CONFIG_LH7A40X_CONTIGMEM is not set
# CONFIG_LH7A40X_ONE_BANK_PER_NODE is not set # CONFIG_LH7A40X_ONE_BANK_PER_NODE is not set
...@@ -110,6 +115,8 @@ CONFIG_ARM_THUMB=y ...@@ -110,6 +115,8 @@ CONFIG_ARM_THUMB=y
# #
# Bus support # Bus support
# #
CONFIG_ARM_AMBA=y
CONFIG_ISA_DMA_API=y
# #
# PCCARD (PCMCIA/CardBus) support # PCCARD (PCMCIA/CardBus) support
...@@ -119,6 +126,7 @@ CONFIG_ARM_THUMB=y ...@@ -119,6 +126,7 @@ CONFIG_ARM_THUMB=y
# #
# Kernel Features # Kernel Features
# #
# CONFIG_SMP is not set
CONFIG_PREEMPT=y CONFIG_PREEMPT=y
CONFIG_DISCONTIGMEM=y CONFIG_DISCONTIGMEM=y
CONFIG_ALIGNMENT_TRAP=y CONFIG_ALIGNMENT_TRAP=y
...@@ -175,7 +183,7 @@ CONFIG_MTD=y ...@@ -175,7 +183,7 @@ CONFIG_MTD=y
# CONFIG_MTD_CONCAT is not set # CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set # CONFIG_MTD_AFS_PARTS is not set
# #
...@@ -217,7 +225,10 @@ CONFIG_MTD_CFI_UTIL=y ...@@ -217,7 +225,10 @@ CONFIG_MTD_CFI_UTIL=y
# Mapping drivers for chip access # Mapping drivers for chip access
# #
# CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_START=0x00000000
CONFIG_MTD_PHYSMAP_LEN=0x04000000
CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ARM_INTEGRATOR is not set # CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_EDB7312 is not set # CONFIG_MTD_EDB7312 is not set
...@@ -254,7 +265,6 @@ CONFIG_MTD_CFI_UTIL=y ...@@ -254,7 +265,6 @@ CONFIG_MTD_CFI_UTIL=y
# #
# Block devices # Block devices
# #
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_CRYPTOLOOP is not set
...@@ -288,13 +298,15 @@ CONFIG_BLK_DEV_IDEDISK=y ...@@ -288,13 +298,15 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set # CONFIG_IDE_TASK_IOCTL is not set
CONFIG_IDE_POLL=y
# #
# IDE chipset support/bugfixes # IDE chipset support/bugfixes
# #
CONFIG_IDE_GENERIC=y CONFIG_IDE_GENERIC=y
# CONFIG_IDE_ARM is not set CONFIG_IDE_ARM=y
# CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set # CONFIG_BLK_DEV_HD is not set
...@@ -302,7 +314,37 @@ CONFIG_IDE_GENERIC=y ...@@ -302,7 +314,37 @@ CONFIG_IDE_GENERIC=y
# #
# SCSI device support # SCSI device support
# #
# CONFIG_SCSI is not set CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
#
# SCSI support type (disk, tape, CD-ROM)
#
# CONFIG_BLK_DEV_SD is not set
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
#
# SCSI Transport Attributes
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
#
# SCSI low-level drivers
#
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_DEBUG is not set
# #
# Multi-device support (RAID and LVM) # Multi-device support (RAID and LVM)
...@@ -331,7 +373,6 @@ CONFIG_NET=y ...@@ -331,7 +373,6 @@ CONFIG_NET=y
# #
CONFIG_PACKET=y CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set # CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y CONFIG_UNIX=y
# CONFIG_NET_KEY is not set # CONFIG_NET_KEY is not set
CONFIG_INET=y CONFIG_INET=y
...@@ -438,13 +479,10 @@ CONFIG_INPUT=y ...@@ -438,13 +479,10 @@ CONFIG_INPUT=y
# #
# Userland interfaces # Userland interfaces
# #
CONFIG_INPUT_MOUSEDEV=y # CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set # CONFIG_INPUT_EVBUG is not set
# #
...@@ -453,7 +491,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ...@@ -453,7 +491,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
CONFIG_TOUCHSCREEN_ADS7843_LH7=y
CONFIG_HAS_TOUCHSCREEN_ADS7843_LH7=y
# CONFIG_INPUT_MISC is not set # CONFIG_INPUT_MISC is not set
# #
...@@ -461,7 +505,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ...@@ -461,7 +505,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# #
# CONFIG_SERIO is not set # CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set # CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
# #
# Character devices # Character devices
...@@ -479,6 +522,8 @@ CONFIG_HW_CONSOLE=y ...@@ -479,6 +522,8 @@ CONFIG_HW_CONSOLE=y
# #
# Non-8250 serial port support # Non-8250 serial port support
# #
# CONFIG_SERIAL_AMBA_PL010 is not set
# CONFIG_SERIAL_AMBA_PL011 is not set
CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_LH7A40X=y CONFIG_SERIAL_LH7A40X=y
...@@ -510,7 +555,6 @@ CONFIG_RTC=y ...@@ -510,7 +555,6 @@ CONFIG_RTC=y
# #
# TPM devices # TPM devices
# #
# CONFIG_TCG_TPM is not set
# #
# I2C support # I2C support
...@@ -534,18 +578,73 @@ CONFIG_RTC=y ...@@ -534,18 +578,73 @@ CONFIG_RTC=y
# #
# Graphics support # Graphics support
# #
# CONFIG_FB is not set CONFIG_FB=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_FB_SOFT_CURSOR=y
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
CONFIG_FB_ARMCLCD=y
CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT=y
# CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02 is not set
# CONFIG_FB_ARMCLCD_SHARP_LQ64D343 is not set
# CONFIG_FB_ARMCLCD_SHARP_LQ10D368 is not set
# CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41 is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
# #
# Console display driver support # Console display driver support
# #
# CONFIG_VGA_CONSOLE is not set # CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE is not set
#
# Logo configuration
#
# CONFIG_LOGO is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# #
# Sound # Sound
# #
# CONFIG_SOUND is not set CONFIG_SOUND=y
#
# Advanced Linux Sound Architecture
#
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
# CONFIG_SND_SEQUENCER is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
# CONFIG_SND_RTCTIMER is not set
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
#
# Generic devices
#
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
CONFIG_SND_AC97_CODEC=y
#
# ALSA ARM devices
#
CONFIG_SND_LH7A40X_AC97=y
#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
# #
# USB support # USB support
......
This diff is collapsed.
This diff is collapsed.
...@@ -271,7 +271,7 @@ ENTRY(sys_call_table) ...@@ -271,7 +271,7 @@ ENTRY(sys_call_table)
@ r8 = syscall table @ r8 = syscall table
.type sys_syscall, #function .type sys_syscall, #function
sys_syscall: sys_syscall:
eor scno, r0, #__NR_OABI_SYSCALL_BASE bic scno, r0, #__NR_OABI_SYSCALL_BASE
cmp scno, #__NR_syscall - __NR_SYSCALL_BASE cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
cmpne scno, #NR_syscalls @ check range cmpne scno, #NR_syscalls @ check range
stmloia sp, {r5, r6} @ shuffle args stmloia sp, {r5, r6} @ shuffle args
......
...@@ -342,10 +342,10 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) ...@@ -342,10 +342,10 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
#ifdef CONFIG_NO_IDLE_HZ #ifdef CONFIG_NO_IDLE_HZ
if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) { if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
write_seqlock(&xtime_lock); spin_lock(&system_timer->dyn_tick->lock);
if (system_timer->dyn_tick->state & DYN_TICK_ENABLED) if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
system_timer->dyn_tick->handler(irq, 0, regs); system_timer->dyn_tick->handler(irq, 0, regs);
write_sequnlock(&xtime_lock); spin_unlock(&system_timer->dyn_tick->lock);
} }
#endif #endif
......
...@@ -379,7 +379,7 @@ static int timer_dyn_tick_enable(void) ...@@ -379,7 +379,7 @@ static int timer_dyn_tick_enable(void)
int ret = -ENODEV; int ret = -ENODEV;
if (dyn_tick) { if (dyn_tick) {
write_seqlock_irqsave(&xtime_lock, flags); spin_lock_irqsave(&dyn_tick->lock, flags);
ret = 0; ret = 0;
if (!(dyn_tick->state & DYN_TICK_ENABLED)) { if (!(dyn_tick->state & DYN_TICK_ENABLED)) {
ret = dyn_tick->enable(); ret = dyn_tick->enable();
...@@ -387,7 +387,7 @@ static int timer_dyn_tick_enable(void) ...@@ -387,7 +387,7 @@ static int timer_dyn_tick_enable(void)
if (ret == 0) if (ret == 0)
dyn_tick->state |= DYN_TICK_ENABLED; dyn_tick->state |= DYN_TICK_ENABLED;
} }
write_sequnlock_irqrestore(&xtime_lock, flags); spin_unlock_irqrestore(&dyn_tick->lock, flags);
} }
return ret; return ret;
...@@ -400,7 +400,7 @@ static int timer_dyn_tick_disable(void) ...@@ -400,7 +400,7 @@ static int timer_dyn_tick_disable(void)
int ret = -ENODEV; int ret = -ENODEV;
if (dyn_tick) { if (dyn_tick) {
write_seqlock_irqsave(&xtime_lock, flags); spin_lock_irqsave(&dyn_tick->lock, flags);
ret = 0; ret = 0;
if (dyn_tick->state & DYN_TICK_ENABLED) { if (dyn_tick->state & DYN_TICK_ENABLED) {
ret = dyn_tick->disable(); ret = dyn_tick->disable();
...@@ -408,7 +408,7 @@ static int timer_dyn_tick_disable(void) ...@@ -408,7 +408,7 @@ static int timer_dyn_tick_disable(void)
if (ret == 0) if (ret == 0)
dyn_tick->state &= ~DYN_TICK_ENABLED; dyn_tick->state &= ~DYN_TICK_ENABLED;
} }
write_sequnlock_irqrestore(&xtime_lock, flags); spin_unlock_irqrestore(&dyn_tick->lock, flags);
} }
return ret; return ret;
...@@ -422,15 +422,20 @@ static int timer_dyn_tick_disable(void) ...@@ -422,15 +422,20 @@ static int timer_dyn_tick_disable(void)
void timer_dyn_reprogram(void) void timer_dyn_reprogram(void)
{ {
struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
unsigned long next, seq; unsigned long next, seq, flags;
if (dyn_tick && (dyn_tick->state & DYN_TICK_ENABLED)) { if (!dyn_tick)
return;
spin_lock_irqsave(&dyn_tick->lock, flags);
if (dyn_tick->state & DYN_TICK_ENABLED) {
next = next_timer_interrupt(); next = next_timer_interrupt();
do { do {
seq = read_seqbegin(&xtime_lock); seq = read_seqbegin(&xtime_lock);
dyn_tick->reprogram(next_timer_interrupt() - jiffies); dyn_tick->reprogram(next - jiffies);
} while (read_seqretry(&xtime_lock, seq)); } while (read_seqretry(&xtime_lock, seq));
} }
spin_unlock_irqrestore(&dyn_tick->lock, flags);
} }
static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
...@@ -499,5 +504,10 @@ void __init time_init(void) ...@@ -499,5 +504,10 @@ void __init time_init(void)
if (system_timer->offset == NULL) if (system_timer->offset == NULL)
system_timer->offset = dummy_gettimeoffset; system_timer->offset = dummy_gettimeoffset;
system_timer->init(); system_timer->init();
#ifdef CONFIG_NO_IDLE_HZ
if (system_timer->dyn_tick)
system_timer->dyn_tick->lock = SPIN_LOCK_UNLOCKED;
#endif
} }
...@@ -14,6 +14,7 @@ config MACH_LPD7A400 ...@@ -14,6 +14,7 @@ config MACH_LPD7A400
bool "LPD7A400 Card Engine" bool "LPD7A400 Card Engine"
select ARCH_LH7A400 select ARCH_LH7A400
# select IDE_POLL # select IDE_POLL
select HAS_TOUCHSCREEN_ADS7843_LH7
help help
Say Y here if you are using Logic Product Development's Say Y here if you are using Logic Product Development's
LPD7A400 CardEngine. For the time being, the LPD7A400 and LPD7A400 CardEngine. For the time being, the LPD7A400 and
...@@ -23,6 +24,7 @@ config MACH_LPD7A404 ...@@ -23,6 +24,7 @@ config MACH_LPD7A404
bool "LPD7A404 Card Engine" bool "LPD7A404 Card Engine"
select ARCH_LH7A404 select ARCH_LH7A404
# select IDE_POLL # select IDE_POLL
select HAS_TOUCHSCREEN_ADC_LH7
help help
Say Y here if you are using Logic Product Development's Say Y here if you are using Logic Product Development's
LPD7A404 CardEngine. For the time being, the LPD7A400 and LPD7A404 CardEngine. For the time being, the LPD7A400 and
...@@ -34,6 +36,9 @@ config ARCH_LH7A400 ...@@ -34,6 +36,9 @@ config ARCH_LH7A400
config ARCH_LH7A404 config ARCH_LH7A404
bool bool
config LPD7A40X_CPLD_SSP
bool
config LH7A40X_CONTIGMEM config LH7A40X_CONTIGMEM
bool "Disable NUMA Support" bool "Disable NUMA Support"
depends on ARCH_LH7A40X depends on ARCH_LH7A40X
......
...@@ -4,11 +4,14 @@ ...@@ -4,11 +4,14 @@
# Object file lists. # Object file lists.
obj-y := time.o obj-y := time.o clocks.o
obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o obj-m :=
obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o obj-n :=
obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o obj- :=
obj-m := obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
obj-n := obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o
obj- := obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o
obj-$(CONFIG_LPD7A40X_CPLD_SSP) += ssp-cpld.o
obj-$(CONFIG_FB_ARMCLCD) += clcd.o
...@@ -23,6 +23,28 @@ ...@@ -23,6 +23,28 @@
#include "common.h" #include "common.h"
#define CPLD_INT_NETHERNET (1<<0)
#define CPLD_INTMASK_ETHERNET (1<<2)
#if defined (CONFIG_MACH_LPD7A400)
# define CPLD_INT_NTOUCH (1<<1)
# define CPLD_INTMASK_TOUCH (1<<3)
# define CPLD_INT_PEN (1<<4)
# define CPLD_INTMASK_PEN (1<<4)
# define CPLD_INT_PIRQ (1<<4)
#endif
#define CPLD_INTMASK_CPLD (1<<7)
#define CPLD_INT_CPLD (1<<6)
#define CPLD_CONTROL_SWINT (1<<7) /* Disable all CPLD IRQs */
#define CPLD_CONTROL_OCMSK (1<<6) /* Mask USB1 connect IRQ */
#define CPLD_CONTROL_PDRV (1<<5) /* PCC_nDRV high */
#define CPLD_CONTROL_USB1C (1<<4) /* USB1 connect IRQ active */
#define CPLD_CONTROL_USB1P (1<<3) /* USB1 power disable */
#define CPLD_CONTROL_AWKP (1<<2) /* Auto-wakeup disabled */
#define CPLD_CONTROL_LCD_ENABLE (1<<1) /* LCD Vee enable */
#define CPLD_CONTROL_WRLAN_NENABLE (1<<0) /* SMC91x power disable */
static struct resource smc91x_resources[] = { static struct resource smc91x_resources[] = {
[0] = { [0] = {
.start = CPLD00_PHYS, .start = CPLD00_PHYS,
...@@ -48,12 +70,12 @@ static struct platform_device smc91x_device = { ...@@ -48,12 +70,12 @@ static struct platform_device smc91x_device = {
static struct resource lh7a40x_usbclient_resources[] = { static struct resource lh7a40x_usbclient_resources[] = {
[0] = { [0] = {
.start = USB_PHYS, .start = USB_PHYS,
.end = (USB_PHYS + 0xFF), .end = (USB_PHYS + PAGE_SIZE),
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
[1] = { [1] = {
.start = IRQ_USBINTR, .start = IRQ_USB,
.end = IRQ_USBINTR, .end = IRQ_USB,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
}, },
}; };
...@@ -61,7 +83,8 @@ static struct resource lh7a40x_usbclient_resources[] = { ...@@ -61,7 +83,8 @@ static struct resource lh7a40x_usbclient_resources[] = {
static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL; static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL;
static struct platform_device lh7a40x_usbclient_device = { static struct platform_device lh7a40x_usbclient_device = {
.name = "lh7a40x_udc", // .name = "lh7a40x_udc",
.name = "lh7-udc",
.id = 0, .id = 0,
.dev = { .dev = {
.dma_mask = &lh7a40x_usbclient_dma_mask, .dma_mask = &lh7a40x_usbclient_dma_mask,
...@@ -101,7 +124,7 @@ static struct platform_device lh7a404_usbhost_device = { ...@@ -101,7 +124,7 @@ static struct platform_device lh7a404_usbhost_device = {
#endif #endif
static struct platform_device *lpd7a40x_devs[] __initdata = { static struct platform_device* lpd7a40x_devs[] __initdata = {
&smc91x_device, &smc91x_device,
&lh7a40x_usbclient_device, &lh7a40x_usbclient_device,
#if defined (CONFIG_ARCH_LH7A404) #if defined (CONFIG_ARCH_LH7A404)
...@@ -113,29 +136,52 @@ extern void lpd7a400_map_io (void); ...@@ -113,29 +136,52 @@ extern void lpd7a400_map_io (void);
static void __init lpd7a40x_init (void) static void __init lpd7a40x_init (void)
{ {
CPLD_CONTROL |= (1<<6); /* Mask USB1 connection IRQ */ #if defined (CONFIG_MACH_LPD7A400)
CPLD_CONTROL |= 0
| CPLD_CONTROL_SWINT /* Disable software interrupt */
| CPLD_CONTROL_OCMSK; /* Mask USB1 connection IRQ */
CPLD_CONTROL &= ~(0 CPLD_CONTROL &= ~(0
| (1<<1) /* Disable LCD */ | CPLD_CONTROL_LCD_ENABLE /* Disable LCD */
| (1<<0) /* Enable WLAN */ | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */
); );
#endif
#if defined (CONFIG_MACH_LPD7A404)
CPLD_CONTROL &= ~(0
| CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */
);
#endif
platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs)); platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs));
#if defined (CONFIG_FB_ARMCLCD)
lh7a40x_clcd_init ();
#endif
} }
static void lh7a40x_ack_cpld_irq (u32 irq) static void lh7a40x_ack_cpld_irq (u32 irq)
{ {
/* CPLD doesn't have ack capability */ /* CPLD doesn't have ack capability, but some devices may */
#if defined (CPLD_INTMASK_TOUCH)
/* The touch control *must* mask the the interrupt because the
* interrupt bit is read by the driver to determine if the pen
* is still down. */
if (irq == IRQ_TOUCH)
CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH;
#endif
} }
static void lh7a40x_mask_cpld_irq (u32 irq) static void lh7a40x_mask_cpld_irq (u32 irq)
{ {
switch (irq) { switch (irq) {
case IRQ_LPD7A40X_ETH_INT: case IRQ_LPD7A40X_ETH_INT:
CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4; CPLD_INTERRUPTS |= CPLD_INTMASK_ETHERNET;
break; break;
case IRQ_LPD7A400_TS: #if defined (IRQ_TOUCH)
CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x8; case IRQ_TOUCH:
CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH;
break; break;
#endif
} }
} }
...@@ -143,11 +189,13 @@ static void lh7a40x_unmask_cpld_irq (u32 irq) ...@@ -143,11 +189,13 @@ static void lh7a40x_unmask_cpld_irq (u32 irq)
{ {
switch (irq) { switch (irq) {
case IRQ_LPD7A40X_ETH_INT: case IRQ_LPD7A40X_ETH_INT:
CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4; CPLD_INTERRUPTS &= ~CPLD_INTMASK_ETHERNET;
break; break;
case IRQ_LPD7A400_TS: #if defined (IRQ_TOUCH)
CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x8; case IRQ_TOUCH:
CPLD_INTERRUPTS &= ~CPLD_INTMASK_TOUCH;
break; break;
#endif
} }
} }
...@@ -164,11 +212,13 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc, ...@@ -164,11 +212,13 @@ static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc,
desc->chip->ack (irq); desc->chip->ack (irq);
if ((mask & 0x1) == 0) /* WLAN */ if ((mask & (1<<0)) == 0) /* WLAN */
IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT); IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT);
if ((mask & 0x2) == 0) /* Touch */ #if defined (IRQ_TOUCH)
IRQ_DISPATCH (IRQ_LPD7A400_TS); if ((mask & (1<<1)) == 0) /* Touch */
IRQ_DISPATCH (IRQ_TOUCH);
#endif
desc->chip->unmask (irq); /* Level-triggered need this */ desc->chip->unmask (irq); /* Level-triggered need this */
} }
...@@ -204,9 +254,21 @@ void __init lh7a40x_init_board_irq (void) ...@@ -204,9 +254,21 @@ void __init lh7a40x_init_board_irq (void)
/* Then, configure CPLD interrupt */ /* Then, configure CPLD interrupt */
CPLD_INTERRUPTS = 0x9c; /* Disable all CPLD interrupts */ /* Disable all CPLD interrupts */
#if defined (CONFIG_MACH_LPD7A400)
CPLD_INTERRUPTS = CPLD_INTMASK_TOUCH | CPLD_INTMASK_PEN
| CPLD_INTMASK_ETHERNET;
/* *** FIXME: don't know why we need 7 and 4. 7 is way wrong
and 4 is uncefined. */
// (1<<7)|(1<<4)|(1<<3)|(1<<2);
#endif
#if defined (CONFIG_MACH_LPD7A404)
CPLD_INTERRUPTS = CPLD_INTMASK_ETHERNET;
/* *** FIXME: don't know why we need 6 and 5, neither is defined. */
// (1<<6)|(1<<5)|(1<<3);
#endif
GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */ GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */
GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */ GPIO_INTTYPE1 &= ~(1 << pinCPLD); /* Level triggered */
GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */ GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */
barrier (); barrier ();
GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */ GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */
...@@ -216,7 +278,7 @@ void __init lh7a40x_init_board_irq (void) ...@@ -216,7 +278,7 @@ void __init lh7a40x_init_board_irq (void)
for (irq = IRQ_BOARD_START; for (irq = IRQ_BOARD_START;
irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) {
set_irq_chip (irq, &lpd7a40x_cpld_chip); set_irq_chip (irq, &lpd7a40x_cpld_chip);
set_irq_handler (irq, do_edge_IRQ); set_irq_handler (irq, do_level_IRQ);
set_irq_flags (irq, IRQF_VALID); set_irq_flags (irq, IRQF_VALID);
} }
...@@ -226,91 +288,109 @@ void __init lh7a40x_init_board_irq (void) ...@@ -226,91 +288,109 @@ void __init lh7a40x_init_board_irq (void)
lpd7a40x_cpld_handler); lpd7a40x_cpld_handler);
} }
static struct map_desc lpd7a400_io_desc[] __initdata = { static struct map_desc lpd7a40x_io_desc[] __initdata = {
{ {
.virtual = IO_VIRT, .virtual = IO_VIRT,
.pfn = __phys_to_pfn(IO_PHYS), .pfn = __phys_to_pfn(IO_PHYS),
.length = IO_SIZE, .length = IO_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { /* Mapping added to work around chip select problems */ },
{ /* Mapping added to work around chip select problems */
.virtual = IOBARRIER_VIRT, .virtual = IOBARRIER_VIRT,
.pfn = __phys_to_pfn(IOBARRIER_PHYS), .pfn = __phys_to_pfn(IOBARRIER_PHYS),
.length = IOBARRIER_SIZE, .length = IOBARRIER_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CF_VIRT, .virtual = CF_VIRT,
.pfn = __phys_to_pfn(CF_PHYS), .pfn = __phys_to_pfn(CF_PHYS),
.length = CF_SIZE, .length = CF_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD02_VIRT, .virtual = CPLD02_VIRT,
.pfn = __phys_to_pfn(CPLD02_PHYS), .pfn = __phys_to_pfn(CPLD02_PHYS),
.length = CPLD02_SIZE, .length = CPLD02_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD06_VIRT, .virtual = CPLD06_VIRT,
.pfn = __phys_to_pfn(CPLD06_PHYS), .pfn = __phys_to_pfn(CPLD06_PHYS),
.length = CPLD06_SIZE, .length = CPLD06_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD08_VIRT,
.pfn = __phys_to_pfn(CPLD08_PHYS),
.length = CPLD08_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD08_VIRT, .virtual = CPLD08_VIRT,
.pfn = __phys_to_pfn(CPLD08_PHYS), .pfn = __phys_to_pfn(CPLD08_PHYS),
.length = CPLD08_SIZE, .length = CPLD08_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD0A_VIRT,
.pfn = __phys_to_pfn(CPLD0A_PHYS),
.length = CPLD0A_SIZE,
.type = MT_DEVICE
},
{
.virtual = CPLD0C_VIRT, .virtual = CPLD0C_VIRT,
.pfn = __phys_to_pfn(CPLD0C_PHYS), .pfn = __phys_to_pfn(CPLD0C_PHYS),
.length = CPLD0C_SIZE, .length = CPLD0C_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD0E_VIRT, .virtual = CPLD0E_VIRT,
.pfn = __phys_to_pfn(CPLD0E_PHYS), .pfn = __phys_to_pfn(CPLD0E_PHYS),
.length = CPLD0E_SIZE, .length = CPLD0E_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD10_VIRT, .virtual = CPLD10_VIRT,
.pfn = __phys_to_pfn(CPLD10_PHYS), .pfn = __phys_to_pfn(CPLD10_PHYS),
.length = CPLD10_SIZE, .length = CPLD10_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD12_VIRT, .virtual = CPLD12_VIRT,
.pfn = __phys_to_pfn(CPLD12_PHYS), .pfn = __phys_to_pfn(CPLD12_PHYS),
.length = CPLD12_SIZE, .length = CPLD12_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD14_VIRT, .virtual = CPLD14_VIRT,
.pfn = __phys_to_pfn(CPLD14_PHYS), .pfn = __phys_to_pfn(CPLD14_PHYS),
.length = CPLD14_SIZE, .length = CPLD14_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD16_VIRT, .virtual = CPLD16_VIRT,
.pfn = __phys_to_pfn(CPLD16_PHYS), .pfn = __phys_to_pfn(CPLD16_PHYS),
.length = CPLD16_SIZE, .length = CPLD16_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD18_VIRT, .virtual = CPLD18_VIRT,
.pfn = __phys_to_pfn(CPLD18_PHYS), .pfn = __phys_to_pfn(CPLD18_PHYS),
.length = CPLD18_SIZE, .length = CPLD18_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, { },
{
.virtual = CPLD1A_VIRT, .virtual = CPLD1A_VIRT,
.pfn = __phys_to_pfn(CPLD1A_PHYS), .pfn = __phys_to_pfn(CPLD1A_PHYS),
.length = CPLD1A_SIZE, .length = CPLD1A_SIZE,
.type = MT_DEVICE .type = MT_DEVICE
}, },
/* This mapping is redundant since the smc driver performs another. */
/* { CPLD00_VIRT, CPLD00_PHYS, CPLD00_SIZE, MT_DEVICE }, */
}; };
void __init void __init
lpd7a400_map_io(void) lpd7a40x_map_io(void)
{ {
iotable_init (lpd7a400_io_desc, ARRAY_SIZE (lpd7a400_io_desc)); iotable_init (lpd7a40x_io_desc, ARRAY_SIZE (lpd7a40x_io_desc));
/* Fixup (improve) Static Memory Controller settings */
SMC_BCR0 = 0x200039af; /* Boot Flash */
SMC_BCR6 = 0x1000fbe0; /* CPLD */
SMC_BCR7 = 0x1000b2c2; /* Compact Flash */
} }
#ifdef CONFIG_MACH_LPD7A400 #ifdef CONFIG_MACH_LPD7A400
...@@ -320,7 +400,7 @@ MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10") ...@@ -320,7 +400,7 @@ MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
.phys_io = 0x80000000, .phys_io = 0x80000000,
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100, .boot_params = 0xc0000100,
.map_io = lpd7a400_map_io, .map_io = lpd7a40x_map_io,
.init_irq = lh7a400_init_irq, .init_irq = lh7a400_init_irq,
.timer = &lh7a40x_timer, .timer = &lh7a40x_timer,
.init_machine = lpd7a40x_init, .init_machine = lpd7a40x_init,
...@@ -335,7 +415,7 @@ MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10") ...@@ -335,7 +415,7 @@ MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
.phys_io = 0x80000000, .phys_io = 0x80000000,
.io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc,
.boot_params = 0xc0000100, .boot_params = 0xc0000100,
.map_io = lpd7a400_map_io, .map_io = lpd7a40x_map_io,
.init_irq = lh7a404_init_irq, .init_irq = lh7a404_init_irq,
.timer = &lh7a40x_timer, .timer = &lh7a40x_timer,
.init_machine = lpd7a40x_init, .init_machine = lpd7a40x_init,
......
/*
* arch/arm/mach-lh7a40x/clcd.c
*
* Copyright (C) 2004 Marc Singer
*
* 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 <linux/config.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/sysdev.h>
#include <linux/interrupt.h>
//#include <linux/module.h>
//#include <linux/time.h>
//#include <asm/hardware.h>
//#include <asm/mach/time.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/system.h>
#include <asm/hardware.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#define HRTFTC_HRSETUP __REG(HRTFTC_PHYS + 0x00)
#define HRTFTC_HRCON __REG(HRTFTC_PHYS + 0x04)
#define HRTFTC_HRTIMING1 __REG(HRTFTC_PHYS + 0x08)
#define HRTFTC_HRTIMING2 __REG(HRTFTC_PHYS + 0x0c)
#define ALI_SETUP __REG(ALI_PHYS + 0x00)
#define ALI_CONTROL __REG(ALI_PHYS + 0x04)
#define ALI_TIMING1 __REG(ALI_PHYS + 0x08)
#define ALI_TIMING2 __REG(ALI_PHYS + 0x0c)
#include "lcd-panel.h"
static void lh7a40x_clcd_disable (struct clcd_fb *fb)
{
#if defined (CONFIG_MACH_LPD7A400)
CPLD_CONTROL &= ~(1<<1); /* Disable LCD Vee */
#endif
#if defined (CONFIG_MACH_LPD7A404)
GPIO_PCD &= ~(1<<3); /* Disable LCD Vee */
#endif
#if defined (CONFIG_ARCH_LH7A400)
HRTFTC_HRSETUP &= ~(1<<13); /* Disable HRTFT controller */
#endif
#if defined (CONFIG_ARCH_LH7A404)
ALI_SETUP &= ~(1<<13); /* Disable ALI */
#endif
}
static void lh7a40x_clcd_enable (struct clcd_fb *fb)
{
struct clcd_panel_extra* extra
= (struct clcd_panel_extra*) fb->board_data;
#if defined (CONFIG_MACH_LPD7A400)
CPLD_CONTROL |= (1<<1); /* Enable LCD Vee */
#endif
#if defined (CONFIG_MACH_LPD7A404)
GPIO_PCDD &= ~(1<<3); /* Enable LCD Vee */
GPIO_PCD |= (1<<3);
#endif
#if defined (CONFIG_ARCH_LH7A400)
if (extra) {
HRTFTC_HRSETUP
= (1 << 13)
| ((fb->fb.var.xres - 1) << 4)
| 0xc
| (extra->hrmode ? 1 : 0);
HRTFTC_HRCON
= ((extra->clsen ? 1 : 0) << 1)
| ((extra->spsen ? 1 : 0) << 0);
HRTFTC_HRTIMING1
= (extra->pcdel << 8)
| (extra->revdel << 4)
| (extra->lpdel << 0);
HRTFTC_HRTIMING2
= (extra->spldel << 9)
| (extra->pc2del << 0);
}
else
HRTFTC_HRSETUP
= (1 << 13)
| 0xc;
#endif
#if defined (CONFIG_ARCH_LH7A404)
if (extra) {
ALI_SETUP
= (1 << 13)
| ((fb->fb.var.xres - 1) << 4)
| 0xc
| (extra->hrmode ? 1 : 0);
ALI_CONTROL
= ((extra->clsen ? 1 : 0) << 1)
| ((extra->spsen ? 1 : 0) << 0);
ALI_TIMING1
= (extra->pcdel << 8)
| (extra->revdel << 4)
| (extra->lpdel << 0);
ALI_TIMING2
= (extra->spldel << 9)
| (extra->pc2del << 0);
}
else
ALI_SETUP
= (1 << 13)
| 0xc;
#endif
}
#define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK)
static int lh7a40x_clcd_setup (struct clcd_fb *fb)
{
dma_addr_t dma;
u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres
*(lcd_panel.bpp/8));
fb->panel = &lcd_panel;
/* Enforce the sync polarity defaults */
if (!(fb->panel->tim2 & TIM2_IHS))
fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT;
if (!(fb->panel->tim2 & TIM2_IVS))
fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT;
#if defined (HAS_LCD_PANEL_EXTRA)
fb->board_data = &lcd_panel_extra;
#endif
fb->fb.screen_base
= dma_alloc_writecombine (&fb->dev->dev, len,
&dma, GFP_KERNEL);
printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n",
fb->fb.screen_base, (void*) dma, len,
(void*) io_p2v (CLCDC_PHYS));
printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock);
if (!fb->fb.screen_base) {
printk(KERN_ERR "CLCD: unable to map framebuffer\n");
return -ENOMEM;
}
#if defined (USE_RGB555)
fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */
#endif
fb->fb.fix.smem_start = dma;
fb->fb.fix.smem_len = len;
/* Drive PE4 high to prevent CPLD crash */
GPIO_PEDD |= (1<<4);
GPIO_PED |= (1<<4);
GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */
// fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb);
// fb->fb.fbops->fb_set_par (&fb->fb);
return 0;
}
static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma)
{
return dma_mmap_writecombine(&fb->dev->dev, vma,
fb->fb.screen_base,
fb->fb.fix.smem_start,
fb->fb.fix.smem_len);
}
static void lh7a40x_clcd_remove (struct clcd_fb *fb)
{
dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len,
fb->fb.screen_base, fb->fb.fix.smem_start);
}
static struct clcd_board clcd_platform_data = {
.name = "lh7a40x FB",
.check = clcdfb_check,
.decode = clcdfb_decode,
.enable = lh7a40x_clcd_enable,
.setup = lh7a40x_clcd_setup,
.mmap = lh7a40x_clcd_mmap,
.remove = lh7a40x_clcd_remove,
.disable = lh7a40x_clcd_disable,
};
#define IRQ_CLCDC (IRQ_LCDINTR)
#define AMBA_DEVICE(name,busid,base,plat,pid) \
static struct amba_device name##_device = { \
.dev = { \
.coherent_dma_mask = ~0, \
.bus_id = busid, \
.platform_data = plat, \
}, \
.res = { \
.start = base##_PHYS, \
.end = (base##_PHYS) + (4*1024) - 1, \
.flags = IORESOURCE_MEM, \
}, \
.dma_mask = ~0, \
.irq = { IRQ_##base, }, \
/* .dma = base##_DMA,*/ \
.periphid = pid, \
}
AMBA_DEVICE(clcd, "cldc-lh7a40x", CLCDC, &clcd_platform_data, 0x41110);
static struct amba_device *amba_devs[] __initdata = {
&clcd_device,
};
void __init lh7a40x_clcd_init (void)
{
int i;
int result;
printk ("CLCD: registering amba devices\n");
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
result = amba_device_register(d, &iomem_resource);
printk (" %d -> %d\n", i ,result);
}
}
/* arch/arm/mach-lh7a40x/clocks.c
*
* Copyright (C) 2004 Marc Singer
*
* 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 <linux/config.h>
#include <linux/cpufreq.h>
#include <asm/hardware.h>
#include <asm/arch/clocks.h>
#include <linux/err.h>
struct module;
struct icst525_params;
struct clk {
struct list_head node;
unsigned long rate;
struct module *owner;
const char *name;
// void *data;
// const struct icst525_params *params;
// void (*setvco)(struct clk *, struct icst525_vco vco);
};
int clk_register(struct clk *clk);
void clk_unregister(struct clk *clk);
/* ----- */
#define MAINDIV1(c) (((c) >> 7) & 0x0f)
#define MAINDIV2(c) (((c) >> 11) & 0x1f)
#define PS(c) (((c) >> 18) & 0x03)
#define PREDIV(c) (((c) >> 2) & 0x1f)
#define HCLKDIV(c) (((c) >> 0) & 0x02)
#define PCLKDIV(c) (((c) >> 16) & 0x03)
unsigned int cpufreq_get (unsigned int cpu) /* in kHz */
{
return fclkfreq_get ()/1000;
}
EXPORT_SYMBOL(cpufreq_get);
unsigned int fclkfreq_get (void)
{
unsigned int clkset = CSC_CLKSET;
unsigned int gclk
= XTAL_IN
/ (1 << PS(clkset))
* (MAINDIV1(clkset) + 2)
/ (PREDIV(clkset) + 2)
* (MAINDIV2(clkset) + 2)
;
return gclk;
}
unsigned int hclkfreq_get (void)
{
unsigned int clkset = CSC_CLKSET;
unsigned int hclk = fclkfreq_get () / (HCLKDIV(clkset) + 1);
return hclk;
}
unsigned int pclkfreq_get (void)
{
unsigned int clkset = CSC_CLKSET;
int pclkdiv = PCLKDIV(clkset);
unsigned int pclk;
if (pclkdiv == 0x3)
pclkdiv = 0x2;
pclk = hclkfreq_get () / (1 << pclkdiv);
return pclk;
}
/* ----- */
static LIST_HEAD(clocks);
static DECLARE_MUTEX(clocks_sem);
struct clk *clk_get (struct device *dev, const char *id)
{
struct clk *p;
struct clk *clk = ERR_PTR(-ENOENT);
down (&clocks_sem);
list_for_each_entry (p, &clocks, node) {
if (strcmp (id, p->name) == 0
&& try_module_get(p->owner)) {
clk = p;
break;
}
}
up (&clocks_sem);
return clk;
}
EXPORT_SYMBOL(clk_get);
void clk_put (struct clk *clk)
{
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
int clk_enable (struct clk *clk)
{
return 0;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable (struct clk *clk)
{
}
EXPORT_SYMBOL(clk_disable);
int clk_use (struct clk *clk)
{
return 0;
}
EXPORT_SYMBOL(clk_use);
void clk_unuse (struct clk *clk)
{
}
EXPORT_SYMBOL(clk_unuse);
unsigned long clk_get_rate (struct clk *clk)
{
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
long clk_round_rate (struct clk *clk, unsigned long rate)
{
return rate;
}
EXPORT_SYMBOL(clk_round_rate);
int clk_set_rate (struct clk *clk, unsigned long rate)
{
int ret = -EIO;
return ret;
}
EXPORT_SYMBOL(clk_set_rate);
#if 0
/*
* These are fixed clocks.
*/
static struct clk kmi_clk = {
.name = "KMIREFCLK",
.rate = 24000000,
};
static struct clk uart_clk = {
.name = "UARTCLK",
.rate = 24000000,
};
static struct clk mmci_clk = {
.name = "MCLK",
.rate = 33000000,
};
#endif
static struct clk clcd_clk = {
.name = "CLCDCLK",
.rate = 0,
};
int clk_register (struct clk *clk)
{
down (&clocks_sem);
list_add (&clk->node, &clocks);
up (&clocks_sem);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister (struct clk *clk)
{
down (&clocks_sem);
list_del (&clk->node);
up (&clocks_sem);
}
EXPORT_SYMBOL(clk_unregister);
static int __init clk_init (void)
{
clk_register(&clcd_clk);
return 0;
}
arch_initcall(clk_init);
...@@ -12,6 +12,7 @@ extern struct sys_timer lh7a40x_timer; ...@@ -12,6 +12,7 @@ extern struct sys_timer lh7a40x_timer;
extern void lh7a400_init_irq (void); extern void lh7a400_init_irq (void);
extern void lh7a404_init_irq (void); extern void lh7a404_init_irq (void);
extern void lh7a40x_clcd_init (void);
extern void lh7a40x_init_board_irq (void); extern void lh7a40x_init_board_irq (void);
#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs) #define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs)
...@@ -28,13 +28,17 @@ ...@@ -28,13 +28,17 @@
static unsigned char irq_pri_vic1[] = { static unsigned char irq_pri_vic1[] = {
#if defined (USE_PRIORITIES) #if defined (USE_PRIORITIES)
IRQ_GPIO3INTR, IRQ_GPIO3INTR, /* CPLD */
IRQ_DMAM2P4, IRQ_DMAM2P5, /* AC97 */
#endif #endif
}; };
static unsigned char irq_pri_vic2[] = { static unsigned char irq_pri_vic2[] = {
#if defined (USE_PRIORITIES) #if defined (USE_PRIORITIES)
IRQ_T3UI, IRQ_GPIO7INTR, IRQ_T3UI, /* Timer */
IRQ_GPIO7INTR, /* CPLD */
IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR, IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR,
IRQ_LCDINTR, /* LCD */
IRQ_TSCINTR, /* ADC/Touchscreen */
#endif #endif
}; };
...@@ -98,10 +102,19 @@ static struct irqchip lh7a404_gpio_vic2_chip = { ...@@ -98,10 +102,19 @@ static struct irqchip lh7a404_gpio_vic2_chip = {
/* IRQ initialization */ /* IRQ initialization */
#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
extern void* branch_irq_lh7a400;
#endif
void __init lh7a404_init_irq (void) void __init lh7a404_init_irq (void)
{ {
int irq; int irq;
#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
#define NOP 0xe1a00000 /* mov r0, r0 */
branch_irq_lh7a400 = NOP;
#endif
VIC1_INTENCLR = 0xffffffff; VIC1_INTENCLR = 0xffffffff;
VIC2_INTENCLR = 0xffffffff; VIC2_INTENCLR = 0xffffffff;
VIC1_INTSEL = 0; /* All IRQs */ VIC1_INTSEL = 0; /* All IRQs */
......
/* lcd-panel.h
$Id$
written by Marc Singer
18 Jul 2005
Copyright (C) 2005 Marc Singer
-----------
DESCRIPTION
-----------
Only one panel may be defined at a time.
The pixel clock is calculated to be no greater than the target.
Each timing value is accompanied by a specification comment.
UNITS/MIN/TYP/MAX
Most of the units will be in clocks.
USE_RGB555
Define this macro to configure the AMBA LCD controller to use an
RGB555 encoding for the pels instead of the normal RGB565.
LPD9520, LPD79524, LPD7A400, LPD7A404-10, LPD7A404-11
These boards are best approximated by 555 for all panels. Some
can use an extra low-order bit of blue in bit 16 of the color
value, but we don't have a way to communicate this non-linear
mapping to the kernel.
*/
#if !defined (__LCD_PANEL_H__)
# define __LCD_PANEL_H__
#if defined (MACH_LPD79520)\
|| defined (MACH_LPD79524)\
|| defined (MACH_LPD7A400)\
|| defined (MACH_LPD7A404)
# define USE_RGB555
#endif
struct clcd_panel_extra {
unsigned int hrmode;
unsigned int clsen;
unsigned int spsen;
unsigned int pcdel;
unsigned int revdel;
unsigned int lpdel;
unsigned int spldel;
unsigned int pc2del;
};
#define NS_TO_CLOCK(ns,c) ((((ns)*((c)/1000) + (1000000 - 1))/1000000))
#define CLOCK_TO_DIV(e,c) (((c) + (e) - 1)/(e))
#if defined CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT
/* Logic Product Development LCD 3.5" QVGA HRTFT -10 */
/* Sharp PN LQ035Q7DB02 w/HRTFT controller chip */
#define PIX_CLOCK_TARGET (6800000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "3.5in QVGA (LQ035Q7DB02)",
.xres = 240,
.yres = 320,
.pixclock = PIX_CLOCK,
.left_margin = 16,
.right_margin = 21,
.upper_margin = 8, // line/8/8/8
.lower_margin = 5,
.hsync_len = 61,
.vsync_len = NS_TO_CLOCK (60, PIX_CLOCK),
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IPC | (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#define HAS_LCD_PANEL_EXTRA
static struct clcd_panel_extra lcd_panel_extra = {
.hrmode = 1,
.clsen = 1,
.spsen = 1,
.pcdel = 8,
.revdel = 7,
.lpdel = 13,
.spldel = 77,
.pc2del = 208,
};
#endif
#if defined CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02
/* Logic Product Development LCD 5.7" QVGA -10 */
/* Sharp PN LQ057Q3DC02 */
/* QVGA mode, V/Q=LOW */
/* From Sharp on 2006.1.3. I believe some of the values are incorrect
* based on the datasheet.
Timing0 TIMING1 TIMING2 CONTROL
0x140A0C4C 0x080504EF 0x013F380D 0x00000829
HBP= 20 VBP= 8 BCD= 0
HFP= 10 VFP= 5 CPL=319
HSW= 12 VSW= 1 IOE= 0
PPL= 19 LPP=239 IPC= 1
IHS= 1
IVS= 1
ACB= 0
CSEL= 0
PCD= 13
*/
/* The full horozontal cycle (Th) is clock/360/400/450. */
/* The full vertical cycle (Tv) is line/251/262/280. */
#define PIX_CLOCK_TARGET (6300000) /* -/6.3/7 MHz */
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "5.7in QVGA (LQ057Q3DC02)",
.xres = 320,
.yres = 240,
.pixclock = PIX_CLOCK,
.left_margin = 11,
.right_margin = 400-11-320-2,
.upper_margin = 7, // line/7/7/7
.lower_margin = 262-7-240-2,
.hsync_len = 2, // clk/2/96/200
.vsync_len = 2, // line/2/-/34
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#if defined CONFIG_FB_ARMCLCD_SHARP_LQ64D343
/* Logic Product Development LCD 6.4" VGA -10 */
/* Sharp PN LQ64D343 */
/* The full horozontal cycle (Th) is clock/750/800/900. */
/* The full vertical cycle (Tv) is line/515/525/560. */
#define PIX_CLOCK_TARGET (28330000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "6.4in QVGA (LQ64D343)",
.xres = 640,
.yres = 480,
.pixclock = PIX_CLOCK,
.left_margin = 32,
.right_margin = 800-32-640-96,
.upper_margin = 32, // line/34/34/34
.lower_margin = 540-32-480-2,
.hsync_len = 96, // clk/2/96/200
.vsync_len = 2, // line/2/-/34
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#if defined CONFIG_FB_ARMCLCD_SHARP_LQ10D368
/* Logic Product Development LCD 10.4" VGA -10 */
/* Sharp PN LQ10D368 */
#define PIX_CLOCK_TARGET (28330000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "10.4in VGA (LQ10D368)",
.xres = 640,
.yres = 480,
.pixclock = PIX_CLOCK,
.left_margin = 21,
.right_margin = 15,
.upper_margin = 34,
.lower_margin = 5,
.hsync_len = 96,
.vsync_len = 16,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#if defined CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41
/* Logic Product Development LCD 12.1" SVGA -10 */
/* Sharp PN LQ121S1DG41, was LQ121S1DG31 */
/* Note that with a 99993900 Hz HCLK, it is not possible to hit the
* target clock frequency range of 35MHz to 42MHz. */
/* If the target pixel clock is substantially lower than the panel
* spec, this is done to prevent the LCD display from glitching when
* the CPU is under load. A pixel clock higher than 25MHz
* (empirically determined) will compete with the CPU for bus cycles
* for the Ethernet chip. However, even a pixel clock of 10MHz
* competes with Compact Flash interface during some operations
* (fdisk, e2fsck). And, at that speed the display may have a visible
* flicker. */
/* The full horozontal cycle (Th) is clock/832/1056/1395. */
#define PIX_CLOCK_TARGET (20000000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "12.1in SVGA (LQ121S1DG41)",
.xres = 800,
.yres = 600,
.pixclock = PIX_CLOCK,
.left_margin = 89, // ns/5/-/(1/PIX_CLOCK)-10
.right_margin = 1056-800-89-128,
.upper_margin = 23, // line/23/23/23
.lower_margin = 44,
.hsync_len = 128, // clk/2/128/200
.vsync_len = 4, // line/2/4/6
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#if defined CONFIG_FB_ARMCLCD_HITACHI
/* Hitachi*/
/* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
#define PIX_CLOCK_TARGET (49000000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "Hitachi 800x480",
.xres = 800,
.yres = 480,
.pixclock = PIX_CLOCK,
.left_margin = 88,
.right_margin = 40,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 128,
.vsync_len = 2,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#if defined CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE
/* AU Optotronics A070VW01 7.0 Wide Screen color Display*/
/* Submitted by Michele Da Rold <michele.darold@ecsproject.com> */
#define PIX_CLOCK_TARGET (10000000)
#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK)
#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER)
static struct clcd_panel lcd_panel = {
.mode = {
.name = "7.0in Wide (A070VW01)",
.xres = 480,
.yres = 234,
.pixclock = PIX_CLOCK,
.left_margin = 30,
.right_margin = 25,
.upper_margin = 14,
.lower_margin = 12,
.hsync_len = 100,
.vsync_len = 1,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS
| (PIX_CLOCK_DIVIDER - 2),
.cntl = CNTL_LCDTFT | CNTL_WATERMARK,
.bpp = 16,
};
#endif
#undef NS_TO_CLOCK
#undef CLOCK_TO_DIV
#endif /* __LCD_PANEL_H__ */
/* arch/arm/mach-lh7a40x/ssp-cpld.c
*
* Copyright (C) 2004,2005 Marc Singer
*
* 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.
*
* SSP/SPI driver for the CardEngine CPLD.
*
*/
/* NOTES
-----
o *** This driver is cribbed from the 7952x implementation.
Some comments may not apply.
o This driver contains sufficient logic to control either the
serial EEPROMs or the audio codec. It is included in the kernel
to support the codec. The EEPROMs are really the responsibility
of the boot loader and should probably be left alone.
o The code must be augmented to cope with multiple, simultaneous
clients.
o The audio codec writes to the codec chip whenever playback
starts.
o The touchscreen driver writes to the ads chip every time it
samples.
o The audio codec must write 16 bits, but the touch chip writes
are 8 bits long.
o We need to be able to keep these configurations separate while
simultaneously active.
*/
#include <linux/module.h>
#include <linux/kernel.h>
//#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
//#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/arch/ssp.h>
//#define TALK
#if defined (TALK)
#define PRINTK(f...) printk (f)
#else
#define PRINTK(f...) do {} while (0)
#endif
#if defined (CONFIG_ARCH_LH7A400)
# define CPLD_SPID __REGP16(CPLD06_VIRT) /* SPI data */
# define CPLD_SPIC __REGP16(CPLD08_VIRT) /* SPI control */
# define CPLD_SPIC_CS_CODEC (1<<0)
# define CPLD_SPIC_CS_TOUCH (1<<1)
# define CPLD_SPIC_WRITE (0<<2)
# define CPLD_SPIC_READ (1<<2)
# define CPLD_SPIC_DONE (1<<3) /* r/o */
# define CPLD_SPIC_LOAD (1<<4)
# define CPLD_SPIC_START (1<<4)
# define CPLD_SPIC_LOADED (1<<5) /* r/o */
#endif
#define CPLD_SPI __REGP16(CPLD0A_VIRT) /* SPI operation */
#define CPLD_SPI_CS_EEPROM (1<<3)
#define CPLD_SPI_SCLK (1<<2)
#define CPLD_SPI_TX_SHIFT (1)
#define CPLD_SPI_TX (1<<CPLD_SPI_TX_SHIFT)
#define CPLD_SPI_RX_SHIFT (0)
#define CPLD_SPI_RX (1<<CPLD_SPI_RX_SHIFT)
/* *** FIXME: these timing values are substantially larger than the
*** chip requires. We may implement an nsleep () function. */
#define T_SKH 1 /* Clock time high (us) */
#define T_SKL 1 /* Clock time low (us) */
#define T_CS 1 /* Minimum chip select low time (us) */
#define T_CSS 1 /* Minimum chip select setup time (us) */
#define T_DIS 1 /* Data setup time (us) */
/* EEPROM SPI bits */
#define P_START (1<<9)
#define P_WRITE (1<<7)
#define P_READ (2<<7)
#define P_ERASE (3<<7)
#define P_EWDS (0<<7)
#define P_WRAL (0<<7)
#define P_ERAL (0<<7)
#define P_EWEN (0<<7)
#define P_A_EWDS (0<<5)
#define P_A_WRAL (1<<5)
#define P_A_ERAL (2<<5)
#define P_A_EWEN (3<<5)
struct ssp_configuration {
int device;
int mode;
int speed;
int frame_size_write;
int frame_size_read;
};
static struct ssp_configuration ssp_configuration;
static spinlock_t ssp_lock;
static void enable_cs (void)
{
switch (ssp_configuration.device) {
case DEVICE_EEPROM:
CPLD_SPI |= CPLD_SPI_CS_EEPROM;
break;
}
udelay (T_CSS);
}
static void disable_cs (void)
{
switch (ssp_configuration.device) {
case DEVICE_EEPROM:
CPLD_SPI &= ~CPLD_SPI_CS_EEPROM;
break;
}
udelay (T_CS);
}
static void pulse_clock (void)
{
CPLD_SPI |= CPLD_SPI_SCLK;
udelay (T_SKH);
CPLD_SPI &= ~CPLD_SPI_SCLK;
udelay (T_SKL);
}
/* execute_spi_command
sends an spi command to a device. It first sends cwrite bits from
v. If cread is greater than zero it will read cread bits
(discarding the leading 0 bit) and return them. If cread is less
than zero it will check for completetion status and return 0 on
success or -1 on timeout. If cread is zero it does nothing other
than sending the command.
On the LPD7A400, we can only read or write multiples of 8 bits on
the codec and the touch screen device. Here, we round up.
*/
static int execute_spi_command (int v, int cwrite, int cread)
{
unsigned long l = 0;
#if defined (CONFIG_MACH_LPD7A400)
/* The codec and touch devices cannot be bit-banged. Instead,
* the CPLD provides an eight-bit shift register and a crude
* interface. */
if ( ssp_configuration.device == DEVICE_CODEC
|| ssp_configuration.device == DEVICE_TOUCH) {
int select = 0;
PRINTK ("spi(%d %d.%d) 0x%04x",
ssp_configuration.device, cwrite, cread,
v);
#if defined (TALK)
if (ssp_configuration.device == DEVICE_CODEC)
PRINTK (" 0x%03x -> %2d", v & 0x1ff, (v >> 9) & 0x7f);
#endif
PRINTK ("\n");
if (ssp_configuration.device == DEVICE_CODEC)
select = CPLD_SPIC_CS_CODEC;
if (ssp_configuration.device == DEVICE_TOUCH)
select = CPLD_SPIC_CS_TOUCH;
if (cwrite) {
for (cwrite = (cwrite + 7)/8; cwrite-- > 0; ) {
CPLD_SPID = (v >> (8*cwrite)) & 0xff;
CPLD_SPIC = select | CPLD_SPIC_LOAD;
while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
;
CPLD_SPIC = select;
while (!(CPLD_SPIC & CPLD_SPIC_DONE))
;
}
v = 0;
}
if (cread) {
mdelay (2); /* *** FIXME: required by ads7843? */
v = 0;
for (cread = (cread + 7)/8; cread-- > 0;) {
CPLD_SPID = 0;
CPLD_SPIC = select | CPLD_SPIC_READ
| CPLD_SPIC_START;
while (!(CPLD_SPIC & CPLD_SPIC_LOADED))
;
CPLD_SPIC = select | CPLD_SPIC_READ;
while (!(CPLD_SPIC & CPLD_SPIC_DONE))
;
v = (v << 8) | CPLD_SPID;
}
}
return v;
}
#endif
PRINTK ("spi(%d) 0x%04x -> 0x%x\r\n", ssp_configuration.device,
v & 0x1ff, (v >> 9) & 0x7f);
enable_cs ();
v <<= CPLD_SPI_TX_SHIFT; /* Correction for position of SPI_TX bit */
while (cwrite--) {
CPLD_SPI
= (CPLD_SPI & ~CPLD_SPI_TX)
| ((v >> cwrite) & CPLD_SPI_TX);
udelay (T_DIS);
pulse_clock ();
}
if (cread < 0) {
int delay = 10;
disable_cs ();
udelay (1);
enable_cs ();
l = -1;
do {
if (CPLD_SPI & CPLD_SPI_RX) {
l = 0;
break;
}
} while (udelay (1), --delay);
}
else
/* We pulse the clock before the data to skip the leading zero. */
while (cread-- > 0) {
pulse_clock ();
l = (l<<1)
| (((CPLD_SPI & CPLD_SPI_RX)
>> CPLD_SPI_RX_SHIFT) & 0x1);
}
disable_cs ();
return l;
}
static int ssp_init (void)
{
spin_lock_init (&ssp_lock);
memset (&ssp_configuration, 0, sizeof (ssp_configuration));
return 0;
}
/* ssp_chip_select
drops the chip select line for the CPLD shift-register controlled
devices. It doesn't enable chip
*/
static void ssp_chip_select (int enable)
{
#if defined (CONFIG_MACH_LPD7A400)
int select;
if (ssp_configuration.device == DEVICE_CODEC)
select = CPLD_SPIC_CS_CODEC;
else if (ssp_configuration.device == DEVICE_TOUCH)
select = CPLD_SPIC_CS_TOUCH;
else
return;
if (enable)
CPLD_SPIC = select;
else
CPLD_SPIC = 0;
#endif
}
static void ssp_acquire (void)
{
spin_lock (&ssp_lock);
}
static void ssp_release (void)
{
ssp_chip_select (0); /* just in case */
spin_unlock (&ssp_lock);
}
static int ssp_configure (int device, int mode, int speed,
int frame_size_write, int frame_size_read)
{
ssp_configuration.device = device;
ssp_configuration.mode = mode;
ssp_configuration.speed = speed;
ssp_configuration.frame_size_write = frame_size_write;
ssp_configuration.frame_size_read = frame_size_read;
return 0;
}
static int ssp_read (void)
{
return execute_spi_command (0, 0, ssp_configuration.frame_size_read);
}
static int ssp_write (u16 data)
{
execute_spi_command (data, ssp_configuration.frame_size_write, 0);
return 0;
}
static int ssp_write_read (u16 data)
{
return execute_spi_command (data, ssp_configuration.frame_size_write,
ssp_configuration.frame_size_read);
}
struct ssp_driver lh7a40x_cpld_ssp_driver = {
.init = ssp_init,
.acquire = ssp_acquire,
.release = ssp_release,
.configure = ssp_configure,
.chip_select = ssp_chip_select,
.read = ssp_read,
.write = ssp_write,
.write_read = ssp_write_read,
};
MODULE_AUTHOR("Marc Singer");
MODULE_DESCRIPTION("LPD7A40X CPLD SPI driver");
MODULE_LICENSE("GPL");
/* /*
* arch/arm/mach-lh7a40x/time.c * arch/arm/mach-lh7a40x/time.c
* *
* Copyright (C) 2004 Logic Product Development * Copyright (C) 2004 Logic Product Development
...@@ -57,7 +57,7 @@ static struct irqaction lh7a40x_timer_irq = { ...@@ -57,7 +57,7 @@ static struct irqaction lh7a40x_timer_irq = {
.handler = lh7a40x_timer_interrupt, .handler = lh7a40x_timer_interrupt,
}; };
static void __init lh7a40x_timer_init(void) static void __init lh7a40x_timer_init (void)
{ {
/* Stop/disable all timers */ /* Stop/disable all timers */
TIMER_CONTROL1 = 0; TIMER_CONTROL1 = 0;
......
#
# Makefile for the linux kernel.
#
obj-y := core.o irq.o time.o clock.o gpio.o serial.o dma.o
obj-m :=
obj-n :=
obj- :=
# Power Management
obj-$(CONFIG_PM) += pm.o sleep.o
zreladdr-y := 0x80008000
params_phys-y := 0x80000100
initrd_phys-y := 0x80800000
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -70,7 +70,7 @@ void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable) ...@@ -70,7 +70,7 @@ void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
clkcon &= ~clocks; clkcon &= ~clocks;
/* ensure none of the special function bits set */ /* ensure none of the special function bits set */
clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER); clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER | 3);
__raw_writel(clkcon, S3C2410_CLKCON); __raw_writel(clkcon, S3C2410_CLKCON);
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment