Commit cd392752 authored by Olof Johansson's avatar Olof Johansson

Merge tag 'ep93xx-cleanup' of...

Merge tag 'ep93xx-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator into next/cleanup

Merge "EP93xx cleanups for v4.3" from Linus Walleij:

EP93xx cleanup and completing developments. This switches
EP93xx to generic time and brings in a few out-of-tree small
patches that were stalled for ages.

It also removes the need for memory config options and instead moves over to
using PATCH_PHYS_VIRT.

* tag 'ep93xx-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator:
  ARM: ep93xx: simone: enable DMA on the SPI host
  ARM: ep93xx: vision_ep9307: add audio support
  ARM: ep93xx: vision_ep9307: enable DMA for SPI
  ARM: ep93xx: toss the device ID into the entropy pool
  ARM: ep93xx: remove memory configuration options
  ARM: ep93xx: update comment on timer usage
  ARM: ep93xx: switch clockevent to timer 3
  ARM: ep93xx: use non-raw accessors for timer
  ARM: ep93xx: switch to GENERIC_CLOCKEVENTS
  ARM: ep93xx: move timer to its own file
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents 6339189e 109965a3
...@@ -268,7 +268,6 @@ config PHYS_OFFSET ...@@ -268,7 +268,6 @@ config PHYS_OFFSET
depends on !ARM_PATCH_PHYS_VIRT depends on !ARM_PATCH_PHYS_VIRT
default DRAM_BASE if !MMU default DRAM_BASE if !MMU
default 0x00000000 if ARCH_EBSA110 || \ default 0x00000000 if ARCH_EBSA110 || \
EP93XX_SDCE3_SYNC_PHYS_OFFSET || \
ARCH_FOOTBRIDGE || \ ARCH_FOOTBRIDGE || \
ARCH_INTEGRATOR || \ ARCH_INTEGRATOR || \
ARCH_IOP13XX || \ ARCH_IOP13XX || \
...@@ -277,10 +276,7 @@ config PHYS_OFFSET ...@@ -277,10 +276,7 @@ config PHYS_OFFSET
default 0x10000000 if ARCH_OMAP1 || ARCH_RPC default 0x10000000 if ARCH_OMAP1 || ARCH_RPC
default 0x20000000 if ARCH_S5PV210 default 0x20000000 if ARCH_S5PV210
default 0x70000000 if REALVIEW_HIGH_PHYS_OFFSET default 0x70000000 if REALVIEW_HIGH_PHYS_OFFSET
default 0xc0000000 if EP93XX_SDCE0_PHYS_OFFSET || ARCH_SA1100 default 0xc0000000 if ARCH_SA1100
default 0xd0000000 if EP93XX_SDCE1_PHYS_OFFSET
default 0xe0000000 if EP93XX_SDCE2_PHYS_OFFSET
default 0xf0000000 if EP93XX_SDCE3_ASYNC_PHYS_OFFSET
help help
Please provide the physical address corresponding to the Please provide the physical address corresponding to the
location of main memory in your system. location of main memory in your system.
...@@ -418,11 +414,14 @@ config ARCH_EP93XX ...@@ -418,11 +414,14 @@ config ARCH_EP93XX
bool "EP93xx-based" bool "EP93xx-based"
select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select ARCH_USES_GETTIMEOFFSET
select ARM_AMBA select ARM_AMBA
select ARM_PATCH_PHYS_VIRT
select ARM_VIC select ARM_VIC
select AUTO_ZRELADDR
select CLKDEV_LOOKUP select CLKDEV_LOOKUP
select CLKSRC_MMIO
select CPU_ARM920T select CPU_ARM920T
select GENERIC_CLOCKEVENTS
help help
This enables support for the Cirrus EP93xx series of CPUs. This enables support for the Cirrus EP93xx series of CPUs.
......
...@@ -15,45 +15,8 @@ config CRUNCH ...@@ -15,45 +15,8 @@ config CRUNCH
comment "EP93xx Platforms" comment "EP93xx Platforms"
choice
prompt "EP93xx first SDRAM bank selection"
default EP93XX_SDCE3_SYNC_PHYS_OFFSET
config EP93XX_SDCE3_SYNC_PHYS_OFFSET
bool "0x00000000 - SDCE3/SyncBoot"
help
Select this option if you want support for EP93xx boards with the
first SDRAM bank at 0x00000000.
config EP93XX_SDCE0_PHYS_OFFSET
bool "0xc0000000 - SDCEO"
help
Select this option if you want support for EP93xx boards with the
first SDRAM bank at 0xc0000000.
config EP93XX_SDCE1_PHYS_OFFSET
bool "0xd0000000 - SDCE1"
help
Select this option if you want support for EP93xx boards with the
first SDRAM bank at 0xd0000000.
config EP93XX_SDCE2_PHYS_OFFSET
bool "0xe0000000 - SDCE2"
help
Select this option if you want support for EP93xx boards with the
first SDRAM bank at 0xe0000000.
config EP93XX_SDCE3_ASYNC_PHYS_OFFSET
bool "0xf0000000 - SDCE3/AsyncBoot"
help
Select this option if you want support for EP93xx boards with the
first SDRAM bank at 0xf0000000.
endchoice
config MACH_ADSSPHERE config MACH_ADSSPHERE
bool "Support ADS Sphere" bool "Support ADS Sphere"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
help help
Say 'Y' here if you want your kernel to support the ADS Say 'Y' here if you want your kernel to support the ADS
Sphere board. Sphere board.
...@@ -63,7 +26,6 @@ config MACH_EDB93XX ...@@ -63,7 +26,6 @@ config MACH_EDB93XX
config MACH_EDB9301 config MACH_EDB9301
bool "Support Cirrus Logic EDB9301" bool "Support Cirrus Logic EDB9301"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_EDB93XX select MACH_EDB93XX
help help
Say 'Y' here if you want your kernel to support the Cirrus Say 'Y' here if you want your kernel to support the Cirrus
...@@ -71,7 +33,6 @@ config MACH_EDB9301 ...@@ -71,7 +33,6 @@ config MACH_EDB9301
config MACH_EDB9302 config MACH_EDB9302
bool "Support Cirrus Logic EDB9302" bool "Support Cirrus Logic EDB9302"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_EDB93XX select MACH_EDB93XX
help help
Say 'Y' here if you want your kernel to support the Cirrus Say 'Y' here if you want your kernel to support the Cirrus
...@@ -79,7 +40,6 @@ config MACH_EDB9302 ...@@ -79,7 +40,6 @@ config MACH_EDB9302
config MACH_EDB9302A config MACH_EDB9302A
bool "Support Cirrus Logic EDB9302A" bool "Support Cirrus Logic EDB9302A"
depends on EP93XX_SDCE0_PHYS_OFFSET
select MACH_EDB93XX select MACH_EDB93XX
help help
Say 'Y' here if you want your kernel to support the Cirrus Say 'Y' here if you want your kernel to support the Cirrus
...@@ -87,7 +47,6 @@ config MACH_EDB9302A ...@@ -87,7 +47,6 @@ config MACH_EDB9302A
config MACH_EDB9307 config MACH_EDB9307
bool "Support Cirrus Logic EDB9307" bool "Support Cirrus Logic EDB9307"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_EDB93XX select MACH_EDB93XX
help help
Say 'Y' here if you want your kernel to support the Cirrus Say 'Y' here if you want your kernel to support the Cirrus
...@@ -95,7 +54,6 @@ config MACH_EDB9307 ...@@ -95,7 +54,6 @@ config MACH_EDB9307
config MACH_EDB9307A config MACH_EDB9307A
bool "Support Cirrus Logic EDB9307A" bool "Support Cirrus Logic EDB9307A"
depends on EP93XX_SDCE0_PHYS_OFFSET
select MACH_EDB93XX select MACH_EDB93XX
help help
Say 'Y' here if you want your kernel to support the Cirrus Say 'Y' here if you want your kernel to support the Cirrus
...@@ -103,7 +61,6 @@ config MACH_EDB9307A ...@@ -103,7 +61,6 @@ config MACH_EDB9307A
config MACH_EDB9312 config MACH_EDB9312
bool "Support Cirrus Logic EDB9312" bool "Support Cirrus Logic EDB9312"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_EDB93XX select MACH_EDB93XX
help help
Say 'Y' here if you want your kernel to support the Cirrus Say 'Y' here if you want your kernel to support the Cirrus
...@@ -111,7 +68,6 @@ config MACH_EDB9312 ...@@ -111,7 +68,6 @@ config MACH_EDB9312
config MACH_EDB9315 config MACH_EDB9315
bool "Support Cirrus Logic EDB9315" bool "Support Cirrus Logic EDB9315"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_EDB93XX select MACH_EDB93XX
help help
Say 'Y' here if you want your kernel to support the Cirrus Say 'Y' here if you want your kernel to support the Cirrus
...@@ -119,14 +75,12 @@ config MACH_EDB9315 ...@@ -119,14 +75,12 @@ config MACH_EDB9315
config MACH_EDB9315A config MACH_EDB9315A
bool "Support Cirrus Logic EDB9315A" bool "Support Cirrus Logic EDB9315A"
depends on EP93XX_SDCE0_PHYS_OFFSET
select MACH_EDB93XX select MACH_EDB93XX
help help
Say 'Y' here if you want your kernel to support the Cirrus Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9315A Evaluation Board. Logic EDB9315A Evaluation Board.
config MACH_GESBC9312 config MACH_GESBC9312
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
bool "Support Glomation GESBC-9312-sx" bool "Support Glomation GESBC-9312-sx"
help help
Say 'Y' here if you want your kernel to support the Glomation Say 'Y' here if you want your kernel to support the Glomation
...@@ -137,7 +91,6 @@ config MACH_MICRO9 ...@@ -137,7 +91,6 @@ config MACH_MICRO9
config MACH_MICRO9H config MACH_MICRO9H
bool "Support Contec Micro9-High" bool "Support Contec Micro9-High"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_MICRO9 select MACH_MICRO9
help help
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
...@@ -145,7 +98,6 @@ config MACH_MICRO9H ...@@ -145,7 +98,6 @@ config MACH_MICRO9H
config MACH_MICRO9M config MACH_MICRO9M
bool "Support Contec Micro9-Mid" bool "Support Contec Micro9-Mid"
depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
select MACH_MICRO9 select MACH_MICRO9
help help
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
...@@ -153,7 +105,6 @@ config MACH_MICRO9M ...@@ -153,7 +105,6 @@ config MACH_MICRO9M
config MACH_MICRO9L config MACH_MICRO9L
bool "Support Contec Micro9-Lite" bool "Support Contec Micro9-Lite"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_MICRO9 select MACH_MICRO9
help help
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
...@@ -161,7 +112,6 @@ config MACH_MICRO9L ...@@ -161,7 +112,6 @@ config MACH_MICRO9L
config MACH_MICRO9S config MACH_MICRO9S
bool "Support Contec Micro9-Slim" bool "Support Contec Micro9-Slim"
depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
select MACH_MICRO9 select MACH_MICRO9
help help
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
...@@ -169,28 +119,24 @@ config MACH_MICRO9S ...@@ -169,28 +119,24 @@ config MACH_MICRO9S
config MACH_SIM_ONE config MACH_SIM_ONE
bool "Support Simplemachines Sim.One board" bool "Support Simplemachines Sim.One board"
depends on EP93XX_SDCE0_PHYS_OFFSET
help help
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
Simplemachines Sim.One board. Simplemachines Sim.One board.
config MACH_SNAPPER_CL15 config MACH_SNAPPER_CL15
bool "Support Bluewater Systems Snapper CL15 Module" bool "Support Bluewater Systems Snapper CL15 Module"
depends on EP93XX_SDCE0_PHYS_OFFSET
help help
Say 'Y' here if you want your kernel to support the Bluewater Say 'Y' here if you want your kernel to support the Bluewater
Systems Snapper CL15 Module. Systems Snapper CL15 Module.
config MACH_TS72XX config MACH_TS72XX
bool "Support Technologic Systems TS-72xx SBC" bool "Support Technologic Systems TS-72xx SBC"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
help help
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
Technologic Systems TS-72xx board. Technologic Systems TS-72xx board.
config MACH_VISION_EP9307 config MACH_VISION_EP9307
bool "Support Vision Engraving Systems EP9307 SoM" bool "Support Vision Engraving Systems EP9307 SoM"
depends on EP93XX_SDCE0_PHYS_OFFSET
help help
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
Vision Engraving Systems EP9307 SoM. Vision Engraving Systems EP9307 SoM.
......
# #
# Makefile for the linux kernel. # Makefile for the linux kernel.
# #
obj-y := core.o clock.o obj-y := core.o clock.o timer-ep93xx.o
obj-$(CONFIG_EP93XX_DMA) += dma.o obj-$(CONFIG_EP93XX_DMA) += dma.o
......
zreladdr-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) += 0x00008000 # Empty file waiting for deletion once Makefile.boot isn't needed any more.
params_phys-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) := 0x00000100
zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) += 0xc0008000
params_phys-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0000100
zreladdr-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) += 0xd0008000
params_phys-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) := 0xd0000100
zreladdr-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) += 0xe0008000
params_phys-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) := 0xe0000100
zreladdr-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) += 0xf0008000
params_phys-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) := 0xf0000100
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/sys_soc.h> #include <linux/sys_soc.h>
#include <linux/timex.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/gpio.h> #include <linux/gpio.h>
...@@ -38,6 +37,7 @@ ...@@ -38,6 +37,7 @@
#include <linux/irqchip/arm-vic.h> #include <linux/irqchip/arm-vic.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/usb/ohci_pdriver.h> #include <linux/usb/ohci_pdriver.h>
#include <linux/random.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <linux/platform_data/video-ep93xx.h> #include <linux/platform_data/video-ep93xx.h>
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/time.h>
#include "soc.h" #include "soc.h"
...@@ -73,113 +72,6 @@ void __init ep93xx_map_io(void) ...@@ -73,113 +72,6 @@ void __init ep93xx_map_io(void)
iotable_init(ep93xx_io_desc, ARRAY_SIZE(ep93xx_io_desc)); iotable_init(ep93xx_io_desc, ARRAY_SIZE(ep93xx_io_desc));
} }
/*************************************************************************
* Timer handling for EP93xx
*************************************************************************
* The ep93xx has four internal timers. Timers 1, 2 (both 16 bit) and
* 3 (32 bit) count down at 508 kHz, are self-reloading, and can generate
* an interrupt on underflow. Timer 4 (40 bit) counts down at 983.04 kHz,
* is free-running, and can't generate interrupts.
*
* The 508 kHz timers are ideal for use for the timer interrupt, as the
* most common values of HZ divide 508 kHz nicely. We pick one of the 16
* bit timers (timer 1) since we don't need more than 16 bits of reload
* value as long as HZ >= 8.
*
* The higher clock rate of timer 4 makes it a better choice than the
* other timers for use in gettimeoffset(), while the fact that it can't
* generate interrupts means we don't have to worry about not being able
* to use this timer for something else. We also use timer 4 for keeping
* track of lost jiffies.
*/
#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00)
#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04)
#define EP93XX_TIMER1_CONTROL EP93XX_TIMER_REG(0x08)
#define EP93XX_TIMER123_CONTROL_ENABLE (1 << 7)
#define EP93XX_TIMER123_CONTROL_MODE (1 << 6)
#define EP93XX_TIMER123_CONTROL_CLKSEL (1 << 3)
#define EP93XX_TIMER1_CLEAR EP93XX_TIMER_REG(0x0c)
#define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20)
#define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24)
#define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28)
#define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c)
#define EP93XX_TIMER4_VALUE_LOW EP93XX_TIMER_REG(0x60)
#define EP93XX_TIMER4_VALUE_HIGH EP93XX_TIMER_REG(0x64)
#define EP93XX_TIMER4_VALUE_HIGH_ENABLE (1 << 8)
#define EP93XX_TIMER3_LOAD EP93XX_TIMER_REG(0x80)
#define EP93XX_TIMER3_VALUE EP93XX_TIMER_REG(0x84)
#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88)
#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c)
#define EP93XX_TIMER123_CLOCK 508469
#define EP93XX_TIMER4_CLOCK 983040
#define TIMER1_RELOAD ((EP93XX_TIMER123_CLOCK / HZ) - 1)
#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(EP93XX_TIMER4_CLOCK, HZ)
static unsigned int last_jiffy_time;
static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
{
/* Writing any value clears the timer interrupt */
__raw_writel(1, EP93XX_TIMER1_CLEAR);
/* Recover lost jiffies */
while ((signed long)
(__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
>= TIMER4_TICKS_PER_JIFFY) {
last_jiffy_time += TIMER4_TICKS_PER_JIFFY;
timer_tick();
}
return IRQ_HANDLED;
}
static struct irqaction ep93xx_timer_irq = {
.name = "ep93xx timer",
.flags = IRQF_TIMER | IRQF_IRQPOLL,
.handler = ep93xx_timer_interrupt,
};
static u32 ep93xx_gettimeoffset(void)
{
int offset;
offset = __raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time;
/*
* Timer 4 is based on a 983.04 kHz reference clock,
* so dividing by 983040 gives the fraction of a second,
* so dividing by 0.983040 converts to uS.
* Refactor the calculation to avoid overflow.
* Finally, multiply by 1000 to give nS.
*/
return (offset + (53 * offset / 3072)) * 1000;
}
void __init ep93xx_timer_init(void)
{
u32 tmode = EP93XX_TIMER123_CONTROL_MODE |
EP93XX_TIMER123_CONTROL_CLKSEL;
arch_gettimeoffset = ep93xx_gettimeoffset;
/* Enable periodic HZ timer. */
__raw_writel(tmode, EP93XX_TIMER1_CONTROL);
__raw_writel(TIMER1_RELOAD, EP93XX_TIMER1_LOAD);
__raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
EP93XX_TIMER1_CONTROL);
/* Enable lost jiffy timer. */
__raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
EP93XX_TIMER4_VALUE_HIGH);
setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
}
/************************************************************************* /*************************************************************************
* EP93xx IRQ handling * EP93xx IRQ handling
*************************************************************************/ *************************************************************************/
...@@ -971,6 +863,12 @@ static const char __init *ep93xx_get_soc_id(void) ...@@ -971,6 +863,12 @@ static const char __init *ep93xx_get_soc_id(void)
if (id != id2) if (id != id2)
return "invalid"; return "invalid";
/* Toss the unique ID into the entropy pool */
add_device_randomness(&id2, 4);
add_device_randomness(&id3, 4);
add_device_randomness(&id4, 4);
add_device_randomness(&id5, 4);
snprintf(ep93xx_soc_id, sizeof(ep93xx_soc_id), snprintf(ep93xx_soc_id, sizeof(ep93xx_soc_id),
"%08x%08x%08x%08x", id2, id3, id4, id5); "%08x%08x%08x%08x", id2, id3, id4, id5);
......
...@@ -169,6 +169,7 @@ static struct spi_board_info simone_spi_devices[] __initdata = { ...@@ -169,6 +169,7 @@ static struct spi_board_info simone_spi_devices[] __initdata = {
static struct ep93xx_spi_info simone_spi_info __initdata = { static struct ep93xx_spi_info simone_spi_info __initdata = {
.num_chipselect = ARRAY_SIZE(simone_spi_devices), .num_chipselect = ARRAY_SIZE(simone_spi_devices),
.use_dma = 1,
}; };
static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = { static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = {
......
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/sched_clock.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/mach/time.h>
#include "soc.h"
/*************************************************************************
* Timer handling for EP93xx
*************************************************************************
* The ep93xx has four internal timers. Timers 1, 2 (both 16 bit) and
* 3 (32 bit) count down at 508 kHz, are self-reloading, and can generate
* an interrupt on underflow. Timer 4 (40 bit) counts down at 983.04 kHz,
* is free-running, and can't generate interrupts.
*
* The 508 kHz timers are ideal for use for the timer interrupt, as the
* most common values of HZ divide 508 kHz nicely. We pick the 32 bit
* timer (timer 3) to get as long sleep intervals as possible when using
* CONFIG_NO_HZ.
*
* The higher clock rate of timer 4 makes it a better choice than the
* other timers for use as clock source and for sched_clock(), providing
* a stable 40 bit time base.
*************************************************************************
*/
#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00)
#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04)
#define EP93XX_TIMER1_CONTROL EP93XX_TIMER_REG(0x08)
#define EP93XX_TIMER123_CONTROL_ENABLE (1 << 7)
#define EP93XX_TIMER123_CONTROL_MODE (1 << 6)
#define EP93XX_TIMER123_CONTROL_CLKSEL (1 << 3)
#define EP93XX_TIMER1_CLEAR EP93XX_TIMER_REG(0x0c)
#define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20)
#define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24)
#define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28)
#define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c)
#define EP93XX_TIMER4_VALUE_LOW EP93XX_TIMER_REG(0x60)
#define EP93XX_TIMER4_VALUE_HIGH EP93XX_TIMER_REG(0x64)
#define EP93XX_TIMER4_VALUE_HIGH_ENABLE (1 << 8)
#define EP93XX_TIMER3_LOAD EP93XX_TIMER_REG(0x80)
#define EP93XX_TIMER3_VALUE EP93XX_TIMER_REG(0x84)
#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88)
#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c)
#define EP93XX_TIMER123_RATE 508469
#define EP93XX_TIMER4_RATE 983040
static u64 notrace ep93xx_read_sched_clock(void)
{
u64 ret;
ret = readl(EP93XX_TIMER4_VALUE_LOW);
ret |= ((u64) (readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32);
return ret;
}
cycle_t ep93xx_clocksource_read(struct clocksource *c)
{
u64 ret;
ret = readl(EP93XX_TIMER4_VALUE_LOW);
ret |= ((u64) (readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32);
return (cycle_t) ret;
}
static int ep93xx_clkevt_set_next_event(unsigned long next,
struct clock_event_device *evt)
{
/* Default mode: periodic, off, 508 kHz */
u32 tmode = EP93XX_TIMER123_CONTROL_MODE |
EP93XX_TIMER123_CONTROL_CLKSEL;
/* Clear timer */
writel(tmode, EP93XX_TIMER3_CONTROL);
/* Set next event */
writel(next, EP93XX_TIMER3_LOAD);
writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
EP93XX_TIMER3_CONTROL);
return 0;
}
static void ep93xx_clkevt_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
/* Disable timer */
writel(0, EP93XX_TIMER3_CONTROL);
}
static struct clock_event_device ep93xx_clockevent = {
.name = "timer1",
.features = CLOCK_EVT_FEAT_ONESHOT,
.set_mode = ep93xx_clkevt_set_mode,
.set_next_event = ep93xx_clkevt_set_next_event,
.rating = 300,
};
static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = dev_id;
/* Writing any value clears the timer interrupt */
writel(1, EP93XX_TIMER3_CLEAR);
evt->event_handler(evt);
return IRQ_HANDLED;
}
static struct irqaction ep93xx_timer_irq = {
.name = "ep93xx timer",
.flags = IRQF_TIMER | IRQF_IRQPOLL,
.handler = ep93xx_timer_interrupt,
.dev_id = &ep93xx_clockevent,
};
void __init ep93xx_timer_init(void)
{
/* Enable and register clocksource and sched_clock on timer 4 */
writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
EP93XX_TIMER4_VALUE_HIGH);
clocksource_mmio_init(NULL, "timer4",
EP93XX_TIMER4_RATE, 200, 40,
ep93xx_clocksource_read);
sched_clock_register(ep93xx_read_sched_clock, 40,
EP93XX_TIMER4_RATE);
/* Set up clockevent on timer 3 */
setup_irq(IRQ_EP93XX_TIMER3, &ep93xx_timer_irq);
clockevents_config_and_register(&ep93xx_clockevent,
EP93XX_TIMER123_RATE,
1,
0xffffffffU);
}
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <linux/spi/mmc_spi.h> #include <linux/spi/mmc_spi.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <sound/cs4271.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <linux/platform_data/video-ep93xx.h> #include <linux/platform_data/video-ep93xx.h>
#include <linux/platform_data/spi-ep93xx.h> #include <linux/platform_data/spi-ep93xx.h>
...@@ -168,6 +170,35 @@ static struct i2c_board_info vision_i2c_info[] __initdata = { ...@@ -168,6 +170,35 @@ static struct i2c_board_info vision_i2c_info[] __initdata = {
}, },
}; };
/*************************************************************************
* SPI CS4271 Audio Codec
*************************************************************************/
static struct cs4271_platform_data vision_cs4271_data = {
.gpio_nreset = EP93XX_GPIO_LINE_H(2),
};
static int vision_cs4271_hw_setup(struct spi_device *spi)
{
return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6,
GPIOF_OUT_INIT_HIGH, spi->modalias);
}
static void vision_cs4271_hw_cleanup(struct spi_device *spi)
{
gpio_free(EP93XX_GPIO_LINE_EGPIO6);
}
static void vision_cs4271_hw_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value);
}
static struct ep93xx_spi_chip_ops vision_cs4271_hw = {
.setup = vision_cs4271_hw_setup,
.cleanup = vision_cs4271_hw_cleanup,
.cs_control = vision_cs4271_hw_cs_control,
};
/************************************************************************* /*************************************************************************
* SPI Flash * SPI Flash
*************************************************************************/ *************************************************************************/
...@@ -262,12 +293,20 @@ static struct ep93xx_spi_chip_ops vision_spi_mmc_hw = { ...@@ -262,12 +293,20 @@ static struct ep93xx_spi_chip_ops vision_spi_mmc_hw = {
*************************************************************************/ *************************************************************************/
static struct spi_board_info vision_spi_board_info[] __initdata = { static struct spi_board_info vision_spi_board_info[] __initdata = {
{ {
.modalias = "cs4271",
.platform_data = &vision_cs4271_data,
.controller_data = &vision_cs4271_hw,
.max_speed_hz = 6000000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_3,
}, {
.modalias = "sst25l", .modalias = "sst25l",
.platform_data = &vision_spi_flash_data, .platform_data = &vision_spi_flash_data,
.controller_data = &vision_spi_flash_hw, .controller_data = &vision_spi_flash_hw,
.max_speed_hz = 20000000, .max_speed_hz = 20000000,
.bus_num = 0, .bus_num = 0,
.chip_select = 0, .chip_select = 1,
.mode = SPI_MODE_3, .mode = SPI_MODE_3,
}, { }, {
.modalias = "mmc_spi", .modalias = "mmc_spi",
...@@ -275,15 +314,30 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { ...@@ -275,15 +314,30 @@ static struct spi_board_info vision_spi_board_info[] __initdata = {
.controller_data = &vision_spi_mmc_hw, .controller_data = &vision_spi_mmc_hw,
.max_speed_hz = 20000000, .max_speed_hz = 20000000,
.bus_num = 0, .bus_num = 0,
.chip_select = 1, .chip_select = 2,
.mode = SPI_MODE_3, .mode = SPI_MODE_3,
}, },
}; };
static struct ep93xx_spi_info vision_spi_master __initdata = { static struct ep93xx_spi_info vision_spi_master __initdata = {
.num_chipselect = ARRAY_SIZE(vision_spi_board_info), .num_chipselect = ARRAY_SIZE(vision_spi_board_info),
.use_dma = 1,
}; };
/*************************************************************************
* I2S Audio
*************************************************************************/
static struct platform_device vision_audio_device = {
.name = "edb93xx-audio",
.id = -1,
};
static void __init vision_register_i2s(void)
{
ep93xx_register_i2s();
platform_device_register(&vision_audio_device);
}
/************************************************************************* /*************************************************************************
* Machine Initialization * Machine Initialization
*************************************************************************/ *************************************************************************/
...@@ -309,6 +363,7 @@ static void __init vision_init_machine(void) ...@@ -309,6 +363,7 @@ static void __init vision_init_machine(void)
ARRAY_SIZE(vision_i2c_info)); ARRAY_SIZE(vision_i2c_info));
ep93xx_register_spi(&vision_spi_master, vision_spi_board_info, ep93xx_register_spi(&vision_spi_master, vision_spi_board_info,
ARRAY_SIZE(vision_spi_board_info)); ARRAY_SIZE(vision_spi_board_info));
vision_register_i2s();
} }
MACHINE_START(VISION_EP9307, "Vision Engraving Systems EP9307") MACHINE_START(VISION_EP9307, "Vision Engraving Systems EP9307")
......
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