Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

View file

@ -0,0 +1,200 @@
if ARCH_EP93XX
menu "Cirrus EP93xx Implementation Options"
config EP93XX_SOC_COMMON
bool
default y
select SOC_BUS
select LEDS_GPIO_REGISTER
config CRUNCH
bool "Support for MaverickCrunch"
help
Enable kernel support for MaverickCrunch.
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
bool "Support ADS Sphere"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
help
Say 'Y' here if you want your kernel to support the ADS
Sphere board.
config MACH_EDB93XX
bool
config MACH_EDB9301
bool "Support Cirrus Logic EDB9301"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9301 Evaluation Board.
config MACH_EDB9302
bool "Support Cirrus Logic EDB9302"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9302 Evaluation Board.
config MACH_EDB9302A
bool "Support Cirrus Logic EDB9302A"
depends on EP93XX_SDCE0_PHYS_OFFSET
select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9302A Evaluation Board.
config MACH_EDB9307
bool "Support Cirrus Logic EDB9307"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9307 Evaluation Board.
config MACH_EDB9307A
bool "Support Cirrus Logic EDB9307A"
depends on EP93XX_SDCE0_PHYS_OFFSET
select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9307A Evaluation Board.
config MACH_EDB9312
bool "Support Cirrus Logic EDB9312"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9312 Evaluation Board.
config MACH_EDB9315
bool "Support Cirrus Logic EDB9315"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9315 Evaluation Board.
config MACH_EDB9315A
bool "Support Cirrus Logic EDB9315A"
depends on EP93XX_SDCE0_PHYS_OFFSET
select MACH_EDB93XX
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9315A Evaluation Board.
config MACH_GESBC9312
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
bool "Support Glomation GESBC-9312-sx"
help
Say 'Y' here if you want your kernel to support the Glomation
GESBC-9312-sx board.
config MACH_MICRO9
bool
config MACH_MICRO9H
bool "Support Contec Micro9-High"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_MICRO9
help
Say 'Y' here if you want your kernel to support the
Contec Micro9-High board.
config MACH_MICRO9M
bool "Support Contec Micro9-Mid"
depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
select MACH_MICRO9
help
Say 'Y' here if you want your kernel to support the
Contec Micro9-Mid board.
config MACH_MICRO9L
bool "Support Contec Micro9-Lite"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_MICRO9
help
Say 'Y' here if you want your kernel to support the
Contec Micro9-Lite board.
config MACH_MICRO9S
bool "Support Contec Micro9-Slim"
depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
select MACH_MICRO9
help
Say 'Y' here if you want your kernel to support the
Contec Micro9-Slim board.
config MACH_SIM_ONE
bool "Support Simplemachines Sim.One board"
depends on EP93XX_SDCE0_PHYS_OFFSET
help
Say 'Y' here if you want your kernel to support the
Simplemachines Sim.One board.
config MACH_SNAPPER_CL15
bool "Support Bluewater Systems Snapper CL15 Module"
depends on EP93XX_SDCE0_PHYS_OFFSET
help
Say 'Y' here if you want your kernel to support the Bluewater
Systems Snapper CL15 Module.
config MACH_TS72XX
bool "Support Technologic Systems TS-72xx SBC"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
help
Say 'Y' here if you want your kernel to support the
Technologic Systems TS-72xx board.
config MACH_VISION_EP9307
bool "Support Vision Engraving Systems EP9307 SoM"
depends on EP93XX_SDCE0_PHYS_OFFSET
help
Say 'Y' here if you want your kernel to support the
Vision Engraving Systems EP9307 SoM.
endmenu
endif

View file

@ -0,0 +1,18 @@
#
# Makefile for the linux kernel.
#
obj-y := core.o clock.o
obj-$(CONFIG_EP93XX_DMA) += dma.o
obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o
obj-$(CONFIG_MACH_EDB93XX) += edb93xx.o
obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o
obj-$(CONFIG_MACH_MICRO9) += micro9.o
obj-$(CONFIG_MACH_SIM_ONE) += simone.o
obj-$(CONFIG_MACH_SNAPPER_CL15) += snappercl15.o
obj-$(CONFIG_MACH_TS72XX) += ts72xx.o
obj-$(CONFIG_MACH_VISION_EP9307)+= vision_ep9307.o

View file

@ -0,0 +1,14 @@
zreladdr-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) += 0x00008000
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

View file

@ -0,0 +1,45 @@
/*
* arch/arm/mach-ep93xx/adssphere.c
* ADS Sphere support.
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/sizes.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "soc.h"
static struct ep93xx_eth_data __initdata adssphere_eth_data = {
.phy_id = 1,
};
static void __init adssphere_init_machine(void)
{
ep93xx_init_devices();
ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
ep93xx_register_eth(&adssphere_eth_data, 1);
}
MACHINE_START(ADSSPHERE, "ADS Sphere board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = adssphere_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END

View file

@ -0,0 +1,563 @@
/*
* arch/arm/mach-ep93xx/clock.c
* Clock control for Cirrus EP93xx chips.
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/clkdev.h>
#include <mach/hardware.h>
#include <asm/div64.h>
#include "soc.h"
struct clk {
struct clk *parent;
unsigned long rate;
int users;
int sw_locked;
void __iomem *enable_reg;
u32 enable_mask;
unsigned long (*get_rate)(struct clk *clk);
int (*set_rate)(struct clk *clk, unsigned long rate);
};
static unsigned long get_uart_rate(struct clk *clk);
static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
static int set_div_rate(struct clk *clk, unsigned long rate);
static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);
static struct clk clk_xtali = {
.rate = EP93XX_EXT_CLK_RATE,
};
static struct clk clk_uart1 = {
.parent = &clk_xtali,
.sw_locked = 1,
.enable_reg = EP93XX_SYSCON_DEVCFG,
.enable_mask = EP93XX_SYSCON_DEVCFG_U1EN,
.get_rate = get_uart_rate,
};
static struct clk clk_uart2 = {
.parent = &clk_xtali,
.sw_locked = 1,
.enable_reg = EP93XX_SYSCON_DEVCFG,
.enable_mask = EP93XX_SYSCON_DEVCFG_U2EN,
.get_rate = get_uart_rate,
};
static struct clk clk_uart3 = {
.parent = &clk_xtali,
.sw_locked = 1,
.enable_reg = EP93XX_SYSCON_DEVCFG,
.enable_mask = EP93XX_SYSCON_DEVCFG_U3EN,
.get_rate = get_uart_rate,
};
static struct clk clk_pll1 = {
.parent = &clk_xtali,
};
static struct clk clk_f = {
.parent = &clk_pll1,
};
static struct clk clk_h = {
.parent = &clk_pll1,
};
static struct clk clk_p = {
.parent = &clk_pll1,
};
static struct clk clk_pll2 = {
.parent = &clk_xtali,
};
static struct clk clk_usb_host = {
.parent = &clk_pll2,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN,
};
static struct clk clk_keypad = {
.parent = &clk_xtali,
.sw_locked = 1,
.enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV,
.enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
.set_rate = set_keytchclk_rate,
};
static struct clk clk_spi = {
.parent = &clk_xtali,
.rate = EP93XX_EXT_CLK_RATE,
};
static struct clk clk_pwm = {
.parent = &clk_xtali,
.rate = EP93XX_EXT_CLK_RATE,
};
static struct clk clk_video = {
.sw_locked = 1,
.enable_reg = EP93XX_SYSCON_VIDCLKDIV,
.enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE,
.set_rate = set_div_rate,
};
static struct clk clk_i2s_mclk = {
.sw_locked = 1,
.enable_reg = EP93XX_SYSCON_I2SCLKDIV,
.enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE,
.set_rate = set_div_rate,
};
static struct clk clk_i2s_sclk = {
.sw_locked = 1,
.parent = &clk_i2s_mclk,
.enable_reg = EP93XX_SYSCON_I2SCLKDIV,
.enable_mask = EP93XX_SYSCON_I2SCLKDIV_SENA,
.set_rate = set_i2s_sclk_rate,
};
static struct clk clk_i2s_lrclk = {
.sw_locked = 1,
.parent = &clk_i2s_sclk,
.enable_reg = EP93XX_SYSCON_I2SCLKDIV,
.enable_mask = EP93XX_SYSCON_I2SCLKDIV_SENA,
.set_rate = set_i2s_lrclk_rate,
};
/* DMA Clocks */
static struct clk clk_m2p0 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P0,
};
static struct clk clk_m2p1 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P1,
};
static struct clk clk_m2p2 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P2,
};
static struct clk clk_m2p3 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P3,
};
static struct clk clk_m2p4 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P4,
};
static struct clk clk_m2p5 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P5,
};
static struct clk clk_m2p6 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P6,
};
static struct clk clk_m2p7 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P7,
};
static struct clk clk_m2p8 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P8,
};
static struct clk clk_m2p9 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P9,
};
static struct clk clk_m2m0 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M0,
};
static struct clk clk_m2m1 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M1,
};
#define INIT_CK(dev,con,ck) \
{ .dev_id = dev, .con_id = con, .clk = ck }
static struct clk_lookup clocks[] = {
INIT_CK(NULL, "xtali", &clk_xtali),
INIT_CK("apb:uart1", NULL, &clk_uart1),
INIT_CK("apb:uart2", NULL, &clk_uart2),
INIT_CK("apb:uart3", NULL, &clk_uart3),
INIT_CK(NULL, "pll1", &clk_pll1),
INIT_CK(NULL, "fclk", &clk_f),
INIT_CK(NULL, "hclk", &clk_h),
INIT_CK(NULL, "apb_pclk", &clk_p),
INIT_CK(NULL, "pll2", &clk_pll2),
INIT_CK("ohci-platform", NULL, &clk_usb_host),
INIT_CK("ep93xx-keypad", NULL, &clk_keypad),
INIT_CK("ep93xx-fb", NULL, &clk_video),
INIT_CK("ep93xx-spi.0", NULL, &clk_spi),
INIT_CK("ep93xx-i2s", "mclk", &clk_i2s_mclk),
INIT_CK("ep93xx-i2s", "sclk", &clk_i2s_sclk),
INIT_CK("ep93xx-i2s", "lrclk", &clk_i2s_lrclk),
INIT_CK(NULL, "pwm_clk", &clk_pwm),
INIT_CK(NULL, "m2p0", &clk_m2p0),
INIT_CK(NULL, "m2p1", &clk_m2p1),
INIT_CK(NULL, "m2p2", &clk_m2p2),
INIT_CK(NULL, "m2p3", &clk_m2p3),
INIT_CK(NULL, "m2p4", &clk_m2p4),
INIT_CK(NULL, "m2p5", &clk_m2p5),
INIT_CK(NULL, "m2p6", &clk_m2p6),
INIT_CK(NULL, "m2p7", &clk_m2p7),
INIT_CK(NULL, "m2p8", &clk_m2p8),
INIT_CK(NULL, "m2p9", &clk_m2p9),
INIT_CK(NULL, "m2m0", &clk_m2m0),
INIT_CK(NULL, "m2m1", &clk_m2m1),
};
static DEFINE_SPINLOCK(clk_lock);
static void __clk_enable(struct clk *clk)
{
if (!clk->users++) {
if (clk->parent)
__clk_enable(clk->parent);
if (clk->enable_reg) {
u32 v;
v = __raw_readl(clk->enable_reg);
v |= clk->enable_mask;
if (clk->sw_locked)
ep93xx_syscon_swlocked_write(v, clk->enable_reg);
else
__raw_writel(v, clk->enable_reg);
}
}
}
int clk_enable(struct clk *clk)
{
unsigned long flags;
if (!clk)
return -EINVAL;
spin_lock_irqsave(&clk_lock, flags);
__clk_enable(clk);
spin_unlock_irqrestore(&clk_lock, flags);
return 0;
}
EXPORT_SYMBOL(clk_enable);
static void __clk_disable(struct clk *clk)
{
if (!--clk->users) {
if (clk->enable_reg) {
u32 v;
v = __raw_readl(clk->enable_reg);
v &= ~clk->enable_mask;
if (clk->sw_locked)
ep93xx_syscon_swlocked_write(v, clk->enable_reg);
else
__raw_writel(v, clk->enable_reg);
}
if (clk->parent)
__clk_disable(clk->parent);
}
}
void clk_disable(struct clk *clk)
{
unsigned long flags;
if (!clk)
return;
spin_lock_irqsave(&clk_lock, flags);
__clk_disable(clk);
spin_unlock_irqrestore(&clk_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
static unsigned long get_uart_rate(struct clk *clk)
{
unsigned long rate = clk_get_rate(clk->parent);
u32 value;
value = __raw_readl(EP93XX_SYSCON_PWRCNT);
if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
return rate;
else
return rate / 2;
}
unsigned long clk_get_rate(struct clk *clk)
{
if (clk->get_rate)
return clk->get_rate(clk);
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
{
u32 val;
u32 div_bit;
val = __raw_readl(clk->enable_reg);
/*
* The Key Matrix and ADC clocks are configured using the same
* System Controller register. The clock used will be either
* 1/4 or 1/16 the external clock rate depending on the
* EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
* bit being set or cleared.
*/
div_bit = clk->enable_mask >> 15;
if (rate == EP93XX_KEYTCHCLK_DIV4)
val |= div_bit;
else if (rate == EP93XX_KEYTCHCLK_DIV16)
val &= ~div_bit;
else
return -EINVAL;
ep93xx_syscon_swlocked_write(val, clk->enable_reg);
clk->rate = rate;
return 0;
}
static int calc_clk_div(struct clk *clk, unsigned long rate,
int *psel, int *esel, int *pdiv, int *div)
{
struct clk *mclk;
unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
int i, found = 0, __div = 0, __pdiv = 0;
/* Don't exceed the maximum rate */
max_rate = max3(clk_pll1.rate / 4, clk_pll2.rate / 4, clk_xtali.rate / 4);
rate = min(rate, max_rate);
/*
* Try the two pll's and the external clock
* Because the valid predividers are 2, 2.5 and 3, we multiply
* all the clocks by 2 to avoid floating point math.
*
* This is based on the algorithm in the ep93xx raster guide:
* http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
*
*/
for (i = 0; i < 3; i++) {
if (i == 0)
mclk = &clk_xtali;
else if (i == 1)
mclk = &clk_pll1;
else
mclk = &clk_pll2;
mclk_rate = mclk->rate * 2;
/* Try each predivider value */
for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
__div = mclk_rate / (rate * __pdiv);
if (__div < 2 || __div > 127)
continue;
actual_rate = mclk_rate / (__pdiv * __div);
if (!found || abs(actual_rate - rate) < rate_err) {
*pdiv = __pdiv - 3;
*div = __div;
*psel = (i == 2);
*esel = (i != 0);
clk->parent = mclk;
clk->rate = actual_rate;
rate_err = abs(actual_rate - rate);
found = 1;
}
}
}
if (!found)
return -EINVAL;
return 0;
}
static int set_div_rate(struct clk *clk, unsigned long rate)
{
int err, psel = 0, esel = 0, pdiv = 0, div = 0;
u32 val;
err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
if (err)
return err;
/* Clear the esel, psel, pdiv and div bits */
val = __raw_readl(clk->enable_reg);
val &= ~0x7fff;
/* Set the new esel, psel, pdiv and div bits for the new clock rate */
val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
(psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
(pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
ep93xx_syscon_swlocked_write(val, clk->enable_reg);
return 0;
}
static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate)
{
unsigned val = __raw_readl(clk->enable_reg);
if (rate == clk_i2s_mclk.rate / 2)
ep93xx_syscon_swlocked_write(val & ~EP93XX_I2SCLKDIV_SDIV,
clk->enable_reg);
else if (rate == clk_i2s_mclk.rate / 4)
ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_SDIV,
clk->enable_reg);
else
return -EINVAL;
clk_i2s_sclk.rate = rate;
return 0;
}
static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate)
{
unsigned val = __raw_readl(clk->enable_reg) &
~EP93XX_I2SCLKDIV_LRDIV_MASK;
if (rate == clk_i2s_sclk.rate / 32)
ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV32,
clk->enable_reg);
else if (rate == clk_i2s_sclk.rate / 64)
ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV64,
clk->enable_reg);
else if (rate == clk_i2s_sclk.rate / 128)
ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV128,
clk->enable_reg);
else
return -EINVAL;
clk_i2s_lrclk.rate = rate;
return 0;
}
int clk_set_rate(struct clk *clk, unsigned long rate)
{
if (clk->set_rate)
return clk->set_rate(clk, rate);
return -EINVAL;
}
EXPORT_SYMBOL(clk_set_rate);
static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
static char pclk_divisors[] = { 1, 2, 4, 8 };
/*
* PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
*/
static unsigned long calc_pll_rate(u32 config_word)
{
unsigned long long rate;
int i;
rate = clk_xtali.rate;
rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */
rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */
do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */
for (i = 0; i < ((config_word >> 16) & 3); i++) /* PS */
rate >>= 1;
return (unsigned long)rate;
}
static void __init ep93xx_dma_clock_init(void)
{
clk_m2p0.rate = clk_h.rate;
clk_m2p1.rate = clk_h.rate;
clk_m2p2.rate = clk_h.rate;
clk_m2p3.rate = clk_h.rate;
clk_m2p4.rate = clk_h.rate;
clk_m2p5.rate = clk_h.rate;
clk_m2p6.rate = clk_h.rate;
clk_m2p7.rate = clk_h.rate;
clk_m2p8.rate = clk_h.rate;
clk_m2p9.rate = clk_h.rate;
clk_m2m0.rate = clk_h.rate;
clk_m2m1.rate = clk_h.rate;
}
static int __init ep93xx_clock_init(void)
{
u32 value;
/* Determine the bootloader configured pll1 rate */
value = __raw_readl(EP93XX_SYSCON_CLKSET1);
if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
clk_pll1.rate = clk_xtali.rate;
else
clk_pll1.rate = calc_pll_rate(value);
/* Initialize the pll1 derived clocks */
clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
ep93xx_dma_clock_init();
/* Determine the bootloader configured pll2 rate */
value = __raw_readl(EP93XX_SYSCON_CLKSET2);
if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
clk_pll2.rate = clk_xtali.rate;
else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
clk_pll2.rate = calc_pll_rate(value);
else
clk_pll2.rate = 0;
/* Initialize the pll2 derived clocks */
clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
/*
* EP93xx SSP clock rate was doubled in version E2. For more information
* see:
* http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
*/
if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2)
clk_spi.rate /= 2;
pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
clk_f.rate / 1000000, clk_h.rate / 1000000,
clk_p.rate / 1000000);
clkdev_add_table(clocks, ARRAY_SIZE(clocks));
return 0;
}
postcore_initcall(ep93xx_clock_init);

1076
arch/arm/mach-ep93xx/core.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,313 @@
/*
* arch/arm/kernel/crunch-bits.S
* Cirrus MaverickCrunch context switching and handling
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is
* Copyright (c) 2003-2004, MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/ptrace.h>
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#include <asm/assembler.h>
#include <mach/ep93xx-regs.h>
/*
* We can't use hex constants here due to a bug in gas.
*/
#define CRUNCH_MVDX0 0
#define CRUNCH_MVDX1 8
#define CRUNCH_MVDX2 16
#define CRUNCH_MVDX3 24
#define CRUNCH_MVDX4 32
#define CRUNCH_MVDX5 40
#define CRUNCH_MVDX6 48
#define CRUNCH_MVDX7 56
#define CRUNCH_MVDX8 64
#define CRUNCH_MVDX9 72
#define CRUNCH_MVDX10 80
#define CRUNCH_MVDX11 88
#define CRUNCH_MVDX12 96
#define CRUNCH_MVDX13 104
#define CRUNCH_MVDX14 112
#define CRUNCH_MVDX15 120
#define CRUNCH_MVAX0L 128
#define CRUNCH_MVAX0M 132
#define CRUNCH_MVAX0H 136
#define CRUNCH_MVAX1L 140
#define CRUNCH_MVAX1M 144
#define CRUNCH_MVAX1H 148
#define CRUNCH_MVAX2L 152
#define CRUNCH_MVAX2M 156
#define CRUNCH_MVAX2H 160
#define CRUNCH_MVAX3L 164
#define CRUNCH_MVAX3M 168
#define CRUNCH_MVAX3H 172
#define CRUNCH_DSPSC 176
#define CRUNCH_SIZE 184
.text
/*
* Lazy switching of crunch coprocessor context
*
* r10 = struct thread_info pointer
* r9 = ret_from_exception
* lr = undefined instr exit
*
* called from prefetch exception handler with interrupts enabled
*/
ENTRY(crunch_task_enable)
inc_preempt_count r10, r3
ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr
ldr r1, [r8, #0x80]
tst r1, #0x00800000 @ access to crunch enabled?
bne 2f @ if so no business here
mov r3, #0xaa @ unlock syscon swlock
str r3, [r8, #0xc0]
orr r1, r1, #0x00800000 @ enable access to crunch
str r1, [r8, #0x80]
ldr r3, =crunch_owner
add r0, r10, #TI_CRUNCH_STATE @ get task crunch save area
ldr r2, [sp, #60] @ current task pc value
ldr r1, [r3] @ get current crunch owner
str r0, [r3] @ this task now owns crunch
sub r2, r2, #4 @ adjust pc back
str r2, [sp, #60]
ldr r2, [r8, #0x80]
mov r2, r2 @ flush out enable (@@@)
teq r1, #0 @ test for last ownership
mov lr, r9 @ normal exit from exception
beq crunch_load @ no owner, skip save
crunch_save:
cfstr64 mvdx0, [r1, #CRUNCH_MVDX0] @ save 64b registers
cfstr64 mvdx1, [r1, #CRUNCH_MVDX1]
cfstr64 mvdx2, [r1, #CRUNCH_MVDX2]
cfstr64 mvdx3, [r1, #CRUNCH_MVDX3]
cfstr64 mvdx4, [r1, #CRUNCH_MVDX4]
cfstr64 mvdx5, [r1, #CRUNCH_MVDX5]
cfstr64 mvdx6, [r1, #CRUNCH_MVDX6]
cfstr64 mvdx7, [r1, #CRUNCH_MVDX7]
cfstr64 mvdx8, [r1, #CRUNCH_MVDX8]
cfstr64 mvdx9, [r1, #CRUNCH_MVDX9]
cfstr64 mvdx10, [r1, #CRUNCH_MVDX10]
cfstr64 mvdx11, [r1, #CRUNCH_MVDX11]
cfstr64 mvdx12, [r1, #CRUNCH_MVDX12]
cfstr64 mvdx13, [r1, #CRUNCH_MVDX13]
cfstr64 mvdx14, [r1, #CRUNCH_MVDX14]
cfstr64 mvdx15, [r1, #CRUNCH_MVDX15]
#ifdef __ARMEB__
#error fix me for ARMEB
#endif
cfmv32al mvfx0, mvax0 @ save 72b accumulators
cfstr32 mvfx0, [r1, #CRUNCH_MVAX0L]
cfmv32am mvfx0, mvax0
cfstr32 mvfx0, [r1, #CRUNCH_MVAX0M]
cfmv32ah mvfx0, mvax0
cfstr32 mvfx0, [r1, #CRUNCH_MVAX0H]
cfmv32al mvfx0, mvax1
cfstr32 mvfx0, [r1, #CRUNCH_MVAX1L]
cfmv32am mvfx0, mvax1
cfstr32 mvfx0, [r1, #CRUNCH_MVAX1M]
cfmv32ah mvfx0, mvax1
cfstr32 mvfx0, [r1, #CRUNCH_MVAX1H]
cfmv32al mvfx0, mvax2
cfstr32 mvfx0, [r1, #CRUNCH_MVAX2L]
cfmv32am mvfx0, mvax2
cfstr32 mvfx0, [r1, #CRUNCH_MVAX2M]
cfmv32ah mvfx0, mvax2
cfstr32 mvfx0, [r1, #CRUNCH_MVAX2H]
cfmv32al mvfx0, mvax3
cfstr32 mvfx0, [r1, #CRUNCH_MVAX3L]
cfmv32am mvfx0, mvax3
cfstr32 mvfx0, [r1, #CRUNCH_MVAX3M]
cfmv32ah mvfx0, mvax3
cfstr32 mvfx0, [r1, #CRUNCH_MVAX3H]
cfmv32sc mvdx0, dspsc @ save status word
cfstr64 mvdx0, [r1, #CRUNCH_DSPSC]
teq r0, #0 @ anything to load?
cfldr64eq mvdx0, [r1, #CRUNCH_MVDX0] @ mvdx0 was clobbered
beq 1f
crunch_load:
cfldr64 mvdx0, [r0, #CRUNCH_DSPSC] @ load status word
cfmvsc32 dspsc, mvdx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX0L] @ load 72b accumulators
cfmval32 mvax0, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX0M]
cfmvam32 mvax0, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX0H]
cfmvah32 mvax0, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX1L]
cfmval32 mvax1, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX1M]
cfmvam32 mvax1, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX1H]
cfmvah32 mvax1, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX2L]
cfmval32 mvax2, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX2M]
cfmvam32 mvax2, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX2H]
cfmvah32 mvax2, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX3L]
cfmval32 mvax3, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX3M]
cfmvam32 mvax3, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX3H]
cfmvah32 mvax3, mvfx0
cfldr64 mvdx0, [r0, #CRUNCH_MVDX0] @ load 64b registers
cfldr64 mvdx1, [r0, #CRUNCH_MVDX1]
cfldr64 mvdx2, [r0, #CRUNCH_MVDX2]
cfldr64 mvdx3, [r0, #CRUNCH_MVDX3]
cfldr64 mvdx4, [r0, #CRUNCH_MVDX4]
cfldr64 mvdx5, [r0, #CRUNCH_MVDX5]
cfldr64 mvdx6, [r0, #CRUNCH_MVDX6]
cfldr64 mvdx7, [r0, #CRUNCH_MVDX7]
cfldr64 mvdx8, [r0, #CRUNCH_MVDX8]
cfldr64 mvdx9, [r0, #CRUNCH_MVDX9]
cfldr64 mvdx10, [r0, #CRUNCH_MVDX10]
cfldr64 mvdx11, [r0, #CRUNCH_MVDX11]
cfldr64 mvdx12, [r0, #CRUNCH_MVDX12]
cfldr64 mvdx13, [r0, #CRUNCH_MVDX13]
cfldr64 mvdx14, [r0, #CRUNCH_MVDX14]
cfldr64 mvdx15, [r0, #CRUNCH_MVDX15]
1:
#ifdef CONFIG_PREEMPT_COUNT
get_thread_info r10
#endif
2: dec_preempt_count r10, r3
ret lr
/*
* Back up crunch regs to save area and disable access to them
* (mainly for gdb or sleep mode usage)
*
* r0 = struct thread_info pointer of target task or NULL for any
*/
ENTRY(crunch_task_disable)
stmfd sp!, {r4, r5, lr}
mrs ip, cpsr
orr r2, ip, #PSR_I_BIT @ disable interrupts
msr cpsr_c, r2
ldr r4, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr
ldr r3, =crunch_owner
add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
ldr r1, [r3] @ get current crunch owner
teq r1, #0 @ any current owner?
beq 1f @ no: quit
teq r0, #0 @ any owner?
teqne r1, r2 @ or specified one?
bne 1f @ no: quit
ldr r5, [r4, #0x80] @ enable access to crunch
mov r2, #0xaa
str r2, [r4, #0xc0]
orr r5, r5, #0x00800000
str r5, [r4, #0x80]
mov r0, #0 @ nothing to load
str r0, [r3] @ no more current owner
ldr r2, [r4, #0x80] @ flush out enable (@@@)
mov r2, r2
bl crunch_save
mov r2, #0xaa @ disable access to crunch
str r2, [r4, #0xc0]
bic r5, r5, #0x00800000
str r5, [r4, #0x80]
ldr r5, [r4, #0x80] @ flush out enable (@@@)
mov r5, r5
1: msr cpsr_c, ip @ restore interrupt mode
ldmfd sp!, {r4, r5, pc}
/*
* Copy crunch state to given memory address
*
* r0 = struct thread_info pointer of target task
* r1 = memory address where to store crunch state
*
* this is called mainly in the creation of signal stack frames
*/
ENTRY(crunch_task_copy)
mrs ip, cpsr
orr r2, ip, #PSR_I_BIT @ disable interrupts
msr cpsr_c, r2
ldr r3, =crunch_owner
add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
ldr r3, [r3] @ get current crunch owner
teq r2, r3 @ does this task own it...
beq 1f
@ current crunch values are in the task save area
msr cpsr_c, ip @ restore interrupt mode
mov r0, r1
mov r1, r2
mov r2, #CRUNCH_SIZE
b memcpy
1: @ this task owns crunch regs -- grab a copy from there
mov r0, #0 @ nothing to load
mov r3, lr @ preserve return address
bl crunch_save
msr cpsr_c, ip @ restore interrupt mode
ret r3
/*
* Restore crunch state from given memory address
*
* r0 = struct thread_info pointer of target task
* r1 = memory address where to get crunch state from
*
* this is used to restore crunch state when unwinding a signal stack frame
*/
ENTRY(crunch_task_restore)
mrs ip, cpsr
orr r2, ip, #PSR_I_BIT @ disable interrupts
msr cpsr_c, r2
ldr r3, =crunch_owner
add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
ldr r3, [r3] @ get current crunch owner
teq r2, r3 @ does this task own it...
beq 1f
@ this task doesn't own crunch regs -- use its save area
msr cpsr_c, ip @ restore interrupt mode
mov r0, r2
mov r2, #CRUNCH_SIZE
b memcpy
1: @ this task owns crunch regs -- load them directly
mov r0, r1
mov r1, #0 @ nothing to save
mov r3, lr @ preserve return address
bl crunch_load
msr cpsr_c, ip @ restore interrupt mode
ret r3

View file

@ -0,0 +1,88 @@
/*
* arch/arm/kernel/crunch.c
* Cirrus MaverickCrunch context switching and handling
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* 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/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/io.h>
#include <asm/thread_notify.h>
#include "soc.h"
struct crunch_state *crunch_owner;
void crunch_task_release(struct thread_info *thread)
{
local_irq_disable();
if (crunch_owner == &thread->crunchstate)
crunch_owner = NULL;
local_irq_enable();
}
static int crunch_enabled(u32 devcfg)
{
return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA);
}
static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
{
struct thread_info *thread = (struct thread_info *)t;
struct crunch_state *crunch_state;
u32 devcfg;
crunch_state = &thread->crunchstate;
switch (cmd) {
case THREAD_NOTIFY_FLUSH:
memset(crunch_state, 0, sizeof(*crunch_state));
/*
* FALLTHROUGH: Ensure we don't try to overwrite our newly
* initialised state information on the first fault.
*/
case THREAD_NOTIFY_EXIT:
crunch_task_release(thread);
break;
case THREAD_NOTIFY_SWITCH:
devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
/*
* We don't use ep93xx_syscon_swlocked_write() here
* because we are on the context switch path and
* preemption is already disabled.
*/
devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA;
__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
__raw_writel(devcfg, EP93XX_SYSCON_DEVCFG);
}
break;
}
return NOTIFY_DONE;
}
static struct notifier_block crunch_notifier_block = {
.notifier_call = crunch_do,
};
int __init crunch_init(void)
{
thread_register_notifier(&crunch_notifier_block);
elf_hwcap |= HWCAP_CRUNCH;
return 0;
}

110
arch/arm/mach-ep93xx/dma.c Normal file
View file

@ -0,0 +1,110 @@
/*
* arch/arm/mach-ep93xx/dma.c
*
* Platform support code for the EP93xx dmaengine driver.
*
* Copyright (C) 2011 Mika Westerberg
*
* This work is based on the original dma-m2p implementation with
* following copyrights:
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
* Copyright (C) 2006 Applied Data Systems
* Copyright (C) 2009 Ryan Mallon <rmallon@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/platform_data/dma-ep93xx.h>
#include <mach/hardware.h>
#include "soc.h"
#define DMA_CHANNEL(_name, _base, _irq) \
{ .name = (_name), .base = (_base), .irq = (_irq) }
/*
* DMA M2P channels.
*
* On the EP93xx chip the following peripherals my be allocated to the 10
* Memory to Internal Peripheral (M2P) channels (5 transmit + 5 receive).
*
* I2S contains 3 Tx and 3 Rx DMA Channels
* AAC contains 3 Tx and 3 Rx DMA Channels
* UART1 contains 1 Tx and 1 Rx DMA Channels
* UART2 contains 1 Tx and 1 Rx DMA Channels
* UART3 contains 1 Tx and 1 Rx DMA Channels
* IrDA contains 1 Tx and 1 Rx DMA Channels
*
* Registers are mapped statically in ep93xx_map_io().
*/
static struct ep93xx_dma_chan_data ep93xx_dma_m2p_channels[] = {
DMA_CHANNEL("m2p0", EP93XX_DMA_BASE + 0x0000, IRQ_EP93XX_DMAM2P0),
DMA_CHANNEL("m2p1", EP93XX_DMA_BASE + 0x0040, IRQ_EP93XX_DMAM2P1),
DMA_CHANNEL("m2p2", EP93XX_DMA_BASE + 0x0080, IRQ_EP93XX_DMAM2P2),
DMA_CHANNEL("m2p3", EP93XX_DMA_BASE + 0x00c0, IRQ_EP93XX_DMAM2P3),
DMA_CHANNEL("m2p4", EP93XX_DMA_BASE + 0x0240, IRQ_EP93XX_DMAM2P4),
DMA_CHANNEL("m2p5", EP93XX_DMA_BASE + 0x0200, IRQ_EP93XX_DMAM2P5),
DMA_CHANNEL("m2p6", EP93XX_DMA_BASE + 0x02c0, IRQ_EP93XX_DMAM2P6),
DMA_CHANNEL("m2p7", EP93XX_DMA_BASE + 0x0280, IRQ_EP93XX_DMAM2P7),
DMA_CHANNEL("m2p8", EP93XX_DMA_BASE + 0x0340, IRQ_EP93XX_DMAM2P8),
DMA_CHANNEL("m2p9", EP93XX_DMA_BASE + 0x0300, IRQ_EP93XX_DMAM2P9),
};
static struct ep93xx_dma_platform_data ep93xx_dma_m2p_data = {
.channels = ep93xx_dma_m2p_channels,
.num_channels = ARRAY_SIZE(ep93xx_dma_m2p_channels),
};
static struct platform_device ep93xx_dma_m2p_device = {
.name = "ep93xx-dma-m2p",
.id = -1,
.dev = {
.platform_data = &ep93xx_dma_m2p_data,
},
};
/*
* DMA M2M channels.
*
* There are 2 M2M channels which support memcpy/memset and in addition simple
* hardware requests from/to SSP and IDE. We do not implement an external
* hardware requests.
*
* Registers are mapped statically in ep93xx_map_io().
*/
static struct ep93xx_dma_chan_data ep93xx_dma_m2m_channels[] = {
DMA_CHANNEL("m2m0", EP93XX_DMA_BASE + 0x0100, IRQ_EP93XX_DMAM2M0),
DMA_CHANNEL("m2m1", EP93XX_DMA_BASE + 0x0140, IRQ_EP93XX_DMAM2M1),
};
static struct ep93xx_dma_platform_data ep93xx_dma_m2m_data = {
.channels = ep93xx_dma_m2m_channels,
.num_channels = ARRAY_SIZE(ep93xx_dma_m2m_channels),
};
static struct platform_device ep93xx_dma_m2m_device = {
.name = "ep93xx-dma-m2m",
.id = -1,
.dev = {
.platform_data = &ep93xx_dma_m2m_data,
},
};
static int __init ep93xx_dma_init(void)
{
platform_device_register(&ep93xx_dma_m2p_device);
platform_device_register(&ep93xx_dma_m2m_device);
return 0;
}
arch_initcall(ep93xx_dma_init);

View file

@ -0,0 +1,374 @@
/*
* arch/arm/mach-ep93xx/edb93xx.c
* Cirrus Logic EDB93xx Development Board support.
*
* EDB93XX, EDB9301, EDB9307A
* Copyright (C) 2008-2009 H Hartley Sweeten <hsweeten@visionengravers.com>
*
* EDB9302
* Copyright (C) 2006 George Kashperko <george@chas.com.ua>
*
* EDB9302A, EDB9315, EDB9315A
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* EDB9307
* Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
*
* EDB9312
* Copyright (C) 2006 Infosys Technologies Limited
* Toufeeq Hussain <toufeeq_hussain@infosys.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/spi/spi.h>
#include <sound/cs4271.h>
#include <mach/hardware.h>
#include <linux/platform_data/video-ep93xx.h>
#include <linux/platform_data/spi-ep93xx.h>
#include <mach/gpio-ep93xx.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "soc.h"
static void __init edb93xx_register_flash(void)
{
if (machine_is_edb9307() || machine_is_edb9312() ||
machine_is_edb9315()) {
ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
} else {
ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
}
}
static struct ep93xx_eth_data __initdata edb93xx_eth_data = {
.phy_id = 1,
};
/*************************************************************************
* EDB93xx i2c peripheral handling
*************************************************************************/
static struct i2c_gpio_platform_data __initdata edb93xx_i2c_gpio_data = {
.sda_pin = EP93XX_GPIO_LINE_EEDAT,
.sda_is_open_drain = 0,
.scl_pin = EP93XX_GPIO_LINE_EECLK,
.scl_is_open_drain = 0,
.udelay = 0, /* default to 100 kHz */
.timeout = 0, /* default to 100 ms */
};
static struct i2c_board_info __initdata edb93xxa_i2c_board_info[] = {
{
I2C_BOARD_INFO("isl1208", 0x6f),
},
};
static struct i2c_board_info __initdata edb93xx_i2c_board_info[] = {
{
I2C_BOARD_INFO("ds1337", 0x68),
},
};
static void __init edb93xx_register_i2c(void)
{
if (machine_is_edb9302a() || machine_is_edb9307a() ||
machine_is_edb9315a()) {
ep93xx_register_i2c(&edb93xx_i2c_gpio_data,
edb93xxa_i2c_board_info,
ARRAY_SIZE(edb93xxa_i2c_board_info));
} else if (machine_is_edb9302() || machine_is_edb9307()
|| machine_is_edb9312() || machine_is_edb9315()) {
ep93xx_register_i2c(&edb93xx_i2c_gpio_data,
edb93xx_i2c_board_info,
ARRAY_SIZE(edb93xx_i2c_board_info));
}
}
/*************************************************************************
* EDB93xx SPI peripheral handling
*************************************************************************/
static struct cs4271_platform_data edb93xx_cs4271_data = {
.gpio_nreset = -EINVAL, /* filled in later */
};
static int edb93xx_cs4271_hw_setup(struct spi_device *spi)
{
return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6,
GPIOF_OUT_INIT_HIGH, spi->modalias);
}
static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi)
{
gpio_free(EP93XX_GPIO_LINE_EGPIO6);
}
static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value);
}
static struct ep93xx_spi_chip_ops edb93xx_cs4271_hw = {
.setup = edb93xx_cs4271_hw_setup,
.cleanup = edb93xx_cs4271_hw_cleanup,
.cs_control = edb93xx_cs4271_hw_cs_control,
};
static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
{
.modalias = "cs4271",
.platform_data = &edb93xx_cs4271_data,
.controller_data = &edb93xx_cs4271_hw,
.max_speed_hz = 6000000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_3,
},
};
static struct ep93xx_spi_info edb93xx_spi_info __initdata = {
.num_chipselect = ARRAY_SIZE(edb93xx_spi_board_info),
};
static void __init edb93xx_register_spi(void)
{
if (machine_is_edb9301() || machine_is_edb9302())
edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO1;
else if (machine_is_edb9302a() || machine_is_edb9307a())
edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_H(2);
else if (machine_is_edb9315a())
edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14;
ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info,
ARRAY_SIZE(edb93xx_spi_board_info));
}
/*************************************************************************
* EDB93xx I2S
*************************************************************************/
static struct platform_device edb93xx_audio_device = {
.name = "edb93xx-audio",
.id = -1,
};
static int __init edb93xx_has_audio(void)
{
return (machine_is_edb9301() || machine_is_edb9302() ||
machine_is_edb9302a() || machine_is_edb9307a() ||
machine_is_edb9315a());
}
static void __init edb93xx_register_i2s(void)
{
if (edb93xx_has_audio()) {
ep93xx_register_i2s();
platform_device_register(&edb93xx_audio_device);
}
}
/*************************************************************************
* EDB93xx pwm
*************************************************************************/
static void __init edb93xx_register_pwm(void)
{
if (machine_is_edb9301() ||
machine_is_edb9302() || machine_is_edb9302a()) {
/* EP9301 and EP9302 only have pwm.1 (EGPIO14) */
ep93xx_register_pwm(0, 1);
} else if (machine_is_edb9307() || machine_is_edb9307a()) {
/* EP9307 only has pwm.0 (PWMOUT) */
ep93xx_register_pwm(1, 0);
} else {
/* EP9312 and EP9315 have both */
ep93xx_register_pwm(1, 1);
}
}
/*************************************************************************
* EDB93xx framebuffer
*************************************************************************/
static struct ep93xxfb_mach_info __initdata edb93xxfb_info = {
.num_modes = EP93XXFB_USE_MODEDB,
.bpp = 16,
.flags = 0,
};
static int __init edb93xx_has_fb(void)
{
/* These platforms have an ep93xx with video capability */
return machine_is_edb9307() || machine_is_edb9307a() ||
machine_is_edb9312() || machine_is_edb9315() ||
machine_is_edb9315a();
}
static void __init edb93xx_register_fb(void)
{
if (!edb93xx_has_fb())
return;
if (machine_is_edb9307a() || machine_is_edb9315a())
edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN0;
else
edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN3;
ep93xx_register_fb(&edb93xxfb_info);
}
/*************************************************************************
* EDB93xx IDE
*************************************************************************/
static int __init edb93xx_has_ide(void)
{
/*
* Although EDB9312 and EDB9315 do have IDE capability, they have
* INTRQ line wired as pull-up, which makes using IDE interface
* problematic.
*/
return machine_is_edb9312() || machine_is_edb9315() ||
machine_is_edb9315a();
}
static void __init edb93xx_register_ide(void)
{
if (!edb93xx_has_ide())
return;
ep93xx_register_ide();
}
static void __init edb93xx_init_machine(void)
{
ep93xx_init_devices();
edb93xx_register_flash();
ep93xx_register_eth(&edb93xx_eth_data, 1);
edb93xx_register_i2c();
edb93xx_register_spi();
edb93xx_register_i2s();
edb93xx_register_pwm();
edb93xx_register_fb();
edb93xx_register_ide();
}
#ifdef CONFIG_MACH_EDB9301
MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board")
/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = edb93xx_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EDB9302
MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
/* Maintainer: George Kashperko <george@chas.com.ua> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = edb93xx_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EDB9302A
MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = edb93xx_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EDB9307
MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = edb93xx_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EDB9307A
MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = edb93xx_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EDB9312
MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
/* Maintainer: Toufeeq Hussain <toufeeq_hussain@infosys.com> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = edb93xx_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EDB9315
MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = edb93xx_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EDB9315A
MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = edb93xx_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif

View file

@ -0,0 +1,45 @@
/*
* arch/arm/mach-ep93xx/gesbc9312.c
* Glomation GESBC-9312-sx support.
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/sizes.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "soc.h"
static struct ep93xx_eth_data __initdata gesbc9312_eth_data = {
.phy_id = 1,
};
static void __init gesbc9312_init_machine(void)
{
ep93xx_init_devices();
ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_8M);
ep93xx_register_eth(&gesbc9312_eth_data, 0);
}
MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = gesbc9312_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END

View file

@ -0,0 +1,41 @@
/*
* arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
*/
#ifndef __ASM_ARCH_EP93XX_REGS_H
#define __ASM_ARCH_EP93XX_REGS_H
/*
* EP93xx linux memory map:
*
* virt phys size
* fe800000 5M per-platform mappings
* fed00000 80800000 2M APB
* fef00000 80000000 1M AHB
*/
#define EP93XX_AHB_PHYS_BASE 0x80000000
#define EP93XX_AHB_VIRT_BASE 0xfef00000
#define EP93XX_AHB_SIZE 0x00100000
#define EP93XX_AHB_PHYS(x) (EP93XX_AHB_PHYS_BASE + (x))
#define EP93XX_AHB_IOMEM(x) IOMEM(EP93XX_AHB_VIRT_BASE + (x))
#define EP93XX_APB_PHYS_BASE 0x80800000
#define EP93XX_APB_VIRT_BASE 0xfed00000
#define EP93XX_APB_SIZE 0x00200000
#define EP93XX_APB_PHYS(x) (EP93XX_APB_PHYS_BASE + (x))
#define EP93XX_APB_IOMEM(x) IOMEM(EP93XX_APB_VIRT_BASE + (x))
/* APB UARTs */
#define EP93XX_UART1_PHYS_BASE EP93XX_APB_PHYS(0x000c0000)
#define EP93XX_UART1_BASE EP93XX_APB_IOMEM(0x000c0000)
#define EP93XX_UART2_PHYS_BASE EP93XX_APB_PHYS(0x000d0000)
#define EP93XX_UART2_BASE EP93XX_APB_IOMEM(0x000d0000)
#define EP93XX_UART3_PHYS_BASE EP93XX_APB_PHYS(0x000e0000)
#define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000)
#endif

View file

@ -0,0 +1,110 @@
/* Include file for the EP93XX GPIO controller machine specifics */
#ifndef __GPIO_EP93XX_H
#define __GPIO_EP93XX_H
#include <mach/ep93xx-regs.h>
#define EP93XX_GPIO_PHYS_BASE EP93XX_APB_PHYS(0x00040000)
#define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000)
#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x))
#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0)
#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc)
#define EP93XX_GPIO_EEDRIVE EP93XX_GPIO_REG(0xc8)
/* GPIO port A. */
#define EP93XX_GPIO_LINE_A(x) ((x) + 0)
#define EP93XX_GPIO_LINE_EGPIO0 EP93XX_GPIO_LINE_A(0)
#define EP93XX_GPIO_LINE_EGPIO1 EP93XX_GPIO_LINE_A(1)
#define EP93XX_GPIO_LINE_EGPIO2 EP93XX_GPIO_LINE_A(2)
#define EP93XX_GPIO_LINE_EGPIO3 EP93XX_GPIO_LINE_A(3)
#define EP93XX_GPIO_LINE_EGPIO4 EP93XX_GPIO_LINE_A(4)
#define EP93XX_GPIO_LINE_EGPIO5 EP93XX_GPIO_LINE_A(5)
#define EP93XX_GPIO_LINE_EGPIO6 EP93XX_GPIO_LINE_A(6)
#define EP93XX_GPIO_LINE_EGPIO7 EP93XX_GPIO_LINE_A(7)
/* GPIO port B. */
#define EP93XX_GPIO_LINE_B(x) ((x) + 8)
#define EP93XX_GPIO_LINE_EGPIO8 EP93XX_GPIO_LINE_B(0)
#define EP93XX_GPIO_LINE_EGPIO9 EP93XX_GPIO_LINE_B(1)
#define EP93XX_GPIO_LINE_EGPIO10 EP93XX_GPIO_LINE_B(2)
#define EP93XX_GPIO_LINE_EGPIO11 EP93XX_GPIO_LINE_B(3)
#define EP93XX_GPIO_LINE_EGPIO12 EP93XX_GPIO_LINE_B(4)
#define EP93XX_GPIO_LINE_EGPIO13 EP93XX_GPIO_LINE_B(5)
#define EP93XX_GPIO_LINE_EGPIO14 EP93XX_GPIO_LINE_B(6)
#define EP93XX_GPIO_LINE_EGPIO15 EP93XX_GPIO_LINE_B(7)
/* GPIO port C. */
#define EP93XX_GPIO_LINE_C(x) ((x) + 40)
#define EP93XX_GPIO_LINE_ROW0 EP93XX_GPIO_LINE_C(0)
#define EP93XX_GPIO_LINE_ROW1 EP93XX_GPIO_LINE_C(1)
#define EP93XX_GPIO_LINE_ROW2 EP93XX_GPIO_LINE_C(2)
#define EP93XX_GPIO_LINE_ROW3 EP93XX_GPIO_LINE_C(3)
#define EP93XX_GPIO_LINE_ROW4 EP93XX_GPIO_LINE_C(4)
#define EP93XX_GPIO_LINE_ROW5 EP93XX_GPIO_LINE_C(5)
#define EP93XX_GPIO_LINE_ROW6 EP93XX_GPIO_LINE_C(6)
#define EP93XX_GPIO_LINE_ROW7 EP93XX_GPIO_LINE_C(7)
/* GPIO port D. */
#define EP93XX_GPIO_LINE_D(x) ((x) + 24)
#define EP93XX_GPIO_LINE_COL0 EP93XX_GPIO_LINE_D(0)
#define EP93XX_GPIO_LINE_COL1 EP93XX_GPIO_LINE_D(1)
#define EP93XX_GPIO_LINE_COL2 EP93XX_GPIO_LINE_D(2)
#define EP93XX_GPIO_LINE_COL3 EP93XX_GPIO_LINE_D(3)
#define EP93XX_GPIO_LINE_COL4 EP93XX_GPIO_LINE_D(4)
#define EP93XX_GPIO_LINE_COL5 EP93XX_GPIO_LINE_D(5)
#define EP93XX_GPIO_LINE_COL6 EP93XX_GPIO_LINE_D(6)
#define EP93XX_GPIO_LINE_COL7 EP93XX_GPIO_LINE_D(7)
/* GPIO port E. */
#define EP93XX_GPIO_LINE_E(x) ((x) + 32)
#define EP93XX_GPIO_LINE_GRLED EP93XX_GPIO_LINE_E(0)
#define EP93XX_GPIO_LINE_RDLED EP93XX_GPIO_LINE_E(1)
#define EP93XX_GPIO_LINE_DIORn EP93XX_GPIO_LINE_E(2)
#define EP93XX_GPIO_LINE_IDECS1n EP93XX_GPIO_LINE_E(3)
#define EP93XX_GPIO_LINE_IDECS2n EP93XX_GPIO_LINE_E(4)
#define EP93XX_GPIO_LINE_IDEDA0 EP93XX_GPIO_LINE_E(5)
#define EP93XX_GPIO_LINE_IDEDA1 EP93XX_GPIO_LINE_E(6)
#define EP93XX_GPIO_LINE_IDEDA2 EP93XX_GPIO_LINE_E(7)
/* GPIO port F. */
#define EP93XX_GPIO_LINE_F(x) ((x) + 16)
#define EP93XX_GPIO_LINE_WP EP93XX_GPIO_LINE_F(0)
#define EP93XX_GPIO_LINE_MCCD1 EP93XX_GPIO_LINE_F(1)
#define EP93XX_GPIO_LINE_MCCD2 EP93XX_GPIO_LINE_F(2)
#define EP93XX_GPIO_LINE_MCBVD1 EP93XX_GPIO_LINE_F(3)
#define EP93XX_GPIO_LINE_MCBVD2 EP93XX_GPIO_LINE_F(4)
#define EP93XX_GPIO_LINE_VS1 EP93XX_GPIO_LINE_F(5)
#define EP93XX_GPIO_LINE_READY EP93XX_GPIO_LINE_F(6)
#define EP93XX_GPIO_LINE_VS2 EP93XX_GPIO_LINE_F(7)
/* GPIO port G. */
#define EP93XX_GPIO_LINE_G(x) ((x) + 48)
#define EP93XX_GPIO_LINE_EECLK EP93XX_GPIO_LINE_G(0)
#define EP93XX_GPIO_LINE_EEDAT EP93XX_GPIO_LINE_G(1)
#define EP93XX_GPIO_LINE_SLA0 EP93XX_GPIO_LINE_G(2)
#define EP93XX_GPIO_LINE_SLA1 EP93XX_GPIO_LINE_G(3)
#define EP93XX_GPIO_LINE_DD12 EP93XX_GPIO_LINE_G(4)
#define EP93XX_GPIO_LINE_DD13 EP93XX_GPIO_LINE_G(5)
#define EP93XX_GPIO_LINE_DD14 EP93XX_GPIO_LINE_G(6)
#define EP93XX_GPIO_LINE_DD15 EP93XX_GPIO_LINE_G(7)
/* GPIO port H. */
#define EP93XX_GPIO_LINE_H(x) ((x) + 56)
#define EP93XX_GPIO_LINE_DD0 EP93XX_GPIO_LINE_H(0)
#define EP93XX_GPIO_LINE_DD1 EP93XX_GPIO_LINE_H(1)
#define EP93XX_GPIO_LINE_DD2 EP93XX_GPIO_LINE_H(2)
#define EP93XX_GPIO_LINE_DD3 EP93XX_GPIO_LINE_H(3)
#define EP93XX_GPIO_LINE_DD4 EP93XX_GPIO_LINE_H(4)
#define EP93XX_GPIO_LINE_DD5 EP93XX_GPIO_LINE_H(5)
#define EP93XX_GPIO_LINE_DD6 EP93XX_GPIO_LINE_H(6)
#define EP93XX_GPIO_LINE_DD7 EP93XX_GPIO_LINE_H(7)
/* maximum value for gpio line identifiers */
#define EP93XX_GPIO_LINE_MAX EP93XX_GPIO_LINE_H(7)
/* maximum value for irq capable line identifiers */
#define EP93XX_GPIO_LINE_MAX_IRQ EP93XX_GPIO_LINE_F(7)
#endif /* __GPIO_EP93XX_H */

View file

@ -0,0 +1,24 @@
/*
* arch/arm/mach-ep93xx/include/mach/hardware.h
*/
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
#include <mach/platform.h>
/*
* The EP93xx has two external crystal oscillators. To generate the
* required high-frequency clocks, the processor uses two phase-locked-
* loops (PLLs) to multiply the incoming external clock signal to much
* higher frequencies that are then divided down by programmable dividers
* to produce the needed clocks. The PLLs operate independently of one
* another.
*/
#define EP93XX_EXT_CLK_RATE 14745600
#define EP93XX_EXT_RTC_RATE 32768
#define EP93XX_KEYTCHCLK_DIV4 (EP93XX_EXT_CLK_RATE / 4)
#define EP93XX_KEYTCHCLK_DIV16 (EP93XX_EXT_CLK_RATE / 16)
#endif

View file

@ -0,0 +1,78 @@
/*
* arch/arm/mach-ep93xx/include/mach/irqs.h
*/
#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H
#define IRQ_EP93XX_COMMRX 2
#define IRQ_EP93XX_COMMTX 3
#define IRQ_EP93XX_TIMER1 4
#define IRQ_EP93XX_TIMER2 5
#define IRQ_EP93XX_AACINTR 6
#define IRQ_EP93XX_DMAM2P0 7
#define IRQ_EP93XX_DMAM2P1 8
#define IRQ_EP93XX_DMAM2P2 9
#define IRQ_EP93XX_DMAM2P3 10
#define IRQ_EP93XX_DMAM2P4 11
#define IRQ_EP93XX_DMAM2P5 12
#define IRQ_EP93XX_DMAM2P6 13
#define IRQ_EP93XX_DMAM2P7 14
#define IRQ_EP93XX_DMAM2P8 15
#define IRQ_EP93XX_DMAM2P9 16
#define IRQ_EP93XX_DMAM2M0 17
#define IRQ_EP93XX_DMAM2M1 18
#define IRQ_EP93XX_GPIO0MUX 19
#define IRQ_EP93XX_GPIO1MUX 20
#define IRQ_EP93XX_GPIO2MUX 21
#define IRQ_EP93XX_GPIO3MUX 22
#define IRQ_EP93XX_UART1RX 23
#define IRQ_EP93XX_UART1TX 24
#define IRQ_EP93XX_UART2RX 25
#define IRQ_EP93XX_UART2TX 26
#define IRQ_EP93XX_UART3RX 27
#define IRQ_EP93XX_UART3TX 28
#define IRQ_EP93XX_KEY 29
#define IRQ_EP93XX_TOUCH 30
#define EP93XX_VIC1_VALID_IRQ_MASK 0x7ffffffc
#define IRQ_EP93XX_EXT0 32
#define IRQ_EP93XX_EXT1 33
#define IRQ_EP93XX_EXT2 34
#define IRQ_EP93XX_64HZ 35
#define IRQ_EP93XX_WATCHDOG 36
#define IRQ_EP93XX_RTC 37
#define IRQ_EP93XX_IRDA 38
#define IRQ_EP93XX_ETHERNET 39
#define IRQ_EP93XX_EXT3 40
#define IRQ_EP93XX_PROG 41
#define IRQ_EP93XX_1HZ 42
#define IRQ_EP93XX_VSYNC 43
#define IRQ_EP93XX_VIDEO_FIFO 44
#define IRQ_EP93XX_SSP1RX 45
#define IRQ_EP93XX_SSP1TX 46
#define IRQ_EP93XX_GPIO4MUX 47
#define IRQ_EP93XX_GPIO5MUX 48
#define IRQ_EP93XX_GPIO6MUX 49
#define IRQ_EP93XX_GPIO7MUX 50
#define IRQ_EP93XX_TIMER3 51
#define IRQ_EP93XX_UART1 52
#define IRQ_EP93XX_SSP 53
#define IRQ_EP93XX_UART2 54
#define IRQ_EP93XX_UART3 55
#define IRQ_EP93XX_USB 56
#define IRQ_EP93XX_ETHERNET_PME 57
#define IRQ_EP93XX_DSP 58
#define IRQ_EP93XX_GPIO_AB 59
#define IRQ_EP93XX_SAI 60
#define EP93XX_VIC2_VALID_IRQ_MASK 0x1fffffff
#define NR_EP93XX_IRQS (64 + 24)
#define EP93XX_BOARD_IRQ(x) (NR_EP93XX_IRQS + (x))
#define EP93XX_BOARD_IRQS 32
#define NR_IRQS (NR_EP93XX_IRQS + EP93XX_BOARD_IRQS)
#endif

View file

@ -0,0 +1,70 @@
/*
* arch/arm/mach-ep93xx/include/mach/platform.h
*/
#ifndef __ASSEMBLY__
#include <linux/reboot.h>
struct device;
struct i2c_gpio_platform_data;
struct i2c_board_info;
struct spi_board_info;
struct platform_device;
struct ep93xxfb_mach_info;
struct ep93xx_keypad_platform_data;
struct ep93xx_spi_info;
struct ep93xx_eth_data
{
unsigned char dev_addr[6];
unsigned char phy_id;
};
void ep93xx_map_io(void);
void ep93xx_init_irq(void);
#define EP93XX_CHIP_REV_D0 3
#define EP93XX_CHIP_REV_D1 4
#define EP93XX_CHIP_REV_E0 5
#define EP93XX_CHIP_REV_E1 6
#define EP93XX_CHIP_REV_E2 7
unsigned int ep93xx_chip_revision(void);
void ep93xx_register_flash(unsigned int width,
resource_size_t start, resource_size_t size);
void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
void ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
struct i2c_board_info *devices, int num);
void ep93xx_register_spi(struct ep93xx_spi_info *info,
struct spi_board_info *devices, int num);
void ep93xx_register_fb(struct ep93xxfb_mach_info *data);
void ep93xx_register_pwm(int pwm0, int pwm1);
int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
void ep93xx_pwm_release_gpio(struct platform_device *pdev);
void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data);
int ep93xx_keypad_acquire_gpio(struct platform_device *pdev);
void ep93xx_keypad_release_gpio(struct platform_device *pdev);
void ep93xx_register_i2s(void);
int ep93xx_i2s_acquire(void);
void ep93xx_i2s_release(void);
void ep93xx_register_ac97(void);
void ep93xx_register_ide(void);
int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
void ep93xx_ide_release_gpio(struct platform_device *pdev);
struct device *ep93xx_init_devices(void);
extern void ep93xx_timer_init(void);
void ep93xx_restart(enum reboot_mode, const char *);
void ep93xx_init_late(void);
#ifdef CONFIG_CRUNCH
int crunch_init(void);
#else
static inline int crunch_init(void) { return 0; }
#endif
#endif

View file

@ -0,0 +1,82 @@
/*
* arch/arm/mach-ep93xx/include/mach/uncompress.h
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#include <mach/ep93xx-regs.h>
static unsigned char __raw_readb(unsigned int ptr)
{
return *((volatile unsigned char *)ptr);
}
static unsigned int __raw_readl(unsigned int ptr)
{
return *((volatile unsigned int *)ptr);
}
static void __raw_writeb(unsigned char value, unsigned int ptr)
{
*((volatile unsigned char *)ptr) = value;
}
static void __raw_writel(unsigned int value, unsigned int ptr)
{
*((volatile unsigned int *)ptr) = value;
}
#define PHYS_UART_DATA (CONFIG_DEBUG_UART_PHYS + 0x00)
#define PHYS_UART_FLAG (CONFIG_DEBUG_UART_PHYS + 0x18)
#define UART_FLAG_TXFF 0x20
static inline void putc(int c)
{
int i;
for (i = 0; i < 10000; i++) {
/* Transmit fifo not full? */
if (!(__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF))
break;
}
__raw_writeb(c, PHYS_UART_DATA);
}
static inline void flush(void)
{
}
/*
* Some bootloaders don't turn off DMA from the ethernet MAC before
* jumping to linux, which means that we might end up with bits of RX
* status and packet data scribbled over the uncompressed kernel image.
* Work around this by resetting the ethernet MAC before we uncompress.
*/
#define PHYS_ETH_SELF_CTL 0x80010020
#define ETH_SELF_CTL_RESET 0x00000001
static void ethernet_reset(void)
{
unsigned int v;
/* Reset the ethernet MAC. */
v = __raw_readl(PHYS_ETH_SELF_CTL);
__raw_writel(v | ETH_SELF_CTL_RESET, PHYS_ETH_SELF_CTL);
/* Wait for reset to finish. */
while (__raw_readl(PHYS_ETH_SELF_CTL) & ETH_SELF_CTL_RESET)
;
}
static void arch_decomp_setup(void)
{
ethernet_reset();
}

View file

@ -0,0 +1,128 @@
/*
* linux/arch/arm/mach-ep93xx/micro9.c
*
* Copyright (C) 2006 Contec Steuerungstechnik & Automation GmbH
* Manfred Gruber <m.gruber@tirol.com>
* Copyright (C) 2009 Contec Steuerungstechnik & Automation GmbH
* Hubert Feurstein <hubert.feurstein@contec.at>
*
* 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/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "soc.h"
/*************************************************************************
* Micro9 NOR Flash
*
* Micro9-High has up to 64MB of 32-bit flash on CS1
* Micro9-Mid has up to 64MB of either 32-bit or 16-bit flash on CS1
* Micro9-Lite uses a separate MTD map driver for flash support
* Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1
*************************************************************************/
static unsigned int __init micro9_detect_bootwidth(void)
{
u32 v;
/* Detect the bus width of the external flash memory */
v = __raw_readl(EP93XX_SYSCON_SYSCFG);
if (v & EP93XX_SYSCON_SYSCFG_LCSN7)
return 4; /* 32-bit */
else
return 2; /* 16-bit */
}
static void __init micro9_register_flash(void)
{
unsigned int width;
if (machine_is_micro9())
width = 4;
else if (machine_is_micro9m() || machine_is_micro9s())
width = micro9_detect_bootwidth();
else
width = 0;
if (width)
ep93xx_register_flash(width, EP93XX_CS1_PHYS_BASE, SZ_64M);
}
/*************************************************************************
* Micro9 Ethernet
*************************************************************************/
static struct ep93xx_eth_data __initdata micro9_eth_data = {
.phy_id = 0x1f,
};
static void __init micro9_init_machine(void)
{
ep93xx_init_devices();
ep93xx_register_eth(&micro9_eth_data, 1);
micro9_register_flash();
}
#ifdef CONFIG_MACH_MICRO9H
MACHINE_START(MICRO9, "Contec Micro9-High")
/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = micro9_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_MICRO9M
MACHINE_START(MICRO9M, "Contec Micro9-Mid")
/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = micro9_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_MICRO9L
MACHINE_START(MICRO9L, "Contec Micro9-Lite")
/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = micro9_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
#ifdef CONFIG_MACH_MICRO9S
MACHINE_START(MICRO9S, "Contec Micro9-Slim")
/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = micro9_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif

View file

@ -0,0 +1,89 @@
/*
* arch/arm/mach-ep93xx/simone.c
* Simplemachines Sim.One support.
*
* Copyright (C) 2010 Ryan Mallon
*
* Based on the 2.6.24.7 support:
* Copyright (C) 2009 Simplemachines
* MMC support by Peter Ivanov <ivanovp@gmail.com>, 2007
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <mach/hardware.h>
#include <linux/platform_data/video-ep93xx.h>
#include <mach/gpio-ep93xx.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "soc.h"
static struct ep93xx_eth_data __initdata simone_eth_data = {
.phy_id = 1,
};
static struct ep93xxfb_mach_info __initdata simone_fb_info = {
.num_modes = EP93XXFB_USE_MODEDB,
.bpp = 16,
.flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
};
static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = {
.sda_pin = EP93XX_GPIO_LINE_EEDAT,
.sda_is_open_drain = 0,
.scl_pin = EP93XX_GPIO_LINE_EECLK,
.scl_is_open_drain = 0,
.udelay = 0,
.timeout = 0,
};
static struct i2c_board_info __initdata simone_i2c_board_info[] = {
{
I2C_BOARD_INFO("ds1337", 0x68),
},
};
static struct platform_device simone_audio_device = {
.name = "simone-audio",
.id = -1,
};
static void __init simone_register_audio(void)
{
ep93xx_register_ac97();
platform_device_register(&simone_audio_device);
}
static void __init simone_init_machine(void)
{
ep93xx_init_devices();
ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_8M);
ep93xx_register_eth(&simone_eth_data, 1);
ep93xx_register_fb(&simone_fb_info);
ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
ARRAY_SIZE(simone_i2c_board_info));
simone_register_audio();
}
MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
/* Maintainer: Ryan Mallon */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = simone_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END

View file

@ -0,0 +1,182 @@
/*
* arch/arm/mach-ep93xx/snappercl15.c
* Bluewater Systems Snapper CL15 system module
*
* Copyright (C) 2009 Bluewater Systems Ltd
* Author: Ryan Mallon
*
* NAND code adapted from driver by:
* Andre Renaud <andre@bluewatersys.com>
* James R. McKaskill
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
*/
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/fb.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <mach/hardware.h>
#include <linux/platform_data/video-ep93xx.h>
#include <mach/gpio-ep93xx.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "soc.h"
#define SNAPPERCL15_NAND_BASE (EP93XX_CS7_PHYS_BASE + SZ_16M)
#define SNAPPERCL15_NAND_WPN (1 << 8) /* Write protect (active low) */
#define SNAPPERCL15_NAND_ALE (1 << 9) /* Address latch */
#define SNAPPERCL15_NAND_CLE (1 << 10) /* Command latch */
#define SNAPPERCL15_NAND_CEN (1 << 11) /* Chip enable (active low) */
#define SNAPPERCL15_NAND_RDY (1 << 14) /* Device ready */
#define NAND_CTRL_ADDR(chip) (chip->IO_ADDR_W + 0x40)
static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv;
static u16 nand_state = SNAPPERCL15_NAND_WPN;
u16 set;
if (ctrl & NAND_CTRL_CHANGE) {
set = SNAPPERCL15_NAND_CEN | SNAPPERCL15_NAND_WPN;
if (ctrl & NAND_NCE)
set &= ~SNAPPERCL15_NAND_CEN;
if (ctrl & NAND_CLE)
set |= SNAPPERCL15_NAND_CLE;
if (ctrl & NAND_ALE)
set |= SNAPPERCL15_NAND_ALE;
nand_state &= ~(SNAPPERCL15_NAND_CEN |
SNAPPERCL15_NAND_CLE |
SNAPPERCL15_NAND_ALE);
nand_state |= set;
__raw_writew(nand_state, NAND_CTRL_ADDR(chip));
}
if (cmd != NAND_CMD_NONE)
__raw_writew((cmd & 0xff) | nand_state, chip->IO_ADDR_W);
}
static int snappercl15_nand_dev_ready(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd->priv;
return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY);
}
static struct mtd_partition snappercl15_nand_parts[] = {
{
.name = "Kernel",
.offset = 0,
.size = SZ_2M,
},
{
.name = "Filesystem",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
static struct platform_nand_data snappercl15_nand_data = {
.chip = {
.nr_chips = 1,
.partitions = snappercl15_nand_parts,
.nr_partitions = ARRAY_SIZE(snappercl15_nand_parts),
.chip_delay = 25,
},
.ctrl = {
.dev_ready = snappercl15_nand_dev_ready,
.cmd_ctrl = snappercl15_nand_cmd_ctrl,
},
};
static struct resource snappercl15_nand_resource[] = {
{
.start = SNAPPERCL15_NAND_BASE,
.end = SNAPPERCL15_NAND_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device snappercl15_nand_device = {
.name = "gen_nand",
.id = -1,
.dev.platform_data = &snappercl15_nand_data,
.resource = snappercl15_nand_resource,
.num_resources = ARRAY_SIZE(snappercl15_nand_resource),
};
static struct ep93xx_eth_data __initdata snappercl15_eth_data = {
.phy_id = 1,
};
static struct i2c_gpio_platform_data __initdata snappercl15_i2c_gpio_data = {
.sda_pin = EP93XX_GPIO_LINE_EEDAT,
.sda_is_open_drain = 0,
.scl_pin = EP93XX_GPIO_LINE_EECLK,
.scl_is_open_drain = 0,
.udelay = 0,
.timeout = 0,
};
static struct i2c_board_info __initdata snappercl15_i2c_data[] = {
{
/* Audio codec */
I2C_BOARD_INFO("tlv320aic23", 0x1a),
},
};
static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = {
.num_modes = EP93XXFB_USE_MODEDB,
.bpp = 16,
};
static struct platform_device snappercl15_audio_device = {
.name = "snappercl15-audio",
.id = -1,
};
static void __init snappercl15_register_audio(void)
{
ep93xx_register_i2s();
platform_device_register(&snappercl15_audio_device);
}
static void __init snappercl15_init_machine(void)
{
ep93xx_init_devices();
ep93xx_register_eth(&snappercl15_eth_data, 1);
ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data,
ARRAY_SIZE(snappercl15_i2c_data));
ep93xx_register_fb(&snappercl15_fb_info);
snappercl15_register_audio();
platform_device_register(&snappercl15_nand_device);
}
MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
/* Maintainer: Ryan Mallon */
.atag_offset = 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = snappercl15_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END

214
arch/arm/mach-ep93xx/soc.h Normal file
View file

@ -0,0 +1,214 @@
/*
* arch/arm/mach-ep93xx/soc.h
*
* Copyright (C) 2012 Open Kernel Labs <www.ok-labs.com>
* Copyright (C) 2012 Ryan Mallon <rmallon@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#ifndef _EP93XX_SOC_H
#define _EP93XX_SOC_H
#include <mach/ep93xx-regs.h>
/*
* EP93xx Physical Memory Map:
*
* The ASDO pin is sampled at system reset to select a synchronous or
* asynchronous boot configuration. When ASDO is "1" (i.e. pulled-up)
* the synchronous boot mode is selected. When ASDO is "0" (i.e
* pulled-down) the asynchronous boot mode is selected.
*
* In synchronous boot mode nSDCE3 is decoded starting at physical address
* 0x00000000 and nCS0 is decoded starting at 0xf0000000. For asynchronous
* boot mode they are swapped with nCS0 decoded at 0x00000000 ann nSDCE3
* decoded at 0xf0000000.
*
* There is known errata for the EP93xx dealing with External Memory
* Configurations. Please refer to "AN273: EP93xx Silicon Rev E Design
* Guidelines" for more information. This document can be found at:
*
* http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
*/
#define EP93XX_CS0_PHYS_BASE_ASYNC 0x00000000 /* ASDO Pin = 0 */
#define EP93XX_SDCE3_PHYS_BASE_SYNC 0x00000000 /* ASDO Pin = 1 */
#define EP93XX_CS1_PHYS_BASE 0x10000000
#define EP93XX_CS2_PHYS_BASE 0x20000000
#define EP93XX_CS3_PHYS_BASE 0x30000000
#define EP93XX_PCMCIA_PHYS_BASE 0x40000000
#define EP93XX_CS6_PHYS_BASE 0x60000000
#define EP93XX_CS7_PHYS_BASE 0x70000000
#define EP93XX_SDCE0_PHYS_BASE 0xc0000000
#define EP93XX_SDCE1_PHYS_BASE 0xd0000000
#define EP93XX_SDCE2_PHYS_BASE 0xe0000000
#define EP93XX_SDCE3_PHYS_BASE_ASYNC 0xf0000000 /* ASDO Pin = 0 */
#define EP93XX_CS0_PHYS_BASE_SYNC 0xf0000000 /* ASDO Pin = 1 */
/* AHB peripherals */
#define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000)
#define EP93XX_ETHERNET_PHYS_BASE EP93XX_AHB_PHYS(0x00010000)
#define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000)
#define EP93XX_USB_PHYS_BASE EP93XX_AHB_PHYS(0x00020000)
#define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000)
#define EP93XX_RASTER_PHYS_BASE EP93XX_AHB_PHYS(0x00030000)
#define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000)
#define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000)
#define EP93XX_SDRAM_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00060000)
#define EP93XX_PCMCIA_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00080000)
#define EP93XX_BOOT_ROM_BASE EP93XX_AHB_IOMEM(0x00090000)
#define EP93XX_IDE_PHYS_BASE EP93XX_AHB_PHYS(0x000a0000)
#define EP93XX_IDE_BASE EP93XX_AHB_IOMEM(0x000a0000)
#define EP93XX_VIC1_BASE EP93XX_AHB_IOMEM(0x000b0000)
#define EP93XX_VIC2_BASE EP93XX_AHB_IOMEM(0x000c0000)
/* APB peripherals */
#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000)
#define EP93XX_I2S_PHYS_BASE EP93XX_APB_PHYS(0x00020000)
#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)
#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000)
#define EP93XX_AAC_PHYS_BASE EP93XX_APB_PHYS(0x00080000)
#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000)
#define EP93XX_SPI_PHYS_BASE EP93XX_APB_PHYS(0x000a0000)
#define EP93XX_SPI_BASE EP93XX_APB_IOMEM(0x000a0000)
#define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000)
#define EP93XX_KEY_MATRIX_PHYS_BASE EP93XX_APB_PHYS(0x000f0000)
#define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000)
#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000)
#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000)
#define EP93XX_PWM_PHYS_BASE EP93XX_APB_PHYS(0x00110000)
#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000)
#define EP93XX_RTC_PHYS_BASE EP93XX_APB_PHYS(0x00120000)
#define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000)
#define EP93XX_WATCHDOG_PHYS_BASE EP93XX_APB_PHYS(0x00140000)
#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000)
/* System controller */
#define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000)
#define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x))
#define EP93XX_SYSCON_POWER_STATE EP93XX_SYSCON_REG(0x00)
#define EP93XX_SYSCON_PWRCNT EP93XX_SYSCON_REG(0x04)
#define EP93XX_SYSCON_PWRCNT_FIR_EN (1<<31)
#define EP93XX_SYSCON_PWRCNT_UARTBAUD (1<<29)
#define EP93XX_SYSCON_PWRCNT_USH_EN (1<<28)
#define EP93XX_SYSCON_PWRCNT_DMA_M2M1 (1<<27)
#define EP93XX_SYSCON_PWRCNT_DMA_M2M0 (1<<26)
#define EP93XX_SYSCON_PWRCNT_DMA_M2P8 (1<<25)
#define EP93XX_SYSCON_PWRCNT_DMA_M2P9 (1<<24)
#define EP93XX_SYSCON_PWRCNT_DMA_M2P6 (1<<23)
#define EP93XX_SYSCON_PWRCNT_DMA_M2P7 (1<<22)
#define EP93XX_SYSCON_PWRCNT_DMA_M2P4 (1<<21)
#define EP93XX_SYSCON_PWRCNT_DMA_M2P5 (1<<20)
#define EP93XX_SYSCON_PWRCNT_DMA_M2P2 (1<<19)
#define EP93XX_SYSCON_PWRCNT_DMA_M2P3 (1<<18)
#define EP93XX_SYSCON_PWRCNT_DMA_M2P0 (1<<17)
#define EP93XX_SYSCON_PWRCNT_DMA_M2P1 (1<<16)
#define EP93XX_SYSCON_HALT EP93XX_SYSCON_REG(0x08)
#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c)
#define EP93XX_SYSCON_CLKSET1 EP93XX_SYSCON_REG(0x20)
#define EP93XX_SYSCON_CLKSET1_NBYP1 (1<<23)
#define EP93XX_SYSCON_CLKSET2 EP93XX_SYSCON_REG(0x24)
#define EP93XX_SYSCON_CLKSET2_NBYP2 (1<<19)
#define EP93XX_SYSCON_CLKSET2_PLL2_EN (1<<18)
#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80)
#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31)
#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30)
#define EP93XX_SYSCON_DEVCFG_D0ONG (1<<29)
#define EP93XX_SYSCON_DEVCFG_IONU2 (1<<28)
#define EP93XX_SYSCON_DEVCFG_GONK (1<<27)
#define EP93XX_SYSCON_DEVCFG_TONG (1<<26)
#define EP93XX_SYSCON_DEVCFG_MONG (1<<25)
#define EP93XX_SYSCON_DEVCFG_U3EN (1<<24)
#define EP93XX_SYSCON_DEVCFG_CPENA (1<<23)
#define EP93XX_SYSCON_DEVCFG_A2ONG (1<<22)
#define EP93XX_SYSCON_DEVCFG_A1ONG (1<<21)
#define EP93XX_SYSCON_DEVCFG_U2EN (1<<20)
#define EP93XX_SYSCON_DEVCFG_EXVC (1<<19)
#define EP93XX_SYSCON_DEVCFG_U1EN (1<<18)
#define EP93XX_SYSCON_DEVCFG_TIN (1<<17)
#define EP93XX_SYSCON_DEVCFG_HC3IN (1<<15)
#define EP93XX_SYSCON_DEVCFG_HC3EN (1<<14)
#define EP93XX_SYSCON_DEVCFG_HC1IN (1<<13)
#define EP93XX_SYSCON_DEVCFG_HC1EN (1<<12)
#define EP93XX_SYSCON_DEVCFG_HONIDE (1<<11)
#define EP93XX_SYSCON_DEVCFG_GONIDE (1<<10)
#define EP93XX_SYSCON_DEVCFG_PONG (1<<9)
#define EP93XX_SYSCON_DEVCFG_EONIDE (1<<8)
#define EP93XX_SYSCON_DEVCFG_I2SONSSP (1<<7)
#define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6)
#define EP93XX_SYSCON_DEVCFG_RASONP3 (1<<4)
#define EP93XX_SYSCON_DEVCFG_RAS (1<<3)
#define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2)
#define EP93XX_SYSCON_DEVCFG_KEYS (1<<1)
#define EP93XX_SYSCON_DEVCFG_SHENA (1<<0)
#define EP93XX_SYSCON_VIDCLKDIV EP93XX_SYSCON_REG(0x84)
#define EP93XX_SYSCON_CLKDIV_ENABLE (1<<15)
#define EP93XX_SYSCON_CLKDIV_ESEL (1<<14)
#define EP93XX_SYSCON_CLKDIV_PSEL (1<<13)
#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8
#define EP93XX_SYSCON_I2SCLKDIV EP93XX_SYSCON_REG(0x8c)
#define EP93XX_SYSCON_I2SCLKDIV_SENA (1<<31)
#define EP93XX_SYSCON_I2SCLKDIV_ORIDE (1<<29)
#define EP93XX_SYSCON_I2SCLKDIV_SPOL (1<<19)
#define EP93XX_I2SCLKDIV_SDIV (1 << 16)
#define EP93XX_I2SCLKDIV_LRDIV32 (0 << 17)
#define EP93XX_I2SCLKDIV_LRDIV64 (1 << 17)
#define EP93XX_I2SCLKDIV_LRDIV128 (2 << 17)
#define EP93XX_I2SCLKDIV_LRDIV_MASK (3 << 17)
#define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90)
#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31)
#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)
#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0)
#define EP93XX_SYSCON_SYSCFG EP93XX_SYSCON_REG(0x9c)
#define EP93XX_SYSCON_SYSCFG_REV_MASK (0xf0000000)
#define EP93XX_SYSCON_SYSCFG_REV_SHIFT (28)
#define EP93XX_SYSCON_SYSCFG_SBOOT (1<<8)
#define EP93XX_SYSCON_SYSCFG_LCSN7 (1<<7)
#define EP93XX_SYSCON_SYSCFG_LCSN6 (1<<6)
#define EP93XX_SYSCON_SYSCFG_LASDO (1<<5)
#define EP93XX_SYSCON_SYSCFG_LEEDA (1<<4)
#define EP93XX_SYSCON_SYSCFG_LEECLK (1<<3)
#define EP93XX_SYSCON_SYSCFG_LCSN2 (1<<1)
#define EP93XX_SYSCON_SYSCFG_LCSN1 (1<<0)
#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
/* EP93xx System Controller software locked register write */
void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg);
void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits);
static inline void ep93xx_devcfg_set_bits(unsigned int bits)
{
ep93xx_devcfg_set_clear(bits, 0x00);
}
static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
{
ep93xx_devcfg_set_clear(0x00, bits);
}
#endif /* _EP93XX_SOC_H */

View file

@ -0,0 +1,252 @@
/*
* arch/arm/mach-ep93xx/ts72xx.c
* Technologic Systems TS72xx SBC support.
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/m48t86.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
#include "soc.h"
#include "ts72xx.h"
static struct map_desc ts72xx_io_desc[] __initdata = {
{
.virtual = (unsigned long)TS72XX_MODEL_VIRT_BASE,
.pfn = __phys_to_pfn(TS72XX_MODEL_PHYS_BASE),
.length = TS72XX_MODEL_SIZE,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)TS72XX_OPTIONS_VIRT_BASE,
.pfn = __phys_to_pfn(TS72XX_OPTIONS_PHYS_BASE),
.length = TS72XX_OPTIONS_SIZE,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)TS72XX_OPTIONS2_VIRT_BASE,
.pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
.length = TS72XX_OPTIONS2_SIZE,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)TS72XX_RTC_INDEX_VIRT_BASE,
.pfn = __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE),
.length = TS72XX_RTC_INDEX_SIZE,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)TS72XX_RTC_DATA_VIRT_BASE,
.pfn = __phys_to_pfn(TS72XX_RTC_DATA_PHYS_BASE),
.length = TS72XX_RTC_DATA_SIZE,
.type = MT_DEVICE,
}
};
static void __init ts72xx_map_io(void)
{
ep93xx_map_io();
iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc));
}
/*************************************************************************
* NAND flash
*************************************************************************/
#define TS72XX_NAND_CONTROL_ADDR_LINE 22 /* 0xN0400000 */
#define TS72XX_NAND_BUSY_ADDR_LINE 23 /* 0xN0800000 */
static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
int cmd, unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv;
if (ctrl & NAND_CTRL_CHANGE) {
void __iomem *addr = chip->IO_ADDR_R;
unsigned char bits;
addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE);
bits = __raw_readb(addr) & ~0x07;
bits |= (ctrl & NAND_NCE) << 2; /* bit 0 -> bit 2 */
bits |= (ctrl & NAND_CLE); /* bit 1 -> bit 1 */
bits |= (ctrl & NAND_ALE) >> 2; /* bit 2 -> bit 0 */
__raw_writeb(bits, addr);
}
if (cmd != NAND_CMD_NONE)
__raw_writeb(cmd, chip->IO_ADDR_W);
}
static int ts72xx_nand_device_ready(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd->priv;
void __iomem *addr = chip->IO_ADDR_R;
addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE);
return !!(__raw_readb(addr) & 0x20);
}
#define TS72XX_BOOTROM_PART_SIZE (SZ_16K)
#define TS72XX_REDBOOT_PART_SIZE (SZ_2M + SZ_1M)
static struct mtd_partition ts72xx_nand_parts[] = {
{
.name = "TS-BOOTROM",
.offset = 0,
.size = TS72XX_BOOTROM_PART_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
.name = "Linux",
.offset = MTDPART_OFS_RETAIN,
.size = TS72XX_REDBOOT_PART_SIZE,
/* leave so much for last partition */
}, {
.name = "RedBoot",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
};
static struct platform_nand_data ts72xx_nand_data = {
.chip = {
.nr_chips = 1,
.chip_offset = 0,
.chip_delay = 15,
.partitions = ts72xx_nand_parts,
.nr_partitions = ARRAY_SIZE(ts72xx_nand_parts),
},
.ctrl = {
.cmd_ctrl = ts72xx_nand_hwcontrol,
.dev_ready = ts72xx_nand_device_ready,
},
};
static struct resource ts72xx_nand_resource[] = {
{
.start = 0, /* filled in later */
.end = 0, /* filled in later */
.flags = IORESOURCE_MEM,
},
};
static struct platform_device ts72xx_nand_flash = {
.name = "gen_nand",
.id = -1,
.dev.platform_data = &ts72xx_nand_data,
.resource = ts72xx_nand_resource,
.num_resources = ARRAY_SIZE(ts72xx_nand_resource),
};
static void __init ts72xx_register_flash(void)
{
/*
* TS7200 has NOR flash all other TS72xx board have NAND flash.
*/
if (board_is_ts7200()) {
ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
} else {
resource_size_t start;
if (is_ts9420_installed())
start = EP93XX_CS7_PHYS_BASE;
else
start = EP93XX_CS6_PHYS_BASE;
ts72xx_nand_resource[0].start = start;
ts72xx_nand_resource[0].end = start + SZ_16M - 1;
platform_device_register(&ts72xx_nand_flash);
}
}
static unsigned char ts72xx_rtc_readbyte(unsigned long addr)
{
__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE);
}
static void ts72xx_rtc_writebyte(unsigned char value, unsigned long addr)
{
__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
__raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE);
}
static struct m48t86_ops ts72xx_rtc_ops = {
.readbyte = ts72xx_rtc_readbyte,
.writebyte = ts72xx_rtc_writebyte,
};
static struct platform_device ts72xx_rtc_device = {
.name = "rtc-m48t86",
.id = -1,
.dev = {
.platform_data = &ts72xx_rtc_ops,
},
.num_resources = 0,
};
static struct resource ts72xx_wdt_resources[] = {
{
.start = TS72XX_WDT_CONTROL_PHYS_BASE,
.end = TS72XX_WDT_CONTROL_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = TS72XX_WDT_FEED_PHYS_BASE,
.end = TS72XX_WDT_FEED_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device ts72xx_wdt_device = {
.name = "ts72xx-wdt",
.id = -1,
.num_resources = ARRAY_SIZE(ts72xx_wdt_resources),
.resource = ts72xx_wdt_resources,
};
static struct ep93xx_eth_data __initdata ts72xx_eth_data = {
.phy_id = 1,
};
static void __init ts72xx_init_machine(void)
{
ep93xx_init_devices();
ts72xx_register_flash();
platform_device_register(&ts72xx_rtc_device);
platform_device_register(&ts72xx_wdt_device);
ep93xx_register_eth(&ts72xx_eth_data, 1);
}
MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
.atag_offset = 0x100,
.map_io = ts72xx_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = ts72xx_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END

View file

@ -0,0 +1,98 @@
/*
* arch/arm/mach-ep93xx/include/mach/ts72xx.h
*/
/*
* TS72xx memory map:
*
* virt phys size
* febff000 22000000 4K model number register (bits 0-2)
* febfe000 22400000 4K options register
* febfd000 22800000 4K options register #2
* febf9000 10800000 4K TS-5620 RTC index register
* febf8000 11700000 4K TS-5620 RTC data register
*/
#define TS72XX_MODEL_PHYS_BASE 0x22000000
#define TS72XX_MODEL_VIRT_BASE IOMEM(0xfebff000)
#define TS72XX_MODEL_SIZE 0x00001000
#define TS72XX_MODEL_TS7200 0x00
#define TS72XX_MODEL_TS7250 0x01
#define TS72XX_MODEL_TS7260 0x02
#define TS72XX_MODEL_TS7300 0x03
#define TS72XX_MODEL_TS7400 0x04
#define TS72XX_MODEL_MASK 0x07
#define TS72XX_OPTIONS_PHYS_BASE 0x22400000
#define TS72XX_OPTIONS_VIRT_BASE IOMEM(0xfebfe000)
#define TS72XX_OPTIONS_SIZE 0x00001000
#define TS72XX_OPTIONS_COM2_RS485 0x02
#define TS72XX_OPTIONS_MAX197 0x01
#define TS72XX_OPTIONS2_PHYS_BASE 0x22800000
#define TS72XX_OPTIONS2_VIRT_BASE IOMEM(0xfebfd000)
#define TS72XX_OPTIONS2_SIZE 0x00001000
#define TS72XX_OPTIONS2_TS9420 0x04
#define TS72XX_OPTIONS2_TS9420_BOOT 0x02
#define TS72XX_RTC_INDEX_VIRT_BASE IOMEM(0xfebf9000)
#define TS72XX_RTC_INDEX_PHYS_BASE 0x10800000
#define TS72XX_RTC_INDEX_SIZE 0x00001000
#define TS72XX_RTC_DATA_VIRT_BASE IOMEM(0xfebf8000)
#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000
#define TS72XX_RTC_DATA_SIZE 0x00001000
#define TS72XX_WDT_CONTROL_PHYS_BASE 0x23800000
#define TS72XX_WDT_FEED_PHYS_BASE 0x23c00000
#ifndef __ASSEMBLY__
static inline int ts72xx_model(void)
{
return __raw_readb(TS72XX_MODEL_VIRT_BASE) & TS72XX_MODEL_MASK;
}
static inline int board_is_ts7200(void)
{
return ts72xx_model() == TS72XX_MODEL_TS7200;
}
static inline int board_is_ts7250(void)
{
return ts72xx_model() == TS72XX_MODEL_TS7250;
}
static inline int board_is_ts7260(void)
{
return ts72xx_model() == TS72XX_MODEL_TS7260;
}
static inline int board_is_ts7300(void)
{
return ts72xx_model() == TS72XX_MODEL_TS7300;
}
static inline int board_is_ts7400(void)
{
return ts72xx_model() == TS72XX_MODEL_TS7400;
}
static inline int is_max197_installed(void)
{
return !!(__raw_readb(TS72XX_OPTIONS_VIRT_BASE) &
TS72XX_OPTIONS_MAX197);
}
static inline int is_ts9420_installed(void)
{
return !!(__raw_readb(TS72XX_OPTIONS2_VIRT_BASE) &
TS72XX_OPTIONS2_TS9420);
}
#endif

View file

@ -0,0 +1,323 @@
/*
* arch/arm/mach-ep93xx/vision_ep9307.c
* Vision Engraving Systems EP9307 SoM support.
*
* Copyright (C) 2008-2011 Vision Engraving Systems
* H Hartley Sweeten <hsweeten@visionengravers.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/fb.h>
#include <linux/io.h>
#include <linux/mtd/partitions.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/platform_data/pca953x.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/spi/mmc_spi.h>
#include <linux/mmc/host.h>
#include <mach/hardware.h>
#include <linux/platform_data/video-ep93xx.h>
#include <linux/platform_data/spi-ep93xx.h>
#include <mach/gpio-ep93xx.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
#include "soc.h"
/*************************************************************************
* Static I/O mappings for the FPGA
*************************************************************************/
#define VISION_PHYS_BASE EP93XX_CS7_PHYS_BASE
#define VISION_VIRT_BASE 0xfebff000
static struct map_desc vision_io_desc[] __initdata = {
{
.virtual = VISION_VIRT_BASE,
.pfn = __phys_to_pfn(VISION_PHYS_BASE),
.length = SZ_4K,
.type = MT_DEVICE,
},
};
static void __init vision_map_io(void)
{
ep93xx_map_io();
iotable_init(vision_io_desc, ARRAY_SIZE(vision_io_desc));
}
/*************************************************************************
* Ethernet
*************************************************************************/
static struct ep93xx_eth_data vision_eth_data __initdata = {
.phy_id = 1,
};
/*************************************************************************
* Framebuffer
*************************************************************************/
#define VISION_LCD_ENABLE EP93XX_GPIO_LINE_EGPIO1
static int vision_lcd_setup(struct platform_device *pdev)
{
int err;
err = gpio_request_one(VISION_LCD_ENABLE, GPIOF_INIT_HIGH,
dev_name(&pdev->dev));
if (err)
return err;
ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_RAS |
EP93XX_SYSCON_DEVCFG_RASONP3 |
EP93XX_SYSCON_DEVCFG_EXVC);
return 0;
}
static void vision_lcd_teardown(struct platform_device *pdev)
{
gpio_free(VISION_LCD_ENABLE);
}
static void vision_lcd_blank(int blank_mode, struct fb_info *info)
{
if (blank_mode)
gpio_set_value(VISION_LCD_ENABLE, 0);
else
gpio_set_value(VISION_LCD_ENABLE, 1);
}
static struct ep93xxfb_mach_info ep93xxfb_info __initdata = {
.num_modes = EP93XXFB_USE_MODEDB,
.bpp = 16,
.flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
.setup = vision_lcd_setup,
.teardown = vision_lcd_teardown,
.blank = vision_lcd_blank,
};
/*************************************************************************
* GPIO Expanders
*************************************************************************/
#define PCA9539_74_GPIO_BASE (EP93XX_GPIO_LINE_MAX + 1)
#define PCA9539_75_GPIO_BASE (PCA9539_74_GPIO_BASE + 16)
#define PCA9539_76_GPIO_BASE (PCA9539_75_GPIO_BASE + 16)
#define PCA9539_77_GPIO_BASE (PCA9539_76_GPIO_BASE + 16)
static struct pca953x_platform_data pca953x_74_gpio_data = {
.gpio_base = PCA9539_74_GPIO_BASE,
.irq_base = EP93XX_BOARD_IRQ(0),
};
static struct pca953x_platform_data pca953x_75_gpio_data = {
.gpio_base = PCA9539_75_GPIO_BASE,
.irq_base = -1,
};
static struct pca953x_platform_data pca953x_76_gpio_data = {
.gpio_base = PCA9539_76_GPIO_BASE,
.irq_base = -1,
};
static struct pca953x_platform_data pca953x_77_gpio_data = {
.gpio_base = PCA9539_77_GPIO_BASE,
.irq_base = -1,
};
/*************************************************************************
* I2C Bus
*************************************************************************/
static struct i2c_gpio_platform_data vision_i2c_gpio_data __initdata = {
.sda_pin = EP93XX_GPIO_LINE_EEDAT,
.scl_pin = EP93XX_GPIO_LINE_EECLK,
};
static struct i2c_board_info vision_i2c_info[] __initdata = {
{
I2C_BOARD_INFO("isl1208", 0x6f),
.irq = IRQ_EP93XX_EXT1,
}, {
I2C_BOARD_INFO("pca9539", 0x74),
.platform_data = &pca953x_74_gpio_data,
}, {
I2C_BOARD_INFO("pca9539", 0x75),
.platform_data = &pca953x_75_gpio_data,
}, {
I2C_BOARD_INFO("pca9539", 0x76),
.platform_data = &pca953x_76_gpio_data,
}, {
I2C_BOARD_INFO("pca9539", 0x77),
.platform_data = &pca953x_77_gpio_data,
},
};
/*************************************************************************
* SPI Flash
*************************************************************************/
#define VISION_SPI_FLASH_CS EP93XX_GPIO_LINE_EGPIO7
static struct mtd_partition vision_spi_flash_partitions[] = {
{
.name = "SPI bootstrap",
.offset = 0,
.size = SZ_4K,
}, {
.name = "Bootstrap config",
.offset = MTDPART_OFS_APPEND,
.size = SZ_4K,
}, {
.name = "System config",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
static struct flash_platform_data vision_spi_flash_data = {
.name = "SPI Flash",
.parts = vision_spi_flash_partitions,
.nr_parts = ARRAY_SIZE(vision_spi_flash_partitions),
};
static int vision_spi_flash_hw_setup(struct spi_device *spi)
{
return gpio_request_one(VISION_SPI_FLASH_CS, GPIOF_INIT_HIGH,
spi->modalias);
}
static void vision_spi_flash_hw_cleanup(struct spi_device *spi)
{
gpio_free(VISION_SPI_FLASH_CS);
}
static void vision_spi_flash_hw_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(VISION_SPI_FLASH_CS, value);
}
static struct ep93xx_spi_chip_ops vision_spi_flash_hw = {
.setup = vision_spi_flash_hw_setup,
.cleanup = vision_spi_flash_hw_cleanup,
.cs_control = vision_spi_flash_hw_cs_control,
};
/*************************************************************************
* SPI SD/MMC host
*************************************************************************/
#define VISION_SPI_MMC_CS EP93XX_GPIO_LINE_G(2)
#define VISION_SPI_MMC_WP EP93XX_GPIO_LINE_F(0)
#define VISION_SPI_MMC_CD EP93XX_GPIO_LINE_EGPIO15
static struct mmc_spi_platform_data vision_spi_mmc_data = {
.detect_delay = 100,
.powerup_msecs = 100,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO,
.cd_gpio = VISION_SPI_MMC_CD,
.cd_debounce = 1,
.ro_gpio = VISION_SPI_MMC_WP,
.caps2 = MMC_CAP2_RO_ACTIVE_HIGH,
};
static int vision_spi_mmc_hw_setup(struct spi_device *spi)
{
return gpio_request_one(VISION_SPI_MMC_CS, GPIOF_INIT_HIGH,
spi->modalias);
}
static void vision_spi_mmc_hw_cleanup(struct spi_device *spi)
{
gpio_free(VISION_SPI_MMC_CS);
}
static void vision_spi_mmc_hw_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(VISION_SPI_MMC_CS, value);
}
static struct ep93xx_spi_chip_ops vision_spi_mmc_hw = {
.setup = vision_spi_mmc_hw_setup,
.cleanup = vision_spi_mmc_hw_cleanup,
.cs_control = vision_spi_mmc_hw_cs_control,
};
/*************************************************************************
* SPI Bus
*************************************************************************/
static struct spi_board_info vision_spi_board_info[] __initdata = {
{
.modalias = "sst25l",
.platform_data = &vision_spi_flash_data,
.controller_data = &vision_spi_flash_hw,
.max_speed_hz = 20000000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_3,
}, {
.modalias = "mmc_spi",
.platform_data = &vision_spi_mmc_data,
.controller_data = &vision_spi_mmc_hw,
.max_speed_hz = 20000000,
.bus_num = 0,
.chip_select = 1,
.mode = SPI_MODE_3,
},
};
static struct ep93xx_spi_info vision_spi_master __initdata = {
.num_chipselect = ARRAY_SIZE(vision_spi_board_info),
};
/*************************************************************************
* Machine Initialization
*************************************************************************/
static void __init vision_init_machine(void)
{
ep93xx_init_devices();
ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_64M);
ep93xx_register_eth(&vision_eth_data, 1);
ep93xx_register_fb(&ep93xxfb_info);
ep93xx_register_pwm(1, 0);
/*
* Request the gpio expander's interrupt gpio line now to prevent
* the kernel from doing a WARN in gpiolib:gpio_ensure_requested().
*/
if (gpio_request_one(EP93XX_GPIO_LINE_F(7), GPIOF_DIR_IN,
"pca9539:74"))
pr_warn("cannot request interrupt gpio for pca9539:74\n");
vision_i2c_info[1].irq = gpio_to_irq(EP93XX_GPIO_LINE_F(7));
ep93xx_register_i2c(&vision_i2c_gpio_data, vision_i2c_info,
ARRAY_SIZE(vision_i2c_info));
ep93xx_register_spi(&vision_spi_master, vision_spi_board_info,
ARRAY_SIZE(vision_spi_board_info));
}
MACHINE_START(VISION_EP9307, "Vision Engraving Systems EP9307")
/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
.atag_offset = 0x100,
.map_io = vision_map_io,
.init_irq = ep93xx_init_irq,
.init_time = ep93xx_timer_init,
.init_machine = vision_init_machine,
.init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END