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,52 @@
#
# Makefile for the Linux/SuperH SH-4 backends.
#
# CPU subtype setup
obj-$(CONFIG_CPU_SUBTYPE_SH7757) += setup-sh7757.o
obj-$(CONFIG_CPU_SUBTYPE_SH7763) += setup-sh7763.o
obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o
obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
obj-$(CONFIG_CPU_SUBTYPE_SH7786) += setup-sh7786.o intc-shx3.o
obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o serial-sh7722.o
obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o
obj-$(CONFIG_CPU_SUBTYPE_SH7724) += setup-sh7724.o
obj-$(CONFIG_CPU_SUBTYPE_SH7734) += setup-sh7734.o
obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o
obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o intc-shx3.o
# SMP setup
smp-$(CONFIG_CPU_SHX3) := smp-shx3.o
# Primary on-chip clocks (common)
clock-$(CONFIG_CPU_SUBTYPE_SH7757) := clock-sh7757.o
clock-$(CONFIG_CPU_SUBTYPE_SH7763) := clock-sh7763.o
clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o
clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
clock-$(CONFIG_CPU_SUBTYPE_SH7786) := clock-sh7786.o
clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7723.o
clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7724.o
clock-$(CONFIG_CPU_SUBTYPE_SH7734) := clock-sh7734.o
clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7366.o
clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o
# Pinmux setup
pinmux-$(CONFIG_CPU_SUBTYPE_SH7722) := pinmux-sh7722.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7723) := pinmux-sh7723.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7724) := pinmux-sh7724.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7734) := pinmux-sh7734.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7757) := pinmux-sh7757.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o
pinmux-$(CONFIG_CPU_SUBTYPE_SHX3) := pinmux-shx3.o
obj-y += $(clock-y)
obj-$(CONFIG_SMP) += $(smp-y)
obj-$(CONFIG_GPIOLIB) += $(pinmux-y)
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += ubc.o

View file

@ -0,0 +1,289 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7343.c
*
* SH7343 clock framework support
*
* Copyright (C) 2009 Magnus Damm
*
* 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clock.h>
/* SH7343 registers */
#define FRQCR 0xa4150000
#define VCLKCR 0xa4150004
#define SCLKACR 0xa4150008
#define SCLKBCR 0xa415000c
#define PLLCR 0xa4150024
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
#define DLLFRQ 0xa4150050
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
static struct clk r_clk = {
.rate = 32768,
};
/*
* Default rate for the root input clock, reset this with clk_set_rate()
* from the platform code.
*/
struct clk extal_clk = {
.rate = 33333333,
};
/* The dll block multiplies the 32khz r_clk, may be used instead of extal */
static unsigned long dll_recalc(struct clk *clk)
{
unsigned long mult;
if (__raw_readl(PLLCR) & 0x1000)
mult = __raw_readl(DLLFRQ);
else
mult = 0;
return clk->parent->rate * mult;
}
static struct sh_clk_ops dll_clk_ops = {
.recalc = dll_recalc,
};
static struct clk dll_clk = {
.ops = &dll_clk_ops,
.parent = &r_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static unsigned long pll_recalc(struct clk *clk)
{
unsigned long mult = 1;
if (__raw_readl(PLLCR) & 0x4000)
mult = (((__raw_readl(FRQCR) >> 24) & 0x1f) + 1);
return clk->parent->rate * mult;
}
static struct sh_clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll_clk = {
.ops = &pll_clk_ops,
.flags = CLK_ENABLE_ON_INIT,
};
struct clk *main_clks[] = {
&r_clk,
&extal_clk,
&dll_clk,
&pll_clk,
};
static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
.multipliers = multipliers,
.nr_multipliers = ARRAY_SIZE(multipliers),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
};
enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
DIV4_SIUA, DIV4_SIUB, DIV4_NR };
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
struct clk div4_clks[DIV4_NR] = {
[DIV4_I] = DIV4(FRQCR, 20, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0),
[DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0),
[DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0),
};
enum { DIV6_V, DIV6_NR };
struct clk div6_clks[DIV6_NR] = {
[DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0),
};
#define MSTP(_parent, _reg, _bit, _flags) \
SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026,
MSTP023, MSTP022, MSTP021, MSTP020, MSTP019, MSTP018, MSTP017, MSTP016,
MSTP015, MSTP014, MSTP013, MSTP012, MSTP011, MSTP010,
MSTP007, MSTP006, MSTP005, MSTP004, MSTP003, MSTP002, MSTP001,
MSTP109, MSTP108, MSTP100,
MSTP225, MSTP224, MSTP218, MSTP217, MSTP216,
MSTP214, MSTP213, MSTP212, MSTP211, MSTP208,
MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
MSTP_NR };
static struct clk mstp_clks[MSTP_NR] = {
[MSTP031] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
[MSTP030] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
[MSTP029] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
[MSTP028] = MSTP(&div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
[MSTP026] = MSTP(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
[MSTP023] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 23, 0),
[MSTP022] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 22, 0),
[MSTP021] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
[MSTP020] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 20, 0),
[MSTP019] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
[MSTP017] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 17, 0),
[MSTP015] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
[MSTP014] = MSTP(&r_clk, MSTPCR0, 14, 0),
[MSTP013] = MSTP(&r_clk, MSTPCR0, 13, 0),
[MSTP011] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
[MSTP010] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
[MSTP007] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
[MSTP006] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 6, 0),
[MSTP005] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
[MSTP004] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
[MSTP003] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 3, 0),
[MSTP002] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
[MSTP001] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 1, 0),
[MSTP109] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
[MSTP108] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 8, 0),
[MSTP225] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 25, 0),
[MSTP224] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 24, 0),
[MSTP218] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 18, 0),
[MSTP217] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 17, 0),
[MSTP216] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 16, 0),
[MSTP214] = MSTP(&r_clk, MSTPCR2, 14, 0),
[MSTP213] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 13, 0),
[MSTP212] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 12, 0),
[MSTP211] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 11, 0),
[MSTP208] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 8, 0),
[MSTP206] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT),
[MSTP205] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
[MSTP204] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
[MSTP203] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
[MSTP202] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
[MSTP201] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
[MSTP200] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 0, 0),
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("rclk", &r_clk),
CLKDEV_CON_ID("extal", &extal_clk),
CLKDEV_CON_ID("dll_clk", &dll_clk),
CLKDEV_CON_ID("pll_clk", &pll_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]),
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
CLKDEV_CON_ID("siua_clk", &div4_clks[DIV4_SIUA]),
CLKDEV_CON_ID("siub_clk", &div4_clks[DIV4_SIUB]),
/* DIV6 clocks */
CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
/* MSTP32 clocks */
CLKDEV_CON_ID("tlb0", &mstp_clks[MSTP031]),
CLKDEV_CON_ID("ic0", &mstp_clks[MSTP030]),
CLKDEV_CON_ID("oc0", &mstp_clks[MSTP029]),
CLKDEV_CON_ID("uram0", &mstp_clks[MSTP028]),
CLKDEV_CON_ID("xymem0", &mstp_clks[MSTP026]),
CLKDEV_CON_ID("intc3", &mstp_clks[MSTP023]),
CLKDEV_CON_ID("intc0", &mstp_clks[MSTP022]),
CLKDEV_CON_ID("dmac0", &mstp_clks[MSTP021]),
CLKDEV_CON_ID("sh0", &mstp_clks[MSTP020]),
CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
CLKDEV_ICK_ID("fck", "sh-cmt-32.0", &mstp_clks[MSTP014]),
CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP007]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP006]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP005]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP004]),
CLKDEV_CON_ID("sio0", &mstp_clks[MSTP003]),
CLKDEV_CON_ID("siof0", &mstp_clks[MSTP002]),
CLKDEV_CON_ID("siof1", &mstp_clks[MSTP001]),
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP109]),
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP108]),
CLKDEV_CON_ID("tpu0", &mstp_clks[MSTP225]),
CLKDEV_CON_ID("irda0", &mstp_clks[MSTP224]),
CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP218]),
CLKDEV_CON_ID("mmcif0", &mstp_clks[MSTP217]),
CLKDEV_CON_ID("sim0", &mstp_clks[MSTP216]),
CLKDEV_CON_ID("keysc0", &mstp_clks[MSTP214]),
CLKDEV_CON_ID("tsif0", &mstp_clks[MSTP213]),
CLKDEV_CON_ID("s3d40", &mstp_clks[MSTP212]),
CLKDEV_CON_ID("usbf0", &mstp_clks[MSTP211]),
CLKDEV_CON_ID("siu0", &mstp_clks[MSTP208]),
CLKDEV_CON_ID("jpu0", &mstp_clks[MSTP206]),
CLKDEV_CON_ID("vou0", &mstp_clks[MSTP205]),
CLKDEV_CON_ID("beu0", &mstp_clks[MSTP204]),
CLKDEV_CON_ID("ceu0", &mstp_clks[MSTP203]),
CLKDEV_CON_ID("veu0", &mstp_clks[MSTP202]),
CLKDEV_CON_ID("vpu0", &mstp_clks[MSTP201]),
CLKDEV_CON_ID("lcdc0", &mstp_clks[MSTP200]),
};
int __init arch_clk_init(void)
{
int k, ret = 0;
/* autodetect extal or dll configuration */
if (__raw_readl(PLLCR) & 0x1000)
pll_clk.parent = &dll_clk;
else
pll_clk.parent = &extal_clk;
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
ret = clk_register(main_clks[k]);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
if (!ret)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
return ret;
}

View file

@ -0,0 +1,282 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7366.c
*
* SH7366 clock framework support
*
* Copyright (C) 2009 Magnus Damm
*
* 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clock.h>
/* SH7366 registers */
#define FRQCR 0xa4150000
#define VCLKCR 0xa4150004
#define SCLKACR 0xa4150008
#define SCLKBCR 0xa415000c
#define PLLCR 0xa4150024
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
#define DLLFRQ 0xa4150050
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
static struct clk r_clk = {
.rate = 32768,
};
/*
* Default rate for the root input clock, reset this with clk_set_rate()
* from the platform code.
*/
struct clk extal_clk = {
.rate = 33333333,
};
/* The dll block multiplies the 32khz r_clk, may be used instead of extal */
static unsigned long dll_recalc(struct clk *clk)
{
unsigned long mult;
if (__raw_readl(PLLCR) & 0x1000)
mult = __raw_readl(DLLFRQ);
else
mult = 0;
return clk->parent->rate * mult;
}
static struct sh_clk_ops dll_clk_ops = {
.recalc = dll_recalc,
};
static struct clk dll_clk = {
.ops = &dll_clk_ops,
.parent = &r_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static unsigned long pll_recalc(struct clk *clk)
{
unsigned long mult = 1;
unsigned long div = 1;
if (__raw_readl(PLLCR) & 0x4000)
mult = (((__raw_readl(FRQCR) >> 24) & 0x1f) + 1);
else
div = 2;
return (clk->parent->rate * mult) / div;
}
static struct sh_clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll_clk = {
.ops = &pll_clk_ops,
.flags = CLK_ENABLE_ON_INIT,
};
struct clk *main_clks[] = {
&r_clk,
&extal_clk,
&dll_clk,
&pll_clk,
};
static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
.multipliers = multipliers,
.nr_multipliers = ARRAY_SIZE(multipliers),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
};
enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
DIV4_SIUA, DIV4_SIUB, DIV4_NR };
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
struct clk div4_clks[DIV4_NR] = {
[DIV4_I] = DIV4(FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT),
[DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0),
[DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0),
[DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0),
};
enum { DIV6_V, DIV6_NR };
struct clk div6_clks[DIV6_NR] = {
[DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0),
};
#define MSTP(_parent, _reg, _bit, _flags) \
SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026,
MSTP023, MSTP022, MSTP021, MSTP020, MSTP019, MSTP018, MSTP017, MSTP016,
MSTP015, MSTP014, MSTP013, MSTP012, MSTP011, MSTP010,
MSTP007, MSTP006, MSTP005, MSTP002, MSTP001,
MSTP109, MSTP100,
MSTP227, MSTP226, MSTP224, MSTP223, MSTP222, MSTP218, MSTP217,
MSTP211, MSTP207, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
MSTP_NR };
static struct clk mstp_clks[MSTP_NR] = {
/* See page 52 of Datasheet V0.40: Overview -> Block Diagram */
[MSTP031] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
[MSTP030] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
[MSTP029] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
[MSTP028] = MSTP(&div4_clks[DIV4_SH], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
[MSTP026] = MSTP(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
[MSTP023] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 23, 0),
[MSTP022] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 22, 0),
[MSTP021] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
[MSTP020] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 20, 0),
[MSTP019] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
[MSTP017] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 17, 0),
[MSTP015] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
[MSTP014] = MSTP(&r_clk, MSTPCR0, 14, 0),
[MSTP013] = MSTP(&r_clk, MSTPCR0, 13, 0),
[MSTP011] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
[MSTP010] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
[MSTP007] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
[MSTP006] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 6, 0),
[MSTP005] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
[MSTP002] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
[MSTP001] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 1, 0),
[MSTP109] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
[MSTP227] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 27, 0),
[MSTP226] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 26, 0),
[MSTP224] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 24, 0),
[MSTP223] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 23, 0),
[MSTP222] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 22, 0),
[MSTP218] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 18, 0),
[MSTP217] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 17, 0),
[MSTP211] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 11, 0),
[MSTP207] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 7, CLK_ENABLE_ON_INIT),
[MSTP205] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
[MSTP204] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
[MSTP203] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
[MSTP202] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
[MSTP201] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
[MSTP200] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 0, 0),
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("rclk", &r_clk),
CLKDEV_CON_ID("extal", &extal_clk),
CLKDEV_CON_ID("dll_clk", &dll_clk),
CLKDEV_CON_ID("pll_clk", &pll_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]),
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
CLKDEV_CON_ID("siua_clk", &div4_clks[DIV4_SIUA]),
CLKDEV_CON_ID("siub_clk", &div4_clks[DIV4_SIUB]),
/* DIV6 clocks */
CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
/* MSTP32 clocks */
CLKDEV_CON_ID("tlb0", &mstp_clks[MSTP031]),
CLKDEV_CON_ID("ic0", &mstp_clks[MSTP030]),
CLKDEV_CON_ID("oc0", &mstp_clks[MSTP029]),
CLKDEV_CON_ID("rsmem0", &mstp_clks[MSTP028]),
CLKDEV_CON_ID("xymem0", &mstp_clks[MSTP026]),
CLKDEV_CON_ID("intc3", &mstp_clks[MSTP023]),
CLKDEV_CON_ID("intc0", &mstp_clks[MSTP022]),
CLKDEV_CON_ID("dmac0", &mstp_clks[MSTP021]),
CLKDEV_CON_ID("sh0", &mstp_clks[MSTP020]),
CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
CLKDEV_ICK_ID("fck", "sh-cmt-32.0", &mstp_clks[MSTP014]),
CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP007]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP006]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP005]),
CLKDEV_CON_ID("msiof0", &mstp_clks[MSTP002]),
CLKDEV_CON_ID("sbr0", &mstp_clks[MSTP001]),
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP109]),
CLKDEV_CON_ID("icb0", &mstp_clks[MSTP227]),
CLKDEV_CON_ID("meram0", &mstp_clks[MSTP226]),
CLKDEV_CON_ID("dacy1", &mstp_clks[MSTP224]),
CLKDEV_CON_ID("dacy0", &mstp_clks[MSTP223]),
CLKDEV_CON_ID("tsif0", &mstp_clks[MSTP222]),
CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP218]),
CLKDEV_CON_ID("mmcif0", &mstp_clks[MSTP217]),
CLKDEV_CON_ID("usbf0", &mstp_clks[MSTP211]),
CLKDEV_CON_ID("veu1", &mstp_clks[MSTP207]),
CLKDEV_CON_ID("vou0", &mstp_clks[MSTP205]),
CLKDEV_CON_ID("beu0", &mstp_clks[MSTP204]),
CLKDEV_CON_ID("ceu0", &mstp_clks[MSTP203]),
CLKDEV_CON_ID("veu0", &mstp_clks[MSTP202]),
CLKDEV_CON_ID("vpu0", &mstp_clks[MSTP201]),
CLKDEV_CON_ID("lcdc0", &mstp_clks[MSTP200]),
};
int __init arch_clk_init(void)
{
int k, ret = 0;
/* autodetect extal or dll configuration */
if (__raw_readl(PLLCR) & 0x1000)
pll_clk.parent = &dll_clk;
else
pll_clk.parent = &extal_clk;
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
ret = clk_register(main_clks[k]);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
if (!ret)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
return ret;
}

View file

@ -0,0 +1,265 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7722.c
*
* SH7722 clock framework support
*
* Copyright (C) 2009 Magnus Damm
*
* 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <linux/sh_clk.h>
#include <asm/clock.h>
#include <cpu/sh7722.h>
/* SH7722 registers */
#define FRQCR 0xa4150000
#define VCLKCR 0xa4150004
#define SCLKACR 0xa4150008
#define SCLKBCR 0xa415000c
#define IRDACLKCR 0xa4150018
#define PLLCR 0xa4150024
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
#define DLLFRQ 0xa4150050
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
static struct clk r_clk = {
.rate = 32768,
};
/*
* Default rate for the root input clock, reset this with clk_set_rate()
* from the platform code.
*/
struct clk extal_clk = {
.rate = 33333333,
};
/* The dll block multiplies the 32khz r_clk, may be used instead of extal */
static unsigned long dll_recalc(struct clk *clk)
{
unsigned long mult;
if (__raw_readl(PLLCR) & 0x1000)
mult = __raw_readl(DLLFRQ);
else
mult = 0;
return clk->parent->rate * mult;
}
static struct sh_clk_ops dll_clk_ops = {
.recalc = dll_recalc,
};
static struct clk dll_clk = {
.ops = &dll_clk_ops,
.parent = &r_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static unsigned long pll_recalc(struct clk *clk)
{
unsigned long mult = 1;
unsigned long div = 1;
if (__raw_readl(PLLCR) & 0x4000)
mult = (((__raw_readl(FRQCR) >> 24) & 0x1f) + 1);
else
div = 2;
return (clk->parent->rate * mult) / div;
}
static struct sh_clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll_clk = {
.ops = &pll_clk_ops,
.flags = CLK_ENABLE_ON_INIT,
};
struct clk *main_clks[] = {
&r_clk,
&extal_clk,
&dll_clk,
&pll_clk,
};
static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
.multipliers = multipliers,
.nr_multipliers = ARRAY_SIZE(multipliers),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
};
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR };
struct clk div4_clks[DIV4_NR] = {
[DIV4_I] = DIV4(FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT),
[DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
[DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0),
};
enum { DIV4_IRDA, DIV4_ENABLE_NR };
struct clk div4_enable_clks[DIV4_ENABLE_NR] = {
[DIV4_IRDA] = DIV4(IRDACLKCR, 0, 0x1fff, 0),
};
enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR };
struct clk div4_reparent_clks[DIV4_REPARENT_NR] = {
[DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0),
[DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0),
};
enum { DIV6_V, DIV6_NR };
struct clk div6_clks[DIV6_NR] = {
[DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0),
};
static struct clk mstp_clks[HWBLK_NR] = {
[HWBLK_URAM] = SH_CLK_MSTP32(&div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
[HWBLK_XYMEM] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
[HWBLK_TMU] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
[HWBLK_CMT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 14, 0),
[HWBLK_RWDT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 13, 0),
[HWBLK_FLCTL] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
[HWBLK_SCIF0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
[HWBLK_SCIF1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 6, 0),
[HWBLK_SCIF2] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
[HWBLK_IIC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
[HWBLK_RTC] = SH_CLK_MSTP32(&r_clk, MSTPCR1, 8, 0),
[HWBLK_SDHI] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 18, 0),
[HWBLK_KEYSC] = SH_CLK_MSTP32(&r_clk, MSTPCR2, 14, 0),
[HWBLK_USBF] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 11, 0),
[HWBLK_2DG] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 9, 0),
[HWBLK_SIU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 8, 0),
[HWBLK_JPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 6, 0),
[HWBLK_VOU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
[HWBLK_BEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
[HWBLK_CEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
[HWBLK_VEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 2, 0),
[HWBLK_VPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 1, 0),
[HWBLK_LCDC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 0, 0),
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("rclk", &r_clk),
CLKDEV_CON_ID("extal", &extal_clk),
CLKDEV_CON_ID("dll_clk", &dll_clk),
CLKDEV_CON_ID("pll_clk", &pll_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]),
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
CLKDEV_CON_ID("irda_clk", &div4_enable_clks[DIV4_IRDA]),
CLKDEV_CON_ID("siua_clk", &div4_reparent_clks[DIV4_SIUA]),
CLKDEV_CON_ID("siub_clk", &div4_reparent_clks[DIV4_SIUB]),
/* DIV6 clocks */
CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
/* MSTP clocks */
CLKDEV_CON_ID("uram0", &mstp_clks[HWBLK_URAM]),
CLKDEV_CON_ID("xymem0", &mstp_clks[HWBLK_XYMEM]),
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[HWBLK_TMU]),
CLKDEV_ICK_ID("fck", "sh-cmt-32.0", &mstp_clks[HWBLK_CMT]),
CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC]),
CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]),
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI]),
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[HWBLK_KEYSC]),
CLKDEV_CON_ID("usbf0", &mstp_clks[HWBLK_USBF]),
CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]),
CLKDEV_DEV_ID("siu-pcm-audio", &mstp_clks[HWBLK_SIU]),
CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]),
CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU]),
CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU]),
CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]),
};
int __init arch_clk_init(void)
{
int k, ret = 0;
/* autodetect extal or dll configuration */
if (__raw_readl(PLLCR) & 0x1000)
pll_clk.parent = &dll_clk;
else
pll_clk.parent = &extal_clk;
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
ret = clk_register(main_clks[k]);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
if (!ret)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
ret = sh_clk_div4_enable_register(div4_enable_clks,
DIV4_ENABLE_NR, &div4_table);
if (!ret)
ret = sh_clk_div4_reparent_register(div4_reparent_clks,
DIV4_REPARENT_NR, &div4_table);
if (!ret)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
ret = sh_clk_mstp_register(mstp_clks, HWBLK_NR);
return ret;
}

View file

@ -0,0 +1,313 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7723.c
*
* SH7723 clock framework support
*
* Copyright (C) 2009 Magnus Damm
*
* 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/sh_clk.h>
#include <asm/clock.h>
#include <cpu/sh7723.h>
/* SH7723 registers */
#define FRQCR 0xa4150000
#define VCLKCR 0xa4150004
#define SCLKACR 0xa4150008
#define SCLKBCR 0xa415000c
#define IRDACLKCR 0xa4150018
#define PLLCR 0xa4150024
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
#define DLLFRQ 0xa4150050
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
static struct clk r_clk = {
.rate = 32768,
};
/*
* Default rate for the root input clock, reset this with clk_set_rate()
* from the platform code.
*/
struct clk extal_clk = {
.rate = 33333333,
};
/* The dll multiplies the 32khz r_clk, may be used instead of extal */
static unsigned long dll_recalc(struct clk *clk)
{
unsigned long mult;
if (__raw_readl(PLLCR) & 0x1000)
mult = __raw_readl(DLLFRQ);
else
mult = 0;
return clk->parent->rate * mult;
}
static struct sh_clk_ops dll_clk_ops = {
.recalc = dll_recalc,
};
static struct clk dll_clk = {
.ops = &dll_clk_ops,
.parent = &r_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static unsigned long pll_recalc(struct clk *clk)
{
unsigned long mult = 1;
unsigned long div = 1;
if (__raw_readl(PLLCR) & 0x4000)
mult = (((__raw_readl(FRQCR) >> 24) & 0x1f) + 1);
else
div = 2;
return (clk->parent->rate * mult) / div;
}
static struct sh_clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll_clk = {
.ops = &pll_clk_ops,
.flags = CLK_ENABLE_ON_INIT,
};
struct clk *main_clks[] = {
&r_clk,
&extal_clk,
&dll_clk,
&pll_clk,
};
static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
.multipliers = multipliers,
.nr_multipliers = ARRAY_SIZE(multipliers),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
};
enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR };
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
struct clk div4_clks[DIV4_NR] = {
[DIV4_I] = DIV4(FRQCR, 20, 0x0dbf, CLK_ENABLE_ON_INIT),
[DIV4_U] = DIV4(FRQCR, 16, 0x0dbf, CLK_ENABLE_ON_INIT),
[DIV4_SH] = DIV4(FRQCR, 12, 0x0dbf, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4(FRQCR, 8, 0x0dbf, CLK_ENABLE_ON_INIT),
[DIV4_B3] = DIV4(FRQCR, 4, 0x0db4, CLK_ENABLE_ON_INIT),
[DIV4_P] = DIV4(FRQCR, 0, 0x0dbf, 0),
};
enum { DIV4_IRDA, DIV4_ENABLE_NR };
struct clk div4_enable_clks[DIV4_ENABLE_NR] = {
[DIV4_IRDA] = DIV4(IRDACLKCR, 0, 0x0dbf, 0),
};
enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR };
struct clk div4_reparent_clks[DIV4_REPARENT_NR] = {
[DIV4_SIUA] = DIV4(SCLKACR, 0, 0x0dbf, 0),
[DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x0dbf, 0),
};
enum { DIV6_V, DIV6_NR };
struct clk div6_clks[DIV6_NR] = {
[DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0),
};
static struct clk mstp_clks[] = {
/* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
[HWBLK_TLB] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
[HWBLK_IC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
[HWBLK_OC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
[HWBLK_L2C] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
[HWBLK_ILMEM] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 27, CLK_ENABLE_ON_INIT),
[HWBLK_FPU] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 24, CLK_ENABLE_ON_INIT),
[HWBLK_INTC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 22, CLK_ENABLE_ON_INIT),
[HWBLK_DMAC0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 21, 0),
[HWBLK_SHYWAY] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR0, 20, CLK_ENABLE_ON_INIT),
[HWBLK_HUDI] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
[HWBLK_UBC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 17, 0),
[HWBLK_TMU0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
[HWBLK_CMT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 14, 0),
[HWBLK_RWDT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 13, 0),
[HWBLK_DMAC1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 12, 0),
[HWBLK_TMU1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
[HWBLK_FLCTL] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
[HWBLK_SCIF0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
[HWBLK_SCIF1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
[HWBLK_SCIF2] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
[HWBLK_SCIF3] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 6, 0),
[HWBLK_SCIF4] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 5, 0),
[HWBLK_SCIF5] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 4, 0),
[HWBLK_MSIOF0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 2, 0),
[HWBLK_MSIOF1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 1, 0),
[HWBLK_MERAM] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR0, 0, 0),
[HWBLK_IIC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
[HWBLK_RTC] = SH_CLK_MSTP32(&r_clk, MSTPCR1, 8, 0),
[HWBLK_ATAPI] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR2, 28, 0),
[HWBLK_ADC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 27, 0),
[HWBLK_TPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 25, 0),
[HWBLK_IRDA] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 24, 0),
[HWBLK_TSIF] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 22, 0),
[HWBLK_ICB] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 21, CLK_ENABLE_ON_INIT),
[HWBLK_SDHI0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 18, 0),
[HWBLK_SDHI1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 17, 0),
[HWBLK_KEYSC] = SH_CLK_MSTP32(&r_clk, MSTPCR2, 14, 0),
[HWBLK_USB] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 11, 0),
[HWBLK_2DG] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 10, 0),
[HWBLK_SIU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 8, 0),
[HWBLK_VEU2H1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 6, 0),
[HWBLK_VOU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
[HWBLK_BEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
[HWBLK_CEU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
[HWBLK_VEU2H0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 2, 0),
[HWBLK_VPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 1, 0),
[HWBLK_LCDC] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 0, 0),
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("rclk", &r_clk),
CLKDEV_CON_ID("extal", &extal_clk),
CLKDEV_CON_ID("dll_clk", &dll_clk),
CLKDEV_CON_ID("pll_clk", &pll_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]),
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
CLKDEV_CON_ID("irda_clk", &div4_enable_clks[DIV4_IRDA]),
CLKDEV_CON_ID("siua_clk", &div4_reparent_clks[DIV4_SIUA]),
CLKDEV_CON_ID("siub_clk", &div4_reparent_clks[DIV4_SIUB]),
/* DIV6 clocks */
CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
/* MSTP clocks */
CLKDEV_CON_ID("tlb0", &mstp_clks[HWBLK_TLB]),
CLKDEV_CON_ID("ic0", &mstp_clks[HWBLK_IC]),
CLKDEV_CON_ID("oc0", &mstp_clks[HWBLK_OC]),
CLKDEV_CON_ID("l2c0", &mstp_clks[HWBLK_L2C]),
CLKDEV_CON_ID("ilmem0", &mstp_clks[HWBLK_ILMEM]),
CLKDEV_CON_ID("fpu0", &mstp_clks[HWBLK_FPU]),
CLKDEV_CON_ID("intc0", &mstp_clks[HWBLK_INTC]),
CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[HWBLK_DMAC0]),
CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
CLKDEV_ICK_ID("fck", "sh-cmt-32.0", &mstp_clks[HWBLK_CMT]),
CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[HWBLK_DMAC1]),
CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[HWBLK_MSIOF0]),
CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[HWBLK_MSIOF1]),
CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[HWBLK_MERAM]),
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC]),
CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]),
CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]),
CLKDEV_CON_ID("adc0", &mstp_clks[HWBLK_ADC]),
CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]),
CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]),
CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]),
CLKDEV_CON_ID("icb0", &mstp_clks[HWBLK_ICB]),
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]),
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]),
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[HWBLK_KEYSC]),
CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB]),
CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]),
CLKDEV_DEV_ID("siu-pcm-audio", &mstp_clks[HWBLK_SIU]),
CLKDEV_CON_ID("veu1", &mstp_clks[HWBLK_VEU2H1]),
CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]),
CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU]),
CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU2H0]),
CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[HWBLK_TMU0]),
CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[HWBLK_TMU1]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]),
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]),
};
int __init arch_clk_init(void)
{
int k, ret = 0;
/* autodetect extal or dll configuration */
if (__raw_readl(PLLCR) & 0x1000)
pll_clk.parent = &dll_clk;
else
pll_clk.parent = &extal_clk;
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
ret |= clk_register(main_clks[k]);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
if (!ret)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
ret = sh_clk_div4_enable_register(div4_enable_clks,
DIV4_ENABLE_NR, &div4_table);
if (!ret)
ret = sh_clk_div4_reparent_register(div4_reparent_clks,
DIV4_REPARENT_NR, &div4_table);
if (!ret)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
ret = sh_clk_mstp_register(mstp_clks, HWBLK_NR);
return ret;
}

View file

@ -0,0 +1,379 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7724.c
*
* SH7724 clock framework support
*
* Copyright (C) 2009 Magnus Damm
*
* 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/sh_clk.h>
#include <asm/clock.h>
#include <cpu/sh7724.h>
/* SH7724 registers */
#define FRQCRA 0xa4150000
#define FRQCRB 0xa4150004
#define VCLKCR 0xa4150048
#define FCLKACR 0xa4150008
#define FCLKBCR 0xa415000c
#define IRDACLKCR 0xa4150018
#define PLLCR 0xa4150024
#define MSTPCR0 0xa4150030
#define MSTPCR1 0xa4150034
#define MSTPCR2 0xa4150038
#define SPUCLKCR 0xa415003c
#define FLLFRQ 0xa4150050
#define LSTATS 0xa4150060
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
static struct clk r_clk = {
.rate = 32768,
};
/*
* Default rate for the root input clock, reset this with clk_set_rate()
* from the platform code.
*/
static struct clk extal_clk = {
.rate = 33333333,
};
/* The fll multiplies the 32khz r_clk, may be used instead of extal */
static unsigned long fll_recalc(struct clk *clk)
{
unsigned long mult = 0;
unsigned long div = 1;
if (__raw_readl(PLLCR) & 0x1000)
mult = __raw_readl(FLLFRQ) & 0x3ff;
if (__raw_readl(FLLFRQ) & 0x4000)
div = 2;
return (clk->parent->rate * mult) / div;
}
static struct sh_clk_ops fll_clk_ops = {
.recalc = fll_recalc,
};
static struct clk fll_clk = {
.ops = &fll_clk_ops,
.parent = &r_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static unsigned long pll_recalc(struct clk *clk)
{
unsigned long mult = 1;
if (__raw_readl(PLLCR) & 0x4000)
mult = (((__raw_readl(FRQCRA) >> 24) & 0x3f) + 1) * 2;
return clk->parent->rate * mult;
}
static struct sh_clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll_clk = {
.ops = &pll_clk_ops,
.flags = CLK_ENABLE_ON_INIT,
};
/* A fixed divide-by-3 block use by the div6 clocks */
static unsigned long div3_recalc(struct clk *clk)
{
return clk->parent->rate / 3;
}
static struct sh_clk_ops div3_clk_ops = {
.recalc = div3_recalc,
};
static struct clk div3_clk = {
.ops = &div3_clk_ops,
.parent = &pll_clk,
};
/* External input clock (pin name: FSIMCKA/FSIMCKB/DV_CLKI ) */
struct clk sh7724_fsimcka_clk = {
};
struct clk sh7724_fsimckb_clk = {
};
struct clk sh7724_dv_clki = {
};
static struct clk *main_clks[] = {
&r_clk,
&extal_clk,
&fll_clk,
&pll_clk,
&div3_clk,
&sh7724_fsimcka_clk,
&sh7724_fsimckb_clk,
&sh7724_dv_clki,
};
static void div4_kick(struct clk *clk)
{
unsigned long value;
/* set KICK bit in FRQCRA to update hardware setting */
value = __raw_readl(FRQCRA);
value |= (1 << 31);
__raw_writel(value, FRQCRA);
}
static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
.kick = div4_kick,
};
enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_P, DIV4_M1, DIV4_NR };
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
struct clk div4_clks[DIV4_NR] = {
[DIV4_I] = DIV4(FRQCRA, 20, 0x2f7d, CLK_ENABLE_ON_INIT),
[DIV4_SH] = DIV4(FRQCRA, 12, 0x2f7c, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4(FRQCRA, 8, 0x2f7c, CLK_ENABLE_ON_INIT),
[DIV4_P] = DIV4(FRQCRA, 0, 0x2f7c, 0),
[DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
};
enum { DIV6_V, DIV6_I, DIV6_S, DIV6_FA, DIV6_FB, DIV6_NR };
/* Indices are important - they are the actual src selecting values */
static struct clk *common_parent[] = {
[0] = &div3_clk,
[1] = NULL,
};
static struct clk *vclkcr_parent[8] = {
[0] = &div3_clk,
[2] = &sh7724_dv_clki,
[4] = &extal_clk,
};
static struct clk *fclkacr_parent[] = {
[0] = &div3_clk,
[1] = NULL,
[2] = &sh7724_fsimcka_clk,
[3] = NULL,
};
static struct clk *fclkbcr_parent[] = {
[0] = &div3_clk,
[1] = NULL,
[2] = &sh7724_fsimckb_clk,
[3] = NULL,
};
static struct clk div6_clks[DIV6_NR] = {
[DIV6_V] = SH_CLK_DIV6_EXT(VCLKCR, 0,
vclkcr_parent, ARRAY_SIZE(vclkcr_parent), 12, 3),
[DIV6_I] = SH_CLK_DIV6_EXT(IRDACLKCR, 0,
common_parent, ARRAY_SIZE(common_parent), 6, 1),
[DIV6_S] = SH_CLK_DIV6_EXT(SPUCLKCR, CLK_ENABLE_ON_INIT,
common_parent, ARRAY_SIZE(common_parent), 6, 1),
[DIV6_FA] = SH_CLK_DIV6_EXT(FCLKACR, 0,
fclkacr_parent, ARRAY_SIZE(fclkacr_parent), 6, 2),
[DIV6_FB] = SH_CLK_DIV6_EXT(FCLKBCR, 0,
fclkbcr_parent, ARRAY_SIZE(fclkbcr_parent), 6, 2),
};
static struct clk mstp_clks[HWBLK_NR] = {
[HWBLK_TLB] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
[HWBLK_IC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
[HWBLK_OC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
[HWBLK_RSMEM] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
[HWBLK_ILMEM] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 27, CLK_ENABLE_ON_INIT),
[HWBLK_L2C] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
[HWBLK_FPU] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 24, CLK_ENABLE_ON_INIT),
[HWBLK_INTC] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 22, CLK_ENABLE_ON_INIT),
[HWBLK_DMAC0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 21, 0),
[HWBLK_SHYWAY] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR0, 20, CLK_ENABLE_ON_INIT),
[HWBLK_HUDI] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
[HWBLK_UBC] = SH_CLK_MSTP32(&div4_clks[DIV4_I], MSTPCR0, 17, 0),
[HWBLK_TMU0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
[HWBLK_CMT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 14, 0),
[HWBLK_RWDT] = SH_CLK_MSTP32(&r_clk, MSTPCR0, 13, 0),
[HWBLK_DMAC1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 12, 0),
[HWBLK_TMU1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
[HWBLK_SCIF0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
[HWBLK_SCIF1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
[HWBLK_SCIF2] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
[HWBLK_SCIF3] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 6, 0),
[HWBLK_SCIF4] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 5, 0),
[HWBLK_SCIF5] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 4, 0),
[HWBLK_MSIOF0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 2, 0),
[HWBLK_MSIOF1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR0, 1, 0),
[HWBLK_KEYSC] = SH_CLK_MSTP32(&r_clk, MSTPCR1, 12, 0),
[HWBLK_RTC] = SH_CLK_MSTP32(&r_clk, MSTPCR1, 11, 0),
[HWBLK_IIC0] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
[HWBLK_IIC1] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 8, 0),
[HWBLK_MMC] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 29, 0),
[HWBLK_ETHER] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 28, 0),
[HWBLK_ATAPI] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 26, 0),
[HWBLK_TPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 25, 0),
[HWBLK_IRDA] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 24, 0),
[HWBLK_TSIF] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 22, 0),
[HWBLK_USB1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 21, 0),
[HWBLK_USB0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 20, 0),
[HWBLK_2DG] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 19, 0),
[HWBLK_SDHI0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 18, 0),
[HWBLK_SDHI1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 17, 0),
[HWBLK_VEU1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 15, 0),
[HWBLK_CEU1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 13, 0),
[HWBLK_BEU1] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 12, 0),
[HWBLK_2DDMAC] = SH_CLK_MSTP32(&div4_clks[DIV4_SH], MSTPCR2, 10, 0),
[HWBLK_SPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 9, 0),
[HWBLK_JPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 6, 0),
[HWBLK_VOU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
[HWBLK_BEU0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
[HWBLK_CEU0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
[HWBLK_VEU0] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 2, 0),
[HWBLK_VPU] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 1, 0),
[HWBLK_LCDC] = SH_CLK_MSTP32(&div4_clks[DIV4_B], MSTPCR2, 0, 0),
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("rclk", &r_clk),
CLKDEV_CON_ID("extal", &extal_clk),
CLKDEV_CON_ID("fll_clk", &fll_clk),
CLKDEV_CON_ID("pll_clk", &pll_clk),
CLKDEV_CON_ID("div3_clk", &div3_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
CLKDEV_CON_ID("vpu_clk", &div4_clks[DIV4_M1]),
/* DIV6 clocks */
CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]),
CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FB]),
CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]),
CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]),
/* MSTP clocks */
CLKDEV_CON_ID("tlb0", &mstp_clks[HWBLK_TLB]),
CLKDEV_CON_ID("ic0", &mstp_clks[HWBLK_IC]),
CLKDEV_CON_ID("oc0", &mstp_clks[HWBLK_OC]),
CLKDEV_CON_ID("rs0", &mstp_clks[HWBLK_RSMEM]),
CLKDEV_CON_ID("ilmem0", &mstp_clks[HWBLK_ILMEM]),
CLKDEV_CON_ID("l2c0", &mstp_clks[HWBLK_L2C]),
CLKDEV_CON_ID("fpu0", &mstp_clks[HWBLK_FPU]),
CLKDEV_CON_ID("intc0", &mstp_clks[HWBLK_INTC]),
CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[HWBLK_DMAC0]),
CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[HWBLK_TMU0]),
CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[HWBLK_TMU1]),
CLKDEV_ICK_ID("fck", "sh-cmt-32.0", &mstp_clks[HWBLK_CMT]),
CLKDEV_DEV_ID("sh-wdt.0", &mstp_clks[HWBLK_RWDT]),
CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[HWBLK_DMAC1]),
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[HWBLK_SCIF3]),
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[HWBLK_SCIF4]),
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[HWBLK_SCIF5]),
CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[HWBLK_MSIOF0]),
CLKDEV_DEV_ID("spi_sh_msiof.1", &mstp_clks[HWBLK_MSIOF1]),
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[HWBLK_KEYSC]),
CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]),
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC0]),
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[HWBLK_IIC1]),
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[HWBLK_MMC]),
CLKDEV_DEV_ID("sh7724-ether.0", &mstp_clks[HWBLK_ETHER]),
CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]),
CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]),
CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]),
CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]),
CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[HWBLK_USB1]),
CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[HWBLK_USB0]),
CLKDEV_CON_ID("usb1", &mstp_clks[HWBLK_USB1]),
CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB0]),
CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]),
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]),
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]),
CLKDEV_CON_ID("veu1", &mstp_clks[HWBLK_VEU1]),
CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[HWBLK_CEU1]),
CLKDEV_CON_ID("beu1", &mstp_clks[HWBLK_BEU1]),
CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]),
CLKDEV_DEV_ID("sh_fsi.0", &mstp_clks[HWBLK_SPU]),
CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU0]),
CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU0]),
CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU0]),
CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]),
};
int __init arch_clk_init(void)
{
int k, ret = 0;
/* autodetect extal or fll configuration */
if (__raw_readl(PLLCR) & 0x1000)
pll_clk.parent = &fll_clk;
else
pll_clk.parent = &extal_clk;
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
ret = clk_register(main_clks[k]);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
if (!ret)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
if (!ret)
ret = sh_clk_mstp_register(mstp_clks, HWBLK_NR);
return ret;
}

View file

@ -0,0 +1,260 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7734.c
*
* Clock framework for SH7734
*
* Copyright (C) 2011, 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
* Copyright (C) 2011, 2012 Renesas Solutions Corp.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <linux/delay.h>
#include <asm/clock.h>
#include <asm/freq.h>
static struct clk extal_clk = {
.rate = 33333333,
};
#define MODEMR (0xFFCC0020)
#define MODEMR_MASK (0x6)
#define MODEMR_533MHZ (0x2)
static unsigned long pll_recalc(struct clk *clk)
{
int mode = 12;
u32 r = __raw_readl(MODEMR);
if ((r & MODEMR_MASK) & MODEMR_533MHZ)
mode = 16;
return clk->parent->rate * mode;
}
static struct sh_clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll_clk = {
.ops = &pll_clk_ops,
.parent = &extal_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static struct clk *main_clks[] = {
&extal_clk,
&pll_clk,
};
static int multipliers[] = { 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
static int divisors[] = { 1, 3, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = divisors,
.nr_divisors = ARRAY_SIZE(divisors),
.multipliers = multipliers,
.nr_multipliers = ARRAY_SIZE(multipliers),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
};
enum { DIV4_I, DIV4_S, DIV4_B, DIV4_M, DIV4_S1, DIV4_P, DIV4_NR };
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
struct clk div4_clks[DIV4_NR] = {
[DIV4_I] = DIV4(FRQMR1, 28, 0x0003, CLK_ENABLE_ON_INIT),
[DIV4_S] = DIV4(FRQMR1, 20, 0x000C, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4(FRQMR1, 16, 0x0140, CLK_ENABLE_ON_INIT),
[DIV4_M] = DIV4(FRQMR1, 12, 0x0004, CLK_ENABLE_ON_INIT),
[DIV4_S1] = DIV4(FRQMR1, 4, 0x0030, CLK_ENABLE_ON_INIT),
[DIV4_P] = DIV4(FRQMR1, 0, 0x0140, CLK_ENABLE_ON_INIT),
};
#define MSTPCR0 0xFFC80030
#define MSTPCR1 0xFFC80034
#define MSTPCR3 0xFFC8003C
enum {
MSTP030, MSTP029, /* IIC */
MSTP026, MSTP025, MSTP024, /* SCIF */
MSTP023,
MSTP022, MSTP021,
MSTP019, /* HSCIF */
MSTP016, MSTP015, MSTP014, /* TMU / TIMER */
MSTP012, MSTP011, MSTP010, MSTP009, MSTP008, /* SSI */
MSTP007, /* HSPI */
MSTP115, /* ADMAC */
MSTP114, /* GETHER */
MSTP111, /* DMAC */
MSTP109, /* VIDEOIN1 */
MSTP108, /* VIDEOIN0 */
MSTP107, /* RGPVBG */
MSTP106, /* 2DG */
MSTP103, /* VIEW */
MSTP100, /* USB */
MSTP331, /* MMC */
MSTP330, /* MIMLB */
MSTP323, /* SDHI0 */
MSTP322, /* SDHI1 */
MSTP321, /* SDHI2 */
MSTP320, /* RQSPI */
MSTP319, /* SRC0 */
MSTP318, /* SRC1 */
MSTP317, /* RSPI */
MSTP316, /* RCAN0 */
MSTP315, /* RCAN1 */
MSTP314, /* FLTCL */
MSTP313, /* ADC */
MSTP312, /* MTU */
MSTP304, /* IE-BUS */
MSTP303, /* RTC */
MSTP302, /* HIF */
MSTP301, /* STIF0 */
MSTP300, /* STIF1 */
MSTP_NR };
static struct clk mstp_clks[MSTP_NR] = {
/* MSTPCR0 */
[MSTP030] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 30, 0),
[MSTP029] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 29, 0),
[MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0),
[MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0),
[MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0),
[MSTP023] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 23, 0),
[MSTP022] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 22, 0),
[MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
[MSTP019] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
[MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0),
[MSTP015] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
[MSTP014] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 14, 0),
[MSTP012] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 12, 0),
[MSTP011] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
[MSTP010] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
[MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
[MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
[MSTP007] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
/* MSTPCR1 */
[MSTP115] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 15, 0),
[MSTP114] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 14, 0),
[MSTP111] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 11, 0),
[MSTP109] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
[MSTP108] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 8, 0),
[MSTP107] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 7, 0),
[MSTP106] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 6, 0),
[MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0),
[MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 0, 0),
/* MSTPCR3 */
[MSTP331] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 31, 0),
[MSTP330] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 30, 0),
[MSTP323] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 23, 0),
[MSTP322] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 22, 0),
[MSTP321] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 21, 0),
[MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 20, 0),
[MSTP319] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 19, 0),
[MSTP318] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 18, 0),
[MSTP317] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 17, 0),
[MSTP316] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 16, 0),
[MSTP315] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 15, 0),
[MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 14, 0),
[MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 13, 0),
[MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 12, 0),
[MSTP304] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 4, 0),
[MSTP303] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 3, 0),
[MSTP302] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 2, 0),
[MSTP301] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 1, 0),
[MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 0, 0),
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("extal", &extal_clk),
CLKDEV_CON_ID("pll_clk", &pll_clk),
/* clocks */
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_S]),
CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_M]),
CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
CLKDEV_CON_ID("shyway_clk1", &div4_clks[DIV4_S1]),
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh7734.0", &mstp_clks[MSTP030]),
CLKDEV_DEV_ID("i2c-sh7734.1", &mstp_clks[MSTP029]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP026]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP024]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP023]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP022]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP021]),
CLKDEV_CON_ID("hscif", &mstp_clks[MSTP019]),
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]),
CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP015]),
CLKDEV_ICK_ID("fck", "sh-tmu.2", &mstp_clks[MSTP014]),
CLKDEV_CON_ID("ssi0", &mstp_clks[MSTP012]),
CLKDEV_CON_ID("ssi1", &mstp_clks[MSTP011]),
CLKDEV_CON_ID("ssi2", &mstp_clks[MSTP010]),
CLKDEV_CON_ID("ssi3", &mstp_clks[MSTP009]),
CLKDEV_CON_ID("sss", &mstp_clks[MSTP008]),
CLKDEV_CON_ID("hspi", &mstp_clks[MSTP007]),
CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP100]),
CLKDEV_CON_ID("videoin0", &mstp_clks[MSTP109]),
CLKDEV_CON_ID("videoin1", &mstp_clks[MSTP108]),
CLKDEV_CON_ID("rgpvg", &mstp_clks[MSTP107]),
CLKDEV_CON_ID("2dg", &mstp_clks[MSTP106]),
CLKDEV_CON_ID("view", &mstp_clks[MSTP103]),
CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP331]),
CLKDEV_CON_ID("mimlb0", &mstp_clks[MSTP330]),
CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP323]),
CLKDEV_CON_ID("sdhi1", &mstp_clks[MSTP322]),
CLKDEV_CON_ID("sdhi2", &mstp_clks[MSTP321]),
CLKDEV_CON_ID("rqspi0", &mstp_clks[MSTP320]),
CLKDEV_CON_ID("src0", &mstp_clks[MSTP319]),
CLKDEV_CON_ID("src1", &mstp_clks[MSTP318]),
CLKDEV_CON_ID("rsp0", &mstp_clks[MSTP317]),
CLKDEV_CON_ID("rcan0", &mstp_clks[MSTP316]),
CLKDEV_CON_ID("rcan1", &mstp_clks[MSTP315]),
CLKDEV_CON_ID("fltcl0", &mstp_clks[MSTP314]),
CLKDEV_CON_ID("adc0", &mstp_clks[MSTP313]),
CLKDEV_CON_ID("mtu0", &mstp_clks[MSTP312]),
CLKDEV_CON_ID("iebus0", &mstp_clks[MSTP304]),
CLKDEV_DEV_ID("sh7734-gether.0", &mstp_clks[MSTP114]),
CLKDEV_CON_ID("rtc0", &mstp_clks[MSTP303]),
CLKDEV_CON_ID("hif0", &mstp_clks[MSTP302]),
CLKDEV_CON_ID("stif0", &mstp_clks[MSTP301]),
CLKDEV_CON_ID("stif1", &mstp_clks[MSTP300]),
};
int __init arch_clk_init(void)
{
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(main_clks); i++)
ret |= clk_register(main_clks[i]);
for (i = 0; i < ARRAY_SIZE(lookups); i++)
clkdev_add(&lookups[i]);
if (!ret)
ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
&div4_table);
if (!ret)
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
return ret;
}

View file

@ -0,0 +1,155 @@
/*
* arch/sh/kernel/cpu/sh4/clock-sh7757.c
*
* SH7757 support for the clock framework
*
* Copyright (C) 2009-2010 Renesas Solutions Corp.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
/*
* Default rate for the root input clock, reset this with clk_set_rate()
* from the platform code.
*/
static struct clk extal_clk = {
.rate = 48000000,
};
static unsigned long pll_recalc(struct clk *clk)
{
int multiplier;
multiplier = test_mode_pin(MODE_PIN0) ? 24 : 16;
return clk->parent->rate * multiplier;
}
static struct sh_clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll_clk = {
.ops = &pll_clk_ops,
.parent = &extal_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static struct clk *clks[] = {
&extal_clk,
&pll_clk,
};
static unsigned int div2[] = { 1, 1, 2, 1, 1, 4, 1, 6,
1, 1, 1, 16, 1, 24, 1, 1 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = div2,
.nr_divisors = ARRAY_SIZE(div2),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
};
enum { DIV4_I, DIV4_SH, DIV4_P, DIV4_NR };
#define DIV4(_bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, FRQCR, _bit, _mask, _flags)
struct clk div4_clks[DIV4_NR] = {
/*
* P clock is always enable, because some P clock modules is used
* by Host PC.
*/
[DIV4_P] = DIV4(0, 0x2800, CLK_ENABLE_ON_INIT),
[DIV4_SH] = DIV4(12, 0x00a0, CLK_ENABLE_ON_INIT),
[DIV4_I] = DIV4(20, 0x0004, CLK_ENABLE_ON_INIT),
};
#define MSTPCR0 0xffc80030
#define MSTPCR1 0xffc80034
#define MSTPCR2 0xffc10028
enum { MSTP004, MSTP000, MSTP127, MSTP114, MSTP113, MSTP112,
MSTP111, MSTP110, MSTP103, MSTP102, MSTP220,
MSTP_NR };
static struct clk mstp_clks[MSTP_NR] = {
/* MSTPCR0 */
[MSTP004] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
[MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0),
/* MSTPCR1 */
[MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 27, 0),
[MSTP114] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 14, 0),
[MSTP113] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 13, 0),
[MSTP112] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 12, 0),
[MSTP111] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 11, 0),
[MSTP110] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 10, 0),
[MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0),
[MSTP102] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 2, 0),
/* MSTPCR2 */
[MSTP220] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 20, 0),
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("extal", &extal_clk),
CLKDEV_CON_ID("pll_clk", &pll_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
/* MSTP32 clocks */
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP004]),
CLKDEV_CON_ID("riic0", &mstp_clks[MSTP000]),
CLKDEV_CON_ID("riic1", &mstp_clks[MSTP000]),
CLKDEV_CON_ID("riic2", &mstp_clks[MSTP000]),
CLKDEV_CON_ID("riic3", &mstp_clks[MSTP000]),
CLKDEV_CON_ID("riic4", &mstp_clks[MSTP000]),
CLKDEV_CON_ID("riic5", &mstp_clks[MSTP000]),
CLKDEV_CON_ID("riic6", &mstp_clks[MSTP000]),
CLKDEV_CON_ID("riic7", &mstp_clks[MSTP000]),
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP113]),
CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP114]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP112]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP111]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP110]),
CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]),
CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP102]),
CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]),
CLKDEV_DEV_ID("rspi.2", &mstp_clks[MSTP127]),
};
int __init arch_clk_init(void)
{
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(clks); i++)
ret |= clk_register(clks[i]);
for (i = 0; i < ARRAY_SIZE(lookups); i++)
clkdev_add(&lookups[i]);
if (!ret)
ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
&div4_table);
if (!ret)
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
return ret;
}

View file

@ -0,0 +1,119 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7763.c
*
* SH7763 support for the clock framework
*
* Copyright (C) 2005 Paul Mundt
* Copyright (C) 2007 Yoshihiro Shimoda
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <asm/io.h>
static int bfc_divisors[] = { 1, 1, 1, 8, 1, 1, 1, 1 };
static int p0fc_divisors[] = { 1, 1, 1, 8, 1, 1, 1, 1 };
static int cfc_divisors[] = { 1, 1, 4, 1, 1, 1, 1, 1 };
static void master_clk_init(struct clk *clk)
{
clk->rate *= p0fc_divisors[(__raw_readl(FRQCR) >> 4) & 0x07];
}
static struct sh_clk_ops sh7763_master_clk_ops = {
.init = master_clk_init,
};
static unsigned long module_clk_recalc(struct clk *clk)
{
int idx = ((__raw_readl(FRQCR) >> 4) & 0x07);
return clk->parent->rate / p0fc_divisors[idx];
}
static struct sh_clk_ops sh7763_module_clk_ops = {
.recalc = module_clk_recalc,
};
static unsigned long bus_clk_recalc(struct clk *clk)
{
int idx = ((__raw_readl(FRQCR) >> 16) & 0x07);
return clk->parent->rate / bfc_divisors[idx];
}
static struct sh_clk_ops sh7763_bus_clk_ops = {
.recalc = bus_clk_recalc,
};
static struct sh_clk_ops sh7763_cpu_clk_ops = {
.recalc = followparent_recalc,
};
static struct sh_clk_ops *sh7763_clk_ops[] = {
&sh7763_master_clk_ops,
&sh7763_module_clk_ops,
&sh7763_bus_clk_ops,
&sh7763_cpu_clk_ops,
};
void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
{
if (idx < ARRAY_SIZE(sh7763_clk_ops))
*ops = sh7763_clk_ops[idx];
}
static unsigned long shyway_clk_recalc(struct clk *clk)
{
int idx = ((__raw_readl(FRQCR) >> 20) & 0x07);
return clk->parent->rate / cfc_divisors[idx];
}
static struct sh_clk_ops sh7763_shyway_clk_ops = {
.recalc = shyway_clk_recalc,
};
static struct clk sh7763_shyway_clk = {
.flags = CLK_ENABLE_ON_INIT,
.ops = &sh7763_shyway_clk_ops,
};
/*
* Additional SH7763-specific on-chip clocks that aren't already part of the
* clock framework
*/
static struct clk *sh7763_onchip_clocks[] = {
&sh7763_shyway_clk,
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("shyway_clk", &sh7763_shyway_clk),
};
int __init arch_clk_init(void)
{
struct clk *clk;
int i, ret = 0;
cpg_clk_init();
clk = clk_get(NULL, "master_clk");
for (i = 0; i < ARRAY_SIZE(sh7763_onchip_clocks); i++) {
struct clk *clkp = sh7763_onchip_clocks[i];
clkp->parent = clk;
ret |= clk_register(clkp);
}
clk_put(clk);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
return ret;
}

View file

@ -0,0 +1,73 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7770.c
*
* SH7770 support for the clock framework
*
* Copyright (C) 2005 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <asm/io.h>
static int ifc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
static int bfc_divisors[] = { 1, 1, 1, 1, 1, 8,12, 1 };
static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 };
static void master_clk_init(struct clk *clk)
{
clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> 28) & 0x000f];
}
static struct sh_clk_ops sh7770_master_clk_ops = {
.init = master_clk_init,
};
static unsigned long module_clk_recalc(struct clk *clk)
{
int idx = ((__raw_readl(FRQCR) >> 28) & 0x000f);
return clk->parent->rate / pfc_divisors[idx];
}
static struct sh_clk_ops sh7770_module_clk_ops = {
.recalc = module_clk_recalc,
};
static unsigned long bus_clk_recalc(struct clk *clk)
{
int idx = (__raw_readl(FRQCR) & 0x000f);
return clk->parent->rate / bfc_divisors[idx];
}
static struct sh_clk_ops sh7770_bus_clk_ops = {
.recalc = bus_clk_recalc,
};
static unsigned long cpu_clk_recalc(struct clk *clk)
{
int idx = ((__raw_readl(FRQCR) >> 24) & 0x000f);
return clk->parent->rate / ifc_divisors[idx];
}
static struct sh_clk_ops sh7770_cpu_clk_ops = {
.recalc = cpu_clk_recalc,
};
static struct sh_clk_ops *sh7770_clk_ops[] = {
&sh7770_master_clk_ops,
&sh7770_module_clk_ops,
&sh7770_bus_clk_ops,
&sh7770_cpu_clk_ops,
};
void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
{
if (idx < ARRAY_SIZE(sh7770_clk_ops))
*ops = sh7770_clk_ops[idx];
}

View file

@ -0,0 +1,125 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7780.c
*
* SH7780 support for the clock framework
*
* Copyright (C) 2005 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <asm/io.h>
static int ifc_divisors[] = { 2, 4 };
static int bfc_divisors[] = { 1, 1, 1, 8, 12, 16, 24, 1 };
static int pfc_divisors[] = { 1, 24, 24, 1 };
static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 };
static void master_clk_init(struct clk *clk)
{
clk->rate *= pfc_divisors[__raw_readl(FRQCR) & 0x0003];
}
static struct sh_clk_ops sh7780_master_clk_ops = {
.init = master_clk_init,
};
static unsigned long module_clk_recalc(struct clk *clk)
{
int idx = (__raw_readl(FRQCR) & 0x0003);
return clk->parent->rate / pfc_divisors[idx];
}
static struct sh_clk_ops sh7780_module_clk_ops = {
.recalc = module_clk_recalc,
};
static unsigned long bus_clk_recalc(struct clk *clk)
{
int idx = ((__raw_readl(FRQCR) >> 16) & 0x0007);
return clk->parent->rate / bfc_divisors[idx];
}
static struct sh_clk_ops sh7780_bus_clk_ops = {
.recalc = bus_clk_recalc,
};
static unsigned long cpu_clk_recalc(struct clk *clk)
{
int idx = ((__raw_readl(FRQCR) >> 24) & 0x0001);
return clk->parent->rate / ifc_divisors[idx];
}
static struct sh_clk_ops sh7780_cpu_clk_ops = {
.recalc = cpu_clk_recalc,
};
static struct sh_clk_ops *sh7780_clk_ops[] = {
&sh7780_master_clk_ops,
&sh7780_module_clk_ops,
&sh7780_bus_clk_ops,
&sh7780_cpu_clk_ops,
};
void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
{
if (idx < ARRAY_SIZE(sh7780_clk_ops))
*ops = sh7780_clk_ops[idx];
}
static unsigned long shyway_clk_recalc(struct clk *clk)
{
int idx = ((__raw_readl(FRQCR) >> 20) & 0x0007);
return clk->parent->rate / cfc_divisors[idx];
}
static struct sh_clk_ops sh7780_shyway_clk_ops = {
.recalc = shyway_clk_recalc,
};
static struct clk sh7780_shyway_clk = {
.flags = CLK_ENABLE_ON_INIT,
.ops = &sh7780_shyway_clk_ops,
};
/*
* Additional SH7780-specific on-chip clocks that aren't already part of the
* clock framework
*/
static struct clk *sh7780_onchip_clocks[] = {
&sh7780_shyway_clk,
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("shyway_clk", &sh7780_shyway_clk),
};
int __init arch_clk_init(void)
{
struct clk *clk;
int i, ret = 0;
cpg_clk_init();
clk = clk_get(NULL, "master_clk");
for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) {
struct clk *clkp = sh7780_onchip_clocks[i];
clkp->parent = clk;
ret |= clk_register(clkp);
}
clk_put(clk);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
return ret;
}

View file

@ -0,0 +1,177 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7785.c
*
* SH7785 support for the clock framework
*
* Copyright (C) 2007 - 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/cpufreq.h>
#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <cpu/sh7785.h>
/*
* Default rate for the root input clock, reset this with clk_set_rate()
* from the platform code.
*/
static struct clk extal_clk = {
.rate = 33333333,
};
static unsigned long pll_recalc(struct clk *clk)
{
int multiplier;
multiplier = test_mode_pin(MODE_PIN4) ? 36 : 72;
return clk->parent->rate * multiplier;
}
static struct sh_clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll_clk = {
.ops = &pll_clk_ops,
.parent = &extal_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static struct clk *clks[] = {
&extal_clk,
&pll_clk,
};
static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
24, 32, 36, 48 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = div2,
.nr_divisors = ARRAY_SIZE(div2),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
};
enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_GA,
DIV4_DU, DIV4_P, DIV4_NR };
#define DIV4(_bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags)
struct clk div4_clks[DIV4_NR] = {
[DIV4_P] = DIV4(0, 0x0f80, 0),
[DIV4_DU] = DIV4(4, 0x0ff0, 0),
[DIV4_GA] = DIV4(8, 0x0030, 0),
[DIV4_DDR] = DIV4(12, 0x000c, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4(16, 0x0fe0, CLK_ENABLE_ON_INIT),
[DIV4_SH] = DIV4(20, 0x000c, CLK_ENABLE_ON_INIT),
[DIV4_U] = DIV4(24, 0x000c, CLK_ENABLE_ON_INIT),
[DIV4_I] = DIV4(28, 0x000e, CLK_ENABLE_ON_INIT),
};
#define MSTPCR0 0xffc80030
#define MSTPCR1 0xffc80034
enum { MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024,
MSTP021, MSTP020, MSTP017, MSTP016,
MSTP013, MSTP012, MSTP009, MSTP008, MSTP003, MSTP002,
MSTP119, MSTP117, MSTP105, MSTP104, MSTP100,
MSTP_NR };
static struct clk mstp_clks[MSTP_NR] = {
/* MSTPCR0 */
[MSTP029] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 29, 0),
[MSTP028] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 28, 0),
[MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0),
[MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0),
[MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0),
[MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0),
[MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
[MSTP020] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 20, 0),
[MSTP017] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 17, 0),
[MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0),
[MSTP013] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 13, 0),
[MSTP012] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 12, 0),
[MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
[MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
[MSTP003] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 3, 0),
[MSTP002] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
/* MSTPCR1 */
[MSTP119] = SH_CLK_MSTP32(NULL, MSTPCR1, 19, 0),
[MSTP117] = SH_CLK_MSTP32(NULL, MSTPCR1, 17, 0),
[MSTP105] = SH_CLK_MSTP32(NULL, MSTPCR1, 5, 0),
[MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0),
[MSTP100] = SH_CLK_MSTP32(NULL, MSTPCR1, 0, 0),
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("extal", &extal_clk),
CLKDEV_CON_ID("pll_clk", &pll_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
CLKDEV_CON_ID("du_clk", &div4_clks[DIV4_DU]),
CLKDEV_CON_ID("ga_clk", &div4_clks[DIV4_GA]),
CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_DDR]),
CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
/* MSTP32 clocks */
CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP029]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP028]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]),
CLKDEV_CON_ID("ssi1_fck", &mstp_clks[MSTP021]),
CLKDEV_CON_ID("ssi0_fck", &mstp_clks[MSTP020]),
CLKDEV_CON_ID("hac1_fck", &mstp_clks[MSTP017]),
CLKDEV_CON_ID("hac0_fck", &mstp_clks[MSTP016]),
CLKDEV_CON_ID("mmcif_fck", &mstp_clks[MSTP013]),
CLKDEV_CON_ID("flctl_fck", &mstp_clks[MSTP012]),
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP008]),
CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP009]),
CLKDEV_CON_ID("siof_fck", &mstp_clks[MSTP003]),
CLKDEV_CON_ID("hspi_fck", &mstp_clks[MSTP002]),
CLKDEV_CON_ID("hudi_fck", &mstp_clks[MSTP119]),
CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP117]),
CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]),
CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]),
CLKDEV_CON_ID("gdta_fck", &mstp_clks[MSTP100]),
};
int __init arch_clk_init(void)
{
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(clks); i++)
ret |= clk_register(clks[i]);
for (i = 0; i < ARRAY_SIZE(lookups); i++)
clkdev_add(&lookups[i]);
if (!ret)
ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
&div4_table);
if (!ret)
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
return ret;
}

View file

@ -0,0 +1,192 @@
/*
* arch/sh/kernel/cpu/sh4a/clock-sh7786.c
*
* SH7786 support for the clock framework
*
* Copyright (C) 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
/*
* Default rate for the root input clock, reset this with clk_set_rate()
* from the platform code.
*/
static struct clk extal_clk = {
.rate = 33333333,
};
static unsigned long pll_recalc(struct clk *clk)
{
int multiplier;
/*
* Clock modes 0, 1, and 2 use an x64 multiplier against PLL1,
* while modes 3, 4, and 5 use an x32.
*/
multiplier = (sh_mv.mv_mode_pins() & 0xf) < 3 ? 64 : 32;
return clk->parent->rate * multiplier;
}
static struct sh_clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll_clk = {
.ops = &pll_clk_ops,
.parent = &extal_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static struct clk *clks[] = {
&extal_clk,
&pll_clk,
};
static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
24, 32, 36, 48 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = div2,
.nr_divisors = ARRAY_SIZE(div2),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
};
enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_DU, DIV4_P, DIV4_NR };
#define DIV4(_bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags)
struct clk div4_clks[DIV4_NR] = {
[DIV4_P] = DIV4(0, 0x0b40, 0),
[DIV4_DU] = DIV4(4, 0x0010, 0),
[DIV4_DDR] = DIV4(12, 0x0002, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4(16, 0x0360, CLK_ENABLE_ON_INIT),
[DIV4_SH] = DIV4(20, 0x0002, CLK_ENABLE_ON_INIT),
[DIV4_I] = DIV4(28, 0x0006, CLK_ENABLE_ON_INIT),
};
#define MSTPCR0 0xffc40030
#define MSTPCR1 0xffc40034
enum { MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024,
MSTP023, MSTP022, MSTP021, MSTP020, MSTP017, MSTP016,
MSTP015, MSTP014, MSTP011, MSTP010, MSTP009, MSTP008,
MSTP005, MSTP004, MSTP002,
MSTP112, MSTP110, MSTP109, MSTP108,
MSTP105, MSTP104, MSTP103, MSTP102,
MSTP_NR };
static struct clk mstp_clks[MSTP_NR] = {
/* MSTPCR0 */
[MSTP029] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 29, 0),
[MSTP028] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 28, 0),
[MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0),
[MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0),
[MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0),
[MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0),
[MSTP023] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 23, 0),
[MSTP022] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 22, 0),
[MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
[MSTP020] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 20, 0),
[MSTP017] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 17, 0),
[MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0),
[MSTP015] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
[MSTP014] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 14, 0),
[MSTP011] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
[MSTP010] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
[MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
[MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
[MSTP005] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
[MSTP004] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
[MSTP002] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
/* MSTPCR1 */
[MSTP112] = SH_CLK_MSTP32(NULL, MSTPCR1, 12, 0),
[MSTP110] = SH_CLK_MSTP32(NULL, MSTPCR1, 10, 0),
[MSTP109] = SH_CLK_MSTP32(NULL, MSTPCR1, 9, 0),
[MSTP108] = SH_CLK_MSTP32(NULL, MSTPCR1, 8, 0),
[MSTP105] = SH_CLK_MSTP32(NULL, MSTPCR1, 5, 0),
[MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0),
[MSTP103] = SH_CLK_MSTP32(NULL, MSTPCR1, 3, 0),
[MSTP102] = SH_CLK_MSTP32(NULL, MSTPCR1, 2, 0),
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("extal", &extal_clk),
CLKDEV_CON_ID("pll_clk", &pll_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
CLKDEV_CON_ID("du_clk", &div4_clks[DIV4_DU]),
CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_DDR]),
CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
/* MSTP32 clocks */
CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP029]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP028]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]),
CLKDEV_CON_ID("ssi3_fck", &mstp_clks[MSTP023]),
CLKDEV_CON_ID("ssi2_fck", &mstp_clks[MSTP022]),
CLKDEV_CON_ID("ssi1_fck", &mstp_clks[MSTP021]),
CLKDEV_CON_ID("ssi0_fck", &mstp_clks[MSTP020]),
CLKDEV_CON_ID("hac1_fck", &mstp_clks[MSTP017]),
CLKDEV_CON_ID("hac0_fck", &mstp_clks[MSTP016]),
CLKDEV_CON_ID("i2c1_fck", &mstp_clks[MSTP015]),
CLKDEV_CON_ID("i2c0_fck", &mstp_clks[MSTP014]),
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP008]),
CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP009]),
CLKDEV_ICK_ID("fck", "sh-tmu.2", &mstp_clks[MSTP010]),
CLKDEV_ICK_ID("fck", "sh-tmu.3", &mstp_clks[MSTP011]),
CLKDEV_CON_ID("sdif1_fck", &mstp_clks[MSTP005]),
CLKDEV_CON_ID("sdif0_fck", &mstp_clks[MSTP004]),
CLKDEV_CON_ID("hspi_fck", &mstp_clks[MSTP002]),
CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP112]),
CLKDEV_CON_ID("pcie2_fck", &mstp_clks[MSTP110]),
CLKDEV_CON_ID("pcie1_fck", &mstp_clks[MSTP109]),
CLKDEV_CON_ID("pcie0_fck", &mstp_clks[MSTP108]),
CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]),
CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]),
CLKDEV_CON_ID("du_fck", &mstp_clks[MSTP103]),
CLKDEV_CON_ID("ether_fck", &mstp_clks[MSTP102]),
};
int __init arch_clk_init(void)
{
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(clks); i++)
ret |= clk_register(clks[i]);
for (i = 0; i < ARRAY_SIZE(lookups); i++)
clkdev_add(&lookups[i]);
if (!ret)
ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
&div4_table);
if (!ret)
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
return ret;
}

View file

@ -0,0 +1,151 @@
/*
* arch/sh/kernel/cpu/sh4/clock-shx3.c
*
* SH-X3 support for the clock framework
*
* Copyright (C) 2006-2007 Renesas Technology Corp.
* Copyright (C) 2006-2007 Renesas Solutions Corp.
* Copyright (C) 2006-2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
/*
* Default rate for the root input clock, reset this with clk_set_rate()
* from the platform code.
*/
static struct clk extal_clk = {
.rate = 16666666,
};
static unsigned long pll_recalc(struct clk *clk)
{
/* PLL1 has a fixed x72 multiplier. */
return clk->parent->rate * 72;
}
static struct sh_clk_ops pll_clk_ops = {
.recalc = pll_recalc,
};
static struct clk pll_clk = {
.ops = &pll_clk_ops,
.parent = &extal_clk,
.flags = CLK_ENABLE_ON_INIT,
};
static struct clk *clks[] = {
&extal_clk,
&pll_clk,
};
static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
24, 32, 36, 48 };
static struct clk_div_mult_table div4_div_mult_table = {
.divisors = div2,
.nr_divisors = ARRAY_SIZE(div2),
};
static struct clk_div4_table div4_table = {
.div_mult_table = &div4_div_mult_table,
};
enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_SHA, DIV4_P, DIV4_NR };
#define DIV4(_bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags)
struct clk div4_clks[DIV4_NR] = {
[DIV4_P] = DIV4(0, 0x0f80, 0),
[DIV4_SHA] = DIV4(4, 0x0ff0, 0),
[DIV4_DDR] = DIV4(12, 0x000c, CLK_ENABLE_ON_INIT),
[DIV4_B] = DIV4(16, 0x0fe0, CLK_ENABLE_ON_INIT),
[DIV4_SH] = DIV4(20, 0x000c, CLK_ENABLE_ON_INIT),
[DIV4_I] = DIV4(28, 0x000e, CLK_ENABLE_ON_INIT),
};
#define MSTPCR0 0xffc00030
#define MSTPCR1 0xffc00034
enum { MSTP027, MSTP026, MSTP025, MSTP024,
MSTP009, MSTP008, MSTP003, MSTP002,
MSTP001, MSTP000, MSTP119, MSTP105,
MSTP104, MSTP_NR };
static struct clk mstp_clks[MSTP_NR] = {
/* MSTPCR0 */
[MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0),
[MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0),
[MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0),
[MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0),
[MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
[MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
[MSTP003] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 3, 0),
[MSTP002] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
[MSTP001] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 1, 0),
[MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0),
/* MSTPCR1 */
[MSTP119] = SH_CLK_MSTP32(NULL, MSTPCR1, 19, 0),
[MSTP105] = SH_CLK_MSTP32(NULL, MSTPCR1, 5, 0),
[MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0),
};
static struct clk_lookup lookups[] = {
/* main clocks */
CLKDEV_CON_ID("extal", &extal_clk),
CLKDEV_CON_ID("pll_clk", &pll_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
CLKDEV_CON_ID("shywaya_clk", &div4_clks[DIV4_SHA]),
CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_DDR]),
CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
/* MSTP32 clocks */
CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP027]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP026]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]),
CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP024]),
CLKDEV_CON_ID("h8ex_fck", &mstp_clks[MSTP003]),
CLKDEV_CON_ID("csm_fck", &mstp_clks[MSTP002]),
CLKDEV_CON_ID("fe1_fck", &mstp_clks[MSTP001]),
CLKDEV_CON_ID("fe0_fck", &mstp_clks[MSTP000]),
CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP008]),
CLKDEV_ICK_ID("fck", "sh-tmu.1", &mstp_clks[MSTP009]),
CLKDEV_CON_ID("hudi_fck", &mstp_clks[MSTP119]),
CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]),
CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]),
};
int __init arch_clk_init(void)
{
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(clks); i++)
ret |= clk_register(clks[i]);
for (i = 0; i < ARRAY_SIZE(lookups); i++)
clkdev_add(&lookups[i]);
if (!ret)
ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
&div4_table);
if (!ret)
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
return ret;
}

View file

@ -0,0 +1,34 @@
/*
* Shared support for SH-X3 interrupt controllers.
*
* Copyright (C) 2009 - 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/init.h>
#define INTACK 0xfe4100b8
#define INTACKCLR 0xfe4100bc
#define INTC_USERIMASK 0xfe411000
#ifdef CONFIG_INTC_BALANCING
unsigned int irq_lookup(unsigned int irq)
{
return __raw_readl(INTACK) & 1 ? irq : NO_IRQ_IGNORE;
}
void irq_finish(unsigned int irq)
{
__raw_writel(irq2evt(irq), INTACKCLR);
}
#endif
static int __init shx3_irq_setup(void)
{
return register_intc_userimask(INTC_USERIMASK);
}
arch_initcall(shx3_irq_setup);

View file

@ -0,0 +1,302 @@
/*
* Performance events support for SH-4A performance counters
*
* Copyright (C) 2009, 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/perf_event.h>
#include <asm/processor.h>
#define PPC_CCBR(idx) (0xff200800 + (sizeof(u32) * idx))
#define PPC_PMCTR(idx) (0xfc100000 + (sizeof(u32) * idx))
#define CCBR_CIT_MASK (0x7ff << 6)
#define CCBR_DUC (1 << 3)
#define CCBR_CMDS (1 << 1)
#define CCBR_PPCE (1 << 0)
#ifdef CONFIG_CPU_SHX3
/*
* The PMCAT location for SH-X3 CPUs was quietly moved, while the CCBR
* and PMCTR locations remains tentatively constant. This change remains
* wholly undocumented, and was simply found through trial and error.
*
* Early cuts of SH-X3 still appear to use the SH-X/SH-X2 locations, and
* it's unclear when this ceased to be the case. For now we always use
* the new location (if future parts keep up with this trend then
* scanning for them at runtime also remains a viable option.)
*
* The gap in the register space also suggests that there are other
* undocumented counters, so this will need to be revisited at a later
* point in time.
*/
#define PPC_PMCAT 0xfc100240
#else
#define PPC_PMCAT 0xfc100080
#endif
#define PMCAT_OVF3 (1 << 27)
#define PMCAT_CNN3 (1 << 26)
#define PMCAT_CLR3 (1 << 25)
#define PMCAT_OVF2 (1 << 19)
#define PMCAT_CLR2 (1 << 17)
#define PMCAT_OVF1 (1 << 11)
#define PMCAT_CNN1 (1 << 10)
#define PMCAT_CLR1 (1 << 9)
#define PMCAT_OVF0 (1 << 3)
#define PMCAT_CLR0 (1 << 1)
static struct sh_pmu sh4a_pmu;
/*
* Supported raw event codes:
*
* Event Code Description
* ---------- -----------
*
* 0x0000 number of elapsed cycles
* 0x0200 number of elapsed cycles in privileged mode
* 0x0280 number of elapsed cycles while SR.BL is asserted
* 0x0202 instruction execution
* 0x0203 instruction execution in parallel
* 0x0204 number of unconditional branches
* 0x0208 number of exceptions
* 0x0209 number of interrupts
* 0x0220 UTLB miss caused by instruction fetch
* 0x0222 UTLB miss caused by operand access
* 0x02a0 number of ITLB misses
* 0x0028 number of accesses to instruction memories
* 0x0029 number of accesses to instruction cache
* 0x002a instruction cache miss
* 0x022e number of access to instruction X/Y memory
* 0x0030 number of reads to operand memories
* 0x0038 number of writes to operand memories
* 0x0031 number of operand cache read accesses
* 0x0039 number of operand cache write accesses
* 0x0032 operand cache read miss
* 0x003a operand cache write miss
* 0x0236 number of reads to operand X/Y memory
* 0x023e number of writes to operand X/Y memory
* 0x0237 number of reads to operand U memory
* 0x023f number of writes to operand U memory
* 0x0337 number of U memory read buffer misses
* 0x02b4 number of wait cycles due to operand read access
* 0x02bc number of wait cycles due to operand write access
* 0x0033 number of wait cycles due to operand cache read miss
* 0x003b number of wait cycles due to operand cache write miss
*/
/*
* Special reserved bits used by hardware emulators, read values will
* vary, but writes must always be 0.
*/
#define PMCAT_EMU_CLR_MASK ((1 << 24) | (1 << 16) | (1 << 8) | (1 << 0))
static const int sh4a_general_events[] = {
[PERF_COUNT_HW_CPU_CYCLES] = 0x0000,
[PERF_COUNT_HW_INSTRUCTIONS] = 0x0202,
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x0029, /* I-cache */
[PERF_COUNT_HW_CACHE_MISSES] = 0x002a, /* I-cache */
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x0204,
[PERF_COUNT_HW_BRANCH_MISSES] = -1,
[PERF_COUNT_HW_BUS_CYCLES] = -1,
};
#define C(x) PERF_COUNT_HW_CACHE_##x
static const int sh4a_cache_events
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
{
[ C(L1D) ] = {
[ C(OP_READ) ] = {
[ C(RESULT_ACCESS) ] = 0x0031,
[ C(RESULT_MISS) ] = 0x0032,
},
[ C(OP_WRITE) ] = {
[ C(RESULT_ACCESS) ] = 0x0039,
[ C(RESULT_MISS) ] = 0x003a,
},
[ C(OP_PREFETCH) ] = {
[ C(RESULT_ACCESS) ] = 0,
[ C(RESULT_MISS) ] = 0,
},
},
[ C(L1I) ] = {
[ C(OP_READ) ] = {
[ C(RESULT_ACCESS) ] = 0x0029,
[ C(RESULT_MISS) ] = 0x002a,
},
[ C(OP_WRITE) ] = {
[ C(RESULT_ACCESS) ] = -1,
[ C(RESULT_MISS) ] = -1,
},
[ C(OP_PREFETCH) ] = {
[ C(RESULT_ACCESS) ] = 0,
[ C(RESULT_MISS) ] = 0,
},
},
[ C(LL) ] = {
[ C(OP_READ) ] = {
[ C(RESULT_ACCESS) ] = 0x0030,
[ C(RESULT_MISS) ] = 0,
},
[ C(OP_WRITE) ] = {
[ C(RESULT_ACCESS) ] = 0x0038,
[ C(RESULT_MISS) ] = 0,
},
[ C(OP_PREFETCH) ] = {
[ C(RESULT_ACCESS) ] = 0,
[ C(RESULT_MISS) ] = 0,
},
},
[ C(DTLB) ] = {
[ C(OP_READ) ] = {
[ C(RESULT_ACCESS) ] = 0x0222,
[ C(RESULT_MISS) ] = 0x0220,
},
[ C(OP_WRITE) ] = {
[ C(RESULT_ACCESS) ] = 0,
[ C(RESULT_MISS) ] = 0,
},
[ C(OP_PREFETCH) ] = {
[ C(RESULT_ACCESS) ] = 0,
[ C(RESULT_MISS) ] = 0,
},
},
[ C(ITLB) ] = {
[ C(OP_READ) ] = {
[ C(RESULT_ACCESS) ] = 0,
[ C(RESULT_MISS) ] = 0x02a0,
},
[ C(OP_WRITE) ] = {
[ C(RESULT_ACCESS) ] = -1,
[ C(RESULT_MISS) ] = -1,
},
[ C(OP_PREFETCH) ] = {
[ C(RESULT_ACCESS) ] = -1,
[ C(RESULT_MISS) ] = -1,
},
},
[ C(BPU) ] = {
[ C(OP_READ) ] = {
[ C(RESULT_ACCESS) ] = -1,
[ C(RESULT_MISS) ] = -1,
},
[ C(OP_WRITE) ] = {
[ C(RESULT_ACCESS) ] = -1,
[ C(RESULT_MISS) ] = -1,
},
[ C(OP_PREFETCH) ] = {
[ C(RESULT_ACCESS) ] = -1,
[ C(RESULT_MISS) ] = -1,
},
},
[ C(NODE) ] = {
[ C(OP_READ) ] = {
[ C(RESULT_ACCESS) ] = -1,
[ C(RESULT_MISS) ] = -1,
},
[ C(OP_WRITE) ] = {
[ C(RESULT_ACCESS) ] = -1,
[ C(RESULT_MISS) ] = -1,
},
[ C(OP_PREFETCH) ] = {
[ C(RESULT_ACCESS) ] = -1,
[ C(RESULT_MISS) ] = -1,
},
},
};
static int sh4a_event_map(int event)
{
return sh4a_general_events[event];
}
static u64 sh4a_pmu_read(int idx)
{
return __raw_readl(PPC_PMCTR(idx));
}
static void sh4a_pmu_disable(struct hw_perf_event *hwc, int idx)
{
unsigned int tmp;
tmp = __raw_readl(PPC_CCBR(idx));
tmp &= ~(CCBR_CIT_MASK | CCBR_DUC);
__raw_writel(tmp, PPC_CCBR(idx));
}
static void sh4a_pmu_enable(struct hw_perf_event *hwc, int idx)
{
unsigned int tmp;
tmp = __raw_readl(PPC_PMCAT);
tmp &= ~PMCAT_EMU_CLR_MASK;
tmp |= idx ? PMCAT_CLR1 : PMCAT_CLR0;
__raw_writel(tmp, PPC_PMCAT);
tmp = __raw_readl(PPC_CCBR(idx));
tmp |= (hwc->config << 6) | CCBR_CMDS | CCBR_PPCE;
__raw_writel(tmp, PPC_CCBR(idx));
__raw_writel(__raw_readl(PPC_CCBR(idx)) | CCBR_DUC, PPC_CCBR(idx));
}
static void sh4a_pmu_disable_all(void)
{
int i;
for (i = 0; i < sh4a_pmu.num_events; i++)
__raw_writel(__raw_readl(PPC_CCBR(i)) & ~CCBR_DUC, PPC_CCBR(i));
}
static void sh4a_pmu_enable_all(void)
{
int i;
for (i = 0; i < sh4a_pmu.num_events; i++)
__raw_writel(__raw_readl(PPC_CCBR(i)) | CCBR_DUC, PPC_CCBR(i));
}
static struct sh_pmu sh4a_pmu = {
.name = "sh4a",
.num_events = 2,
.event_map = sh4a_event_map,
.max_events = ARRAY_SIZE(sh4a_general_events),
.raw_event_mask = 0x3ff,
.cache_events = &sh4a_cache_events,
.read = sh4a_pmu_read,
.disable = sh4a_pmu_disable,
.enable = sh4a_pmu_enable,
.disable_all = sh4a_pmu_disable_all,
.enable_all = sh4a_pmu_enable_all,
};
static int __init sh4a_pmu_init(void)
{
/*
* Make sure this CPU actually has perf counters.
*/
if (!(boot_cpu_data.flags & CPU_HAS_PERF_COUNTER)) {
pr_notice("HW perf events unsupported, software events only.\n");
return -ENODEV;
}
return register_sh_pmu(&sh4a_pmu);
}
early_initcall(sh4a_pmu_init);

View file

@ -0,0 +1,20 @@
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <cpu/pfc.h>
static struct resource sh7722_pfc_resources[] = {
[0] = {
.start = 0xa4050100,
.end = 0xa405018f,
.flags = IORESOURCE_MEM,
},
};
static int __init plat_pinmux_setup(void)
{
return sh_pfc_register("pfc-sh7722", sh7722_pfc_resources,
ARRAY_SIZE(sh7722_pfc_resources));
}
arch_initcall(plat_pinmux_setup);

View file

@ -0,0 +1,30 @@
/*
* SH7723 Pinmux
*
* Copyright (C) 2008 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <cpu/pfc.h>
static struct resource sh7723_pfc_resources[] = {
[0] = {
.start = 0xa4050100,
.end = 0xa405016f,
.flags = IORESOURCE_MEM,
},
};
static int __init plat_pinmux_setup(void)
{
return sh_pfc_register("pfc-sh7723", sh7723_pfc_resources,
ARRAY_SIZE(sh7723_pfc_resources));
}
arch_initcall(plat_pinmux_setup);

View file

@ -0,0 +1,35 @@
/*
* SH7724 Pinmux
*
* Copyright (C) 2009 Renesas Solutions Corp.
*
* Kuninori Morimoto <morimoto.kuninori@renesas.com>
*
* Based on SH7723 Pinmux
* Copyright (C) 2008 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <cpu/pfc.h>
static struct resource sh7724_pfc_resources[] = {
[0] = {
.start = 0xa4050100,
.end = 0xa405016f,
.flags = IORESOURCE_MEM,
},
};
static int __init plat_pinmux_setup(void)
{
return sh_pfc_register("pfc-sh7724", sh7724_pfc_resources,
ARRAY_SIZE(sh7724_pfc_resources));
}
arch_initcall(plat_pinmux_setup);

View file

@ -0,0 +1,35 @@
/*
* SH7734 processor support - PFC hardware block
*
* Copyright (C) 2012 Renesas Solutions Corp.
* Copyright (C) 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <cpu/pfc.h>
static struct resource sh7734_pfc_resources[] = {
[0] = { /* PFC */
.start = 0xFFFC0000,
.end = 0xFFFC011C,
.flags = IORESOURCE_MEM,
},
[1] = { /* GPIO */
.start = 0xFFC40000,
.end = 0xFFC4502B,
.flags = IORESOURCE_MEM,
}
};
static int __init plat_pinmux_setup(void)
{
return sh_pfc_register("pfc-sh7734", sh7734_pfc_resources,
ARRAY_SIZE(sh7734_pfc_resources));
}
arch_initcall(plat_pinmux_setup);

View file

@ -0,0 +1,35 @@
/*
* SH7757 (B0 step) Pinmux
*
* Copyright (C) 2009-2010 Renesas Solutions Corp.
*
* Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
*
* Based on SH7723 Pinmux
* Copyright (C) 2008 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <cpu/pfc.h>
static struct resource sh7757_pfc_resources[] = {
[0] = {
.start = 0xffec0000,
.end = 0xffec008f,
.flags = IORESOURCE_MEM,
},
};
static int __init plat_pinmux_setup(void)
{
return sh_pfc_register("pfc-sh7757", sh7757_pfc_resources,
ARRAY_SIZE(sh7757_pfc_resources));
}
arch_initcall(plat_pinmux_setup);

View file

@ -0,0 +1,30 @@
/*
* SH7785 Pinmux
*
* Copyright (C) 2008 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <cpu/pfc.h>
static struct resource sh7785_pfc_resources[] = {
[0] = {
.start = 0xffe70000,
.end = 0xffe7008f,
.flags = IORESOURCE_MEM,
},
};
static int __init plat_pinmux_setup(void)
{
return sh_pfc_register("pfc-sh7785", sh7785_pfc_resources,
ARRAY_SIZE(sh7785_pfc_resources));
}
arch_initcall(plat_pinmux_setup);

View file

@ -0,0 +1,35 @@
/*
* SH7786 Pinmux
*
* Copyright (C) 2008, 2009 Renesas Solutions Corp.
* Kuninori Morimoto <morimoto.kuninori@renesas.com>
*
* Based on SH7785 pinmux
*
* Copyright (C) 2008 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <cpu/pfc.h>
static struct resource sh7786_pfc_resources[] = {
[0] = {
.start = 0xffcc0000,
.end = 0xffcc008f,
.flags = IORESOURCE_MEM,
},
};
static int __init plat_pinmux_setup(void)
{
return sh_pfc_register("pfc-sh7786", sh7786_pfc_resources,
ARRAY_SIZE(sh7786_pfc_resources));
}
arch_initcall(plat_pinmux_setup);

View file

@ -0,0 +1,29 @@
/*
* SH-X3 prototype CPU pinmux
*
* Copyright (C) 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <cpu/pfc.h>
static struct resource shx3_pfc_resources[] = {
[0] = {
.start = 0xffc70000,
.end = 0xffc7001f,
.flags = IORESOURCE_MEM,
},
};
static int __init plat_pinmux_setup(void)
{
return sh_pfc_register("pfc-shx3", shx3_pfc_resources,
ARRAY_SIZE(shx3_pfc_resources));
}
arch_initcall(plat_pinmux_setup);

View file

@ -0,0 +1,23 @@
#include <linux/serial_sci.h>
#include <linux/serial_core.h>
#include <linux/io.h>
#define PSCR 0xA405011E
static void sh7722_sci_init_pins(struct uart_port *port, unsigned int cflag)
{
unsigned short data;
if (port->mapbase == 0xffe00000) {
data = __raw_readw(PSCR);
data &= ~0x03cf;
if (!(cflag & CRTSCTS))
data |= 0x0340;
__raw_writew(data, PSCR);
}
}
struct plat_sci_port_ops sh7722_sci_port_ops = {
.init_pins = sh7722_sci_init_pins,
};

View file

@ -0,0 +1,450 @@
/*
* SH7343 Setup
*
* Copyright (C) 2006 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/uio_driver.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <asm/clock.h>
/* Serial */
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
.type = PORT_SCIF,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xffe00000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc00)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
.type = PORT_SCIF,
};
static struct resource scif1_resources[] = {
DEFINE_RES_MEM(0xffe10000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc20)),
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.resource = scif1_resources,
.num_resources = ARRAY_SIZE(scif1_resources),
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
.type = PORT_SCIF,
};
static struct resource scif2_resources[] = {
DEFINE_RES_MEM(0xffe20000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc40)),
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.resource = scif2_resources,
.num_resources = ARRAY_SIZE(scif2_resources),
.dev = {
.platform_data = &scif2_platform_data,
},
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
.type = PORT_SCIF,
};
static struct resource scif3_resources[] = {
DEFINE_RES_MEM(0xffe30000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc60)),
};
static struct platform_device scif3_device = {
.name = "sh-sci",
.id = 3,
.resource = scif3_resources,
.num_resources = ARRAY_SIZE(scif3_resources),
.dev = {
.platform_data = &scif3_platform_data,
},
};
static struct resource iic0_resources[] = {
[0] = {
.name = "IIC0",
.start = 0x04470000,
.end = 0x04470017,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xe00),
.end = evt2irq(0xe60),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device iic0_device = {
.name = "i2c-sh_mobile",
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic0_resources),
.resource = iic0_resources,
};
static struct resource iic1_resources[] = {
[0] = {
.name = "IIC1",
.start = 0x04750000,
.end = 0x04750017,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0x780),
.end = evt2irq(0x7e0),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device iic1_device = {
.name = "i2c-sh_mobile",
.id = 1, /* "i2c1" clock */
.num_resources = ARRAY_SIZE(iic1_resources),
.resource = iic1_resources,
};
static struct uio_info vpu_platform_data = {
.name = "VPU4",
.version = "0",
.irq = evt2irq(0x980),
};
static struct resource vpu_resources[] = {
[0] = {
.name = "VPU",
.start = 0xfe900000,
.end = 0xfe9022eb,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device vpu_device = {
.name = "uio_pdrv_genirq",
.id = 0,
.dev = {
.platform_data = &vpu_platform_data,
},
.resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources),
};
static struct uio_info veu_platform_data = {
.name = "VEU",
.version = "0",
.irq = evt2irq(0x8c0),
};
static struct resource veu_resources[] = {
[0] = {
.name = "VEU",
.start = 0xfe920000,
.end = 0xfe9200b7,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device veu_device = {
.name = "uio_pdrv_genirq",
.id = 1,
.dev = {
.platform_data = &veu_platform_data,
},
.resource = veu_resources,
.num_resources = ARRAY_SIZE(veu_resources),
};
static struct uio_info jpu_platform_data = {
.name = "JPU",
.version = "0",
.irq = evt2irq(0x560),
};
static struct resource jpu_resources[] = {
[0] = {
.name = "JPU",
.start = 0xfea00000,
.end = 0xfea102d3,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device jpu_device = {
.name = "uio_pdrv_genirq",
.id = 2,
.dev = {
.platform_data = &jpu_platform_data,
},
.resource = jpu_resources,
.num_resources = ARRAY_SIZE(jpu_resources),
};
static struct sh_timer_config cmt_platform_data = {
.channels_mask = 0x20,
};
static struct resource cmt_resources[] = {
DEFINE_RES_MEM(0x044a0000, 0x70),
DEFINE_RES_IRQ(evt2irq(0xf00)),
};
static struct platform_device cmt_device = {
.name = "sh-cmt-32",
.id = 0,
.dev = {
.platform_data = &cmt_platform_data,
},
.resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources),
};
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffd80000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0x400)),
DEFINE_RES_IRQ(evt2irq(0x420)),
DEFINE_RES_IRQ(evt2irq(0x440)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct platform_device *sh7343_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&cmt_device,
&tmu0_device,
&iic0_device,
&iic1_device,
&vpu_device,
&veu_device,
&jpu_device,
};
static int __init sh7343_devices_setup(void)
{
platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20);
platform_resource_setup_memory(&veu_device, "veu", 2 << 20);
platform_resource_setup_memory(&jpu_device, "jpu", 2 << 20);
return platform_add_devices(sh7343_devices,
ARRAY_SIZE(sh7343_devices));
}
arch_initcall(sh7343_devices_setup);
static struct platform_device *sh7343_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&cmt_device,
&tmu0_device,
};
void __init plat_early_device_setup(void)
{
early_platform_add_devices(sh7343_early_devices,
ARRAY_SIZE(sh7343_early_devices));
}
enum {
UNUSED = 0,
ENABLED,
DISABLED,
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
DMAC0, DMAC1, DMAC2, DMAC3,
VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU,
MFI, VPU, TPU, Z3D4, USBI0, USBI1,
MMC_ERR, MMC_TRAN, MMC_FSTAT, MMC_FRDY,
DMAC4, DMAC5, DMAC_DADERR,
KEYSC,
SCIF, SCIF1, SCIF2, SCIF3,
SIOF0, SIOF1, SIO,
FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI,
I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI,
SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI,
IRDA, SDHI, CMT, TSIF, SIU,
TMU0, TMU1, TMU2,
JPU, LCDC,
/* interrupt groups */
DMAC0123, VIOVOU, MMC, DMAC45, FLCTL, I2C0, I2C1, SIM, USB,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0),
INTC_VECT(I2C1_ALI, 0x780), INTC_VECT(I2C1_TACKI, 0x7a0),
INTC_VECT(I2C1_WAITI, 0x7c0), INTC_VECT(I2C1_DTEI, 0x7e0),
INTC_VECT(DMAC0, 0x800), INTC_VECT(DMAC1, 0x820),
INTC_VECT(DMAC2, 0x840), INTC_VECT(DMAC3, 0x860),
INTC_VECT(VIO_CEUI, 0x880), INTC_VECT(VIO_BEUI, 0x8a0),
INTC_VECT(VIO_VEUI, 0x8c0), INTC_VECT(VOU, 0x8e0),
INTC_VECT(MFI, 0x900), INTC_VECT(VPU, 0x980),
INTC_VECT(TPU, 0x9a0), INTC_VECT(Z3D4, 0x9e0),
INTC_VECT(USBI0, 0xa20), INTC_VECT(USBI1, 0xa40),
INTC_VECT(MMC_ERR, 0xb00), INTC_VECT(MMC_TRAN, 0xb20),
INTC_VECT(MMC_FSTAT, 0xb40), INTC_VECT(MMC_FRDY, 0xb60),
INTC_VECT(DMAC4, 0xb80), INTC_VECT(DMAC5, 0xba0),
INTC_VECT(DMAC_DADERR, 0xbc0), INTC_VECT(KEYSC, 0xbe0),
INTC_VECT(SCIF, 0xc00), INTC_VECT(SCIF1, 0xc20),
INTC_VECT(SCIF2, 0xc40), INTC_VECT(SCIF3, 0xc60),
INTC_VECT(SIOF0, 0xc80), INTC_VECT(SIOF1, 0xca0),
INTC_VECT(SIO, 0xd00),
INTC_VECT(FLCTL_FLSTEI, 0xd80), INTC_VECT(FLCTL_FLENDI, 0xda0),
INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0),
INTC_VECT(I2C0_ALI, 0xe00), INTC_VECT(I2C0_TACKI, 0xe20),
INTC_VECT(I2C0_WAITI, 0xe40), INTC_VECT(I2C0_DTEI, 0xe60),
INTC_VECT(SDHI, 0xe80), INTC_VECT(SDHI, 0xea0),
INTC_VECT(SDHI, 0xec0), INTC_VECT(SDHI, 0xee0),
INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20),
INTC_VECT(SIU, 0xf80),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
INTC_VECT(TMU2, 0x440),
INTC_VECT(JPU, 0x560), INTC_VECT(LCDC, 0x580),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3),
INTC_GROUP(VIOVOU, VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU),
INTC_GROUP(MMC, MMC_FRDY, MMC_FSTAT, MMC_TRAN, MMC_ERR),
INTC_GROUP(DMAC45, DMAC4, DMAC5, DMAC_DADERR),
INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI,
FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
INTC_GROUP(I2C0, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI),
INTC_GROUP(I2C1, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI),
INTC_GROUP(SIM, SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI),
INTC_GROUP(USB, USBI0, USBI1),
};
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
{ VOU, VIO_VEUI, VIO_BEUI, VIO_CEUI, DMAC3, DMAC2, DMAC1, DMAC0 } },
{ 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */
{ 0, 0, 0, VPU, 0, 0, 0, MFI } },
{ 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */
{ SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI, 0, 0, 0, IRDA } },
{ 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */
{ 0, TMU2, TMU1, TMU0, JPU, 0, 0, LCDC } },
{ 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */
{ KEYSC, DMAC_DADERR, DMAC5, DMAC4, SCIF3, SCIF2, SCIF1, SCIF } },
{ 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */
{ 0, 0, 0, SIO, Z3D4, 0, SIOF1, SIOF0 } },
{ 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */
{ I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI,
FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } },
{ 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
{ DISABLED, ENABLED, ENABLED, ENABLED, 0, 0, 0, SIU } },
{ 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
{ 0, 0, 0, CMT, 0, USBI1, USBI0 } },
{ 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
{ MMC_FRDY, MMC_FSTAT, MMC_TRAN, MMC_ERR } },
{ 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */
{ I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI, TPU, 0, 0, TSIF } },
{ 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2 } },
{ 0xa4080004, 0, 16, 4, /* IPRB */ { JPU, LCDC, SIM } },
{ 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, MFI, VPU } },
{ 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } },
{ 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF, SCIF1, SCIF2, SCIF3 } },
{ 0xa408001c, 0, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C0 } },
{ 0xa4080020, 0, 16, 4, /* IPRI */ { SIO, 0, TSIF, I2C1 } },
{ 0xa4080024, 0, 16, 4, /* IPRJ */ { Z3D4, 0, SIU } },
{ 0xa4080028, 0, 16, 4, /* IPRK */ { 0, MMC, 0, SDHI } },
{ 0xa408002c, 0, 16, 4, /* IPRL */ { 0, 0, TPU } },
{ 0xa4140010, 0, 32, 4, /* INTPRI00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_sense_reg sense_registers[] __initdata = {
{ 0xa414001c, 16, 2, /* ICR1 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_mask_reg ack_registers[] __initdata = {
{ 0xa4140024, 0, 8, /* INTREQ00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_desc intc_desc __initdata = {
.name = "sh7343",
.force_enable = ENABLED,
.force_disable = DISABLED,
.hw = INTC_HW_DESC(vectors, groups, mask_registers,
prio_registers, sense_registers, ack_registers),
};
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}

View file

@ -0,0 +1,392 @@
/*
* SH7366 Setup
*
* Copyright (C) 2008 Renesas Solutions
*
* Based on linux/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/uio_driver.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <linux/usb/r8a66597.h>
#include <asm/clock.h>
static struct plat_sci_port scif0_platform_data = {
.port_reg = 0xa405013e,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xffe00000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc00)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct resource iic_resources[] = {
[0] = {
.name = "IIC",
.start = 0x04470000,
.end = 0x04470017,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xe00),
.end = evt2irq(0xe60),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device iic_device = {
.name = "i2c-sh_mobile",
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic_resources),
.resource = iic_resources,
};
static struct r8a66597_platdata r8a66597_data = {
.on_chip = 1,
};
static struct resource usb_host_resources[] = {
[0] = {
.start = 0xa4d80000,
.end = 0xa4d800ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xa20),
.end = evt2irq(0xa20),
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
},
};
static struct platform_device usb_host_device = {
.name = "r8a66597_hcd",
.id = -1,
.dev = {
.dma_mask = NULL,
.coherent_dma_mask = 0xffffffff,
.platform_data = &r8a66597_data,
},
.num_resources = ARRAY_SIZE(usb_host_resources),
.resource = usb_host_resources,
};
static struct uio_info vpu_platform_data = {
.name = "VPU5",
.version = "0",
.irq = evt2irq(0x980),
};
static struct resource vpu_resources[] = {
[0] = {
.name = "VPU",
.start = 0xfe900000,
.end = 0xfe902807,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device vpu_device = {
.name = "uio_pdrv_genirq",
.id = 0,
.dev = {
.platform_data = &vpu_platform_data,
},
.resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources),
};
static struct uio_info veu0_platform_data = {
.name = "VEU",
.version = "0",
.irq = evt2irq(0x8c0),
};
static struct resource veu0_resources[] = {
[0] = {
.name = "VEU(1)",
.start = 0xfe920000,
.end = 0xfe9200b7,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device veu0_device = {
.name = "uio_pdrv_genirq",
.id = 1,
.dev = {
.platform_data = &veu0_platform_data,
},
.resource = veu0_resources,
.num_resources = ARRAY_SIZE(veu0_resources),
};
static struct uio_info veu1_platform_data = {
.name = "VEU",
.version = "0",
.irq = evt2irq(0x560),
};
static struct resource veu1_resources[] = {
[0] = {
.name = "VEU(2)",
.start = 0xfe924000,
.end = 0xfe9240b7,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device veu1_device = {
.name = "uio_pdrv_genirq",
.id = 2,
.dev = {
.platform_data = &veu1_platform_data,
},
.resource = veu1_resources,
.num_resources = ARRAY_SIZE(veu1_resources),
};
static struct sh_timer_config cmt_platform_data = {
.channels_mask = 0x20,
};
static struct resource cmt_resources[] = {
DEFINE_RES_MEM(0x044a0000, 0x70),
DEFINE_RES_IRQ(evt2irq(0xf00)),
};
static struct platform_device cmt_device = {
.name = "sh-cmt-32",
.id = 0,
.dev = {
.platform_data = &cmt_platform_data,
},
.resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources),
};
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffd80000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0x400)),
DEFINE_RES_IRQ(evt2irq(0x420)),
DEFINE_RES_IRQ(evt2irq(0x440)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct platform_device *sh7366_devices[] __initdata = {
&scif0_device,
&cmt_device,
&tmu0_device,
&iic_device,
&usb_host_device,
&vpu_device,
&veu0_device,
&veu1_device,
};
static int __init sh7366_devices_setup(void)
{
platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20);
platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
platform_resource_setup_memory(&veu1_device, "veu1", 2 << 20);
return platform_add_devices(sh7366_devices,
ARRAY_SIZE(sh7366_devices));
}
arch_initcall(sh7366_devices_setup);
static struct platform_device *sh7366_early_devices[] __initdata = {
&scif0_device,
&cmt_device,
&tmu0_device,
};
void __init plat_early_device_setup(void)
{
early_platform_add_devices(sh7366_early_devices,
ARRAY_SIZE(sh7366_early_devices));
}
enum {
UNUSED=0,
ENABLED,
DISABLED,
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
ICB,
DMAC0, DMAC1, DMAC2, DMAC3,
VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU,
MFI, VPU, USB,
MMC_MMC1I, MMC_MMC2I, MMC_MMC3I,
DMAC4, DMAC5, DMAC_DADERR,
SCIF, SCIFA1, SCIFA2,
DENC, MSIOF,
FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI,
SDHI, CMT, TSIF, SIU,
TMU0, TMU1, TMU2,
VEU2, LCDC,
/* interrupt groups */
DMAC0123, VIOVOU, MMC, DMAC45, FLCTL, I2C,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0),
INTC_VECT(ICB, 0x700),
INTC_VECT(DMAC0, 0x800), INTC_VECT(DMAC1, 0x820),
INTC_VECT(DMAC2, 0x840), INTC_VECT(DMAC3, 0x860),
INTC_VECT(VIO_CEUI, 0x880), INTC_VECT(VIO_BEUI, 0x8a0),
INTC_VECT(VIO_VEUI, 0x8c0), INTC_VECT(VOU, 0x8e0),
INTC_VECT(MFI, 0x900), INTC_VECT(VPU, 0x980), INTC_VECT(USB, 0xa20),
INTC_VECT(MMC_MMC1I, 0xb00), INTC_VECT(MMC_MMC2I, 0xb20),
INTC_VECT(MMC_MMC3I, 0xb40),
INTC_VECT(DMAC4, 0xb80), INTC_VECT(DMAC5, 0xba0),
INTC_VECT(DMAC_DADERR, 0xbc0),
INTC_VECT(SCIF, 0xc00), INTC_VECT(SCIFA1, 0xc20),
INTC_VECT(SCIFA2, 0xc40),
INTC_VECT(DENC, 0xc60), INTC_VECT(MSIOF, 0xc80),
INTC_VECT(FLCTL_FLSTEI, 0xd80), INTC_VECT(FLCTL_FLENDI, 0xda0),
INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0),
INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20),
INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60),
INTC_VECT(SDHI, 0xe80), INTC_VECT(SDHI, 0xea0),
INTC_VECT(SDHI, 0xec0), INTC_VECT(SDHI, 0xee0),
INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20),
INTC_VECT(SIU, 0xf80),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
INTC_VECT(TMU2, 0x440),
INTC_VECT(VEU2, 0x560), INTC_VECT(LCDC, 0x580),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3),
INTC_GROUP(VIOVOU, VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU),
INTC_GROUP(MMC, MMC_MMC1I, MMC_MMC2I, MMC_MMC3I),
INTC_GROUP(DMAC45, DMAC4, DMAC5, DMAC_DADERR),
INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI,
FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI),
};
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
{ } },
{ 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
{ VOU, VIO_VEUI, VIO_BEUI, VIO_CEUI, DMAC3, DMAC2, DMAC1, DMAC0 } },
{ 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */
{ 0, 0, 0, VPU, 0, 0, 0, MFI } },
{ 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */
{ 0, 0, 0, ICB } },
{ 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */
{ 0, TMU2, TMU1, TMU0, VEU2, 0, 0, LCDC } },
{ 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */
{ 0, DMAC_DADERR, DMAC5, DMAC4, DENC, SCIFA2, SCIFA1, SCIF } },
{ 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */
{ 0, 0, 0, 0, 0, 0, 0, MSIOF } },
{ 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */
{ I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI,
FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } },
{ 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
{ DISABLED, ENABLED, ENABLED, ENABLED, 0, 0, 0, SIU } },
{ 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
{ 0, 0, 0, CMT, 0, USB, } },
{ 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
{ 0, MMC_MMC3I, MMC_MMC2I, MMC_MMC1I } },
{ 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */
{ 0, 0, 0, 0, 0, 0, 0, TSIF } },
{ 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2 } },
{ 0xa4080004, 0, 16, 4, /* IPRB */ { VEU2, LCDC, ICB } },
{ 0xa4080008, 0, 16, 4, /* IPRC */ { } },
{ 0xa408000c, 0, 16, 4, /* IPRD */ { } },
{ 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, MFI, VPU } },
{ 0xa4080014, 0, 16, 4, /* IPRF */ { 0, DMAC45, USB, CMT } },
{ 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF, SCIFA1, SCIFA2, DENC } },
{ 0xa408001c, 0, 16, 4, /* IPRH */ { MSIOF, 0, FLCTL, I2C } },
{ 0xa4080020, 0, 16, 4, /* IPRI */ { 0, 0, TSIF, } },
{ 0xa4080024, 0, 16, 4, /* IPRJ */ { 0, 0, SIU } },
{ 0xa4080028, 0, 16, 4, /* IPRK */ { 0, MMC, 0, SDHI } },
{ 0xa408002c, 0, 16, 4, /* IPRL */ { } },
{ 0xa4140010, 0, 32, 4, /* INTPRI00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_sense_reg sense_registers[] __initdata = {
{ 0xa414001c, 16, 2, /* ICR1 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_mask_reg ack_registers[] __initdata = {
{ 0xa4140024, 0, 8, /* INTREQ00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_desc intc_desc __initdata = {
.name = "sh7366",
.force_enable = ENABLED,
.force_disable = DISABLED,
.hw = INTC_HW_DESC(vectors, groups, mask_registers,
prio_registers, sense_registers, ack_registers),
};
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
void __init plat_mem_setup(void)
{
/* TODO: Register Node 1 */
}

View file

@ -0,0 +1,671 @@
/*
* SH7722 Setup
*
* Copyright (C) 2006 - 2008 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/sh_dma.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <linux/uio_driver.h>
#include <linux/usb/m66592.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
#include <asm/siu.h>
#include <cpu/dma-register.h>
#include <cpu/sh7722.h>
#include <cpu/serial.h>
static const struct sh_dmae_slave_config sh7722_dmae_slaves[] = {
{
.slave_id = SHDMA_SLAVE_SCIF0_TX,
.addr = 0xffe0000c,
.chcr = DM_FIX | SM_INC | RS_ERS | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x21,
}, {
.slave_id = SHDMA_SLAVE_SCIF0_RX,
.addr = 0xffe00014,
.chcr = DM_INC | SM_FIX | RS_ERS | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x22,
}, {
.slave_id = SHDMA_SLAVE_SCIF1_TX,
.addr = 0xffe1000c,
.chcr = DM_FIX | SM_INC | RS_ERS | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x25,
}, {
.slave_id = SHDMA_SLAVE_SCIF1_RX,
.addr = 0xffe10014,
.chcr = DM_INC | SM_FIX | RS_ERS | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x26,
}, {
.slave_id = SHDMA_SLAVE_SCIF2_TX,
.addr = 0xffe2000c,
.chcr = DM_FIX | SM_INC | RS_ERS | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x29,
}, {
.slave_id = SHDMA_SLAVE_SCIF2_RX,
.addr = 0xffe20014,
.chcr = DM_INC | SM_FIX | RS_ERS | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x2a,
}, {
.slave_id = SHDMA_SLAVE_SIUA_TX,
.addr = 0xa454c098,
.chcr = DM_FIX | SM_INC | RS_ERS | TS_INDEX2VAL(XMIT_SZ_32BIT),
.mid_rid = 0xb1,
}, {
.slave_id = SHDMA_SLAVE_SIUA_RX,
.addr = 0xa454c090,
.chcr = DM_INC | SM_FIX | RS_ERS | TS_INDEX2VAL(XMIT_SZ_32BIT),
.mid_rid = 0xb2,
}, {
.slave_id = SHDMA_SLAVE_SIUB_TX,
.addr = 0xa454c09c,
.chcr = DM_FIX | SM_INC | RS_ERS | TS_INDEX2VAL(XMIT_SZ_32BIT),
.mid_rid = 0xb5,
}, {
.slave_id = SHDMA_SLAVE_SIUB_RX,
.addr = 0xa454c094,
.chcr = DM_INC | SM_FIX | RS_ERS | TS_INDEX2VAL(XMIT_SZ_32BIT),
.mid_rid = 0xb6,
}, {
.slave_id = SHDMA_SLAVE_SDHI0_TX,
.addr = 0x04ce0030,
.chcr = DM_FIX | SM_INC | RS_ERS | TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xc1,
}, {
.slave_id = SHDMA_SLAVE_SDHI0_RX,
.addr = 0x04ce0030,
.chcr = DM_INC | SM_FIX | RS_ERS | TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xc2,
},
};
static const struct sh_dmae_channel sh7722_dmae_channels[] = {
{
.offset = 0,
.dmars = 0,
.dmars_bit = 0,
}, {
.offset = 0x10,
.dmars = 0,
.dmars_bit = 8,
}, {
.offset = 0x20,
.dmars = 4,
.dmars_bit = 0,
}, {
.offset = 0x30,
.dmars = 4,
.dmars_bit = 8,
}, {
.offset = 0x50,
.dmars = 8,
.dmars_bit = 0,
}, {
.offset = 0x60,
.dmars = 8,
.dmars_bit = 8,
}
};
static const unsigned int ts_shift[] = TS_SHIFT;
static struct sh_dmae_pdata dma_platform_data = {
.slave = sh7722_dmae_slaves,
.slave_num = ARRAY_SIZE(sh7722_dmae_slaves),
.channel = sh7722_dmae_channels,
.channel_num = ARRAY_SIZE(sh7722_dmae_channels),
.ts_low_shift = CHCR_TS_LOW_SHIFT,
.ts_low_mask = CHCR_TS_LOW_MASK,
.ts_high_shift = CHCR_TS_HIGH_SHIFT,
.ts_high_mask = CHCR_TS_HIGH_MASK,
.ts_shift = ts_shift,
.ts_shift_num = ARRAY_SIZE(ts_shift),
.dmaor_init = DMAOR_INIT,
};
static struct resource sh7722_dmae_resources[] = {
[0] = {
/* Channel registers and DMAOR */
.start = 0xfe008020,
.end = 0xfe00808f,
.flags = IORESOURCE_MEM,
},
[1] = {
/* DMARSx */
.start = 0xfe009000,
.end = 0xfe00900b,
.flags = IORESOURCE_MEM,
},
{
.name = "error_irq",
.start = evt2irq(0xbc0),
.end = evt2irq(0xbc0),
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channels 0-3 */
.start = evt2irq(0x800),
.end = evt2irq(0x860),
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channels 4-5 */
.start = evt2irq(0xb80),
.end = evt2irq(0xba0),
.flags = IORESOURCE_IRQ,
},
};
struct platform_device dma_device = {
.name = "sh-dma-engine",
.id = -1,
.resource = sh7722_dmae_resources,
.num_resources = ARRAY_SIZE(sh7722_dmae_resources),
.dev = {
.platform_data = &dma_platform_data,
},
};
/* Serial */
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.ops = &sh7722_sci_port_ops,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xffe00000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc00)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.ops = &sh7722_sci_port_ops,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
static struct resource scif1_resources[] = {
DEFINE_RES_MEM(0xffe10000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc20)),
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.resource = scif1_resources,
.num_resources = ARRAY_SIZE(scif1_resources),
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.ops = &sh7722_sci_port_ops,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
static struct resource scif2_resources[] = {
DEFINE_RES_MEM(0xffe20000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc40)),
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.resource = scif2_resources,
.num_resources = ARRAY_SIZE(scif2_resources),
.dev = {
.platform_data = &scif2_platform_data,
},
};
static struct resource rtc_resources[] = {
[0] = {
.start = 0xa465fec0,
.end = 0xa465fec0 + 0x58 - 1,
.flags = IORESOURCE_IO,
},
[1] = {
/* Period IRQ */
.start = evt2irq(0x7a0),
.flags = IORESOURCE_IRQ,
},
[2] = {
/* Carry IRQ */
.start = evt2irq(0x7c0),
.flags = IORESOURCE_IRQ,
},
[3] = {
/* Alarm IRQ */
.start = evt2irq(0x780),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device rtc_device = {
.name = "sh-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
};
static struct m66592_platdata usbf_platdata = {
.on_chip = 1,
};
static struct resource usbf_resources[] = {
[0] = {
.name = "USBF",
.start = 0x04480000,
.end = 0x044800FF,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xa20),
.end = evt2irq(0xa20),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device usbf_device = {
.name = "m66592_udc",
.id = 0, /* "usbf0" clock */
.dev = {
.dma_mask = NULL,
.coherent_dma_mask = 0xffffffff,
.platform_data = &usbf_platdata,
},
.num_resources = ARRAY_SIZE(usbf_resources),
.resource = usbf_resources,
};
static struct resource iic_resources[] = {
[0] = {
.name = "IIC",
.start = 0x04470000,
.end = 0x04470017,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xe00),
.end = evt2irq(0xe60),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device iic_device = {
.name = "i2c-sh_mobile",
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic_resources),
.resource = iic_resources,
};
static struct uio_info vpu_platform_data = {
.name = "VPU4",
.version = "0",
.irq = evt2irq(0x980),
};
static struct resource vpu_resources[] = {
[0] = {
.name = "VPU",
.start = 0xfe900000,
.end = 0xfe9022eb,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device vpu_device = {
.name = "uio_pdrv_genirq",
.id = 0,
.dev = {
.platform_data = &vpu_platform_data,
},
.resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources),
};
static struct uio_info veu_platform_data = {
.name = "VEU",
.version = "0",
.irq = evt2irq(0x8c0),
};
static struct resource veu_resources[] = {
[0] = {
.name = "VEU",
.start = 0xfe920000,
.end = 0xfe9200b7,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device veu_device = {
.name = "uio_pdrv_genirq",
.id = 1,
.dev = {
.platform_data = &veu_platform_data,
},
.resource = veu_resources,
.num_resources = ARRAY_SIZE(veu_resources),
};
static struct uio_info jpu_platform_data = {
.name = "JPU",
.version = "0",
.irq = evt2irq(0x560),
};
static struct resource jpu_resources[] = {
[0] = {
.name = "JPU",
.start = 0xfea00000,
.end = 0xfea102d3,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device jpu_device = {
.name = "uio_pdrv_genirq",
.id = 2,
.dev = {
.platform_data = &jpu_platform_data,
},
.resource = jpu_resources,
.num_resources = ARRAY_SIZE(jpu_resources),
};
static struct sh_timer_config cmt_platform_data = {
.channels_mask = 0x20,
};
static struct resource cmt_resources[] = {
DEFINE_RES_MEM(0x044a0000, 0x70),
DEFINE_RES_IRQ(evt2irq(0xf00)),
};
static struct platform_device cmt_device = {
.name = "sh-cmt-32",
.id = 0,
.dev = {
.platform_data = &cmt_platform_data,
},
.resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources),
};
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffd80000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0x400)),
DEFINE_RES_IRQ(evt2irq(0x420)),
DEFINE_RES_IRQ(evt2irq(0x440)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct siu_platform siu_platform_data = {
.dma_slave_tx_a = SHDMA_SLAVE_SIUA_TX,
.dma_slave_rx_a = SHDMA_SLAVE_SIUA_RX,
.dma_slave_tx_b = SHDMA_SLAVE_SIUB_TX,
.dma_slave_rx_b = SHDMA_SLAVE_SIUB_RX,
};
static struct resource siu_resources[] = {
[0] = {
.start = 0xa4540000,
.end = 0xa454c10f,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xf80),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device siu_device = {
.name = "siu-pcm-audio",
.id = -1,
.dev = {
.platform_data = &siu_platform_data,
},
.resource = siu_resources,
.num_resources = ARRAY_SIZE(siu_resources),
};
static struct platform_device *sh7722_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&cmt_device,
&tmu0_device,
&rtc_device,
&usbf_device,
&iic_device,
&vpu_device,
&veu_device,
&jpu_device,
&siu_device,
&dma_device,
};
static int __init sh7722_devices_setup(void)
{
platform_resource_setup_memory(&vpu_device, "vpu", 1 << 20);
platform_resource_setup_memory(&veu_device, "veu", 2 << 20);
platform_resource_setup_memory(&jpu_device, "jpu", 2 << 20);
return platform_add_devices(sh7722_devices,
ARRAY_SIZE(sh7722_devices));
}
arch_initcall(sh7722_devices_setup);
static struct platform_device *sh7722_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&cmt_device,
&tmu0_device,
};
void __init plat_early_device_setup(void)
{
early_platform_add_devices(sh7722_early_devices,
ARRAY_SIZE(sh7722_early_devices));
}
enum {
UNUSED=0,
ENABLED,
DISABLED,
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
HUDI,
SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI,
RTC_ATI, RTC_PRI, RTC_CUI,
DMAC0, DMAC1, DMAC2, DMAC3,
VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU,
VPU, TPU,
USB_USBI0, USB_USBI1,
DMAC4, DMAC5, DMAC_DADERR,
KEYSC,
SCIF0, SCIF1, SCIF2, SIOF0, SIOF1, SIO,
FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI,
CMT, TSIF, SIU, TWODG,
TMU0, TMU1, TMU2,
IRDA, JPU, LCDC,
/* interrupt groups */
SIM, RTC, DMAC0123, VIOVOU, USB, DMAC45, FLCTL, I2C, SDHI,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0),
INTC_VECT(SIM_ERI, 0x700), INTC_VECT(SIM_RXI, 0x720),
INTC_VECT(SIM_TXI, 0x740), INTC_VECT(SIM_TEI, 0x760),
INTC_VECT(RTC_ATI, 0x780), INTC_VECT(RTC_PRI, 0x7a0),
INTC_VECT(RTC_CUI, 0x7c0),
INTC_VECT(DMAC0, 0x800), INTC_VECT(DMAC1, 0x820),
INTC_VECT(DMAC2, 0x840), INTC_VECT(DMAC3, 0x860),
INTC_VECT(VIO_CEUI, 0x880), INTC_VECT(VIO_BEUI, 0x8a0),
INTC_VECT(VIO_VEUI, 0x8c0), INTC_VECT(VOU, 0x8e0),
INTC_VECT(VPU, 0x980), INTC_VECT(TPU, 0x9a0),
INTC_VECT(USB_USBI0, 0xa20), INTC_VECT(USB_USBI1, 0xa40),
INTC_VECT(DMAC4, 0xb80), INTC_VECT(DMAC5, 0xba0),
INTC_VECT(DMAC_DADERR, 0xbc0), INTC_VECT(KEYSC, 0xbe0),
INTC_VECT(SCIF0, 0xc00), INTC_VECT(SCIF1, 0xc20),
INTC_VECT(SCIF2, 0xc40), INTC_VECT(SIOF0, 0xc80),
INTC_VECT(SIOF1, 0xca0), INTC_VECT(SIO, 0xd00),
INTC_VECT(FLCTL_FLSTEI, 0xd80), INTC_VECT(FLCTL_FLENDI, 0xda0),
INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0),
INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20),
INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60),
INTC_VECT(SDHI, 0xe80), INTC_VECT(SDHI, 0xea0),
INTC_VECT(SDHI, 0xec0), INTC_VECT(SDHI, 0xee0),
INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20),
INTC_VECT(SIU, 0xf80), INTC_VECT(TWODG, 0xfa0),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
INTC_VECT(TMU2, 0x440), INTC_VECT(IRDA, 0x480),
INTC_VECT(JPU, 0x560), INTC_VECT(LCDC, 0x580),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI),
INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3),
INTC_GROUP(VIOVOU, VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU),
INTC_GROUP(USB, USB_USBI0, USB_USBI1),
INTC_GROUP(DMAC45, DMAC4, DMAC5, DMAC_DADERR),
INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI,
FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI),
};
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
{ } },
{ 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
{ VOU, VIO_VEUI, VIO_BEUI, VIO_CEUI, DMAC3, DMAC2, DMAC1, DMAC0 } },
{ 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */
{ 0, 0, 0, VPU, } },
{ 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */
{ SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI, 0, 0, 0, IRDA } },
{ 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */
{ 0, TMU2, TMU1, TMU0, JPU, 0, 0, LCDC } },
{ 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */
{ KEYSC, DMAC_DADERR, DMAC5, DMAC4, 0, SCIF2, SCIF1, SCIF0 } },
{ 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */
{ 0, 0, 0, SIO, 0, 0, SIOF1, SIOF0 } },
{ 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */
{ I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI,
FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } },
{ 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
{ DISABLED, ENABLED, ENABLED, ENABLED, 0, 0, TWODG, SIU } },
{ 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
{ 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } },
{ 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
{ } },
{ 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */
{ 0, RTC_CUI, RTC_PRI, RTC_ATI, 0, TPU, 0, TSIF } },
{ 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } },
{ 0xa4080004, 0, 16, 4, /* IPRB */ { JPU, LCDC, SIM } },
{ 0xa4080008, 0, 16, 4, /* IPRC */ { } },
{ 0xa408000c, 0, 16, 4, /* IPRD */ { } },
{ 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } },
{ 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } },
{ 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } },
{ 0xa408001c, 0, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } },
{ 0xa4080020, 0, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } },
{ 0xa4080024, 0, 16, 4, /* IPRJ */ { 0, 0, SIU } },
{ 0xa4080028, 0, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } },
{ 0xa408002c, 0, 16, 4, /* IPRL */ { TWODG, 0, TPU } },
{ 0xa4140010, 0, 32, 4, /* INTPRI00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_sense_reg sense_registers[] __initdata = {
{ 0xa414001c, 16, 2, /* ICR1 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_mask_reg ack_registers[] __initdata = {
{ 0xa4140024, 0, 8, /* INTREQ00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_desc intc_desc __initdata = {
.name = "sh7722",
.force_enable = ENABLED,
.force_disable = DISABLED,
.hw = INTC_HW_DESC(vectors, groups, mask_registers,
prio_registers, sense_registers, ack_registers),
};
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
void __init plat_mem_setup(void)
{
/* Register the URAM space as Node 1 */
setup_bootmem_node(1, 0x055f0000, 0x05610000);
}

View file

@ -0,0 +1,661 @@
/*
* SH7723 Setup
*
* Copyright (C) 2008 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/mm.h>
#include <linux/serial_sci.h>
#include <linux/uio_driver.h>
#include <linux/usb/r8a66597.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <linux/io.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
#include <cpu/sh7723.h>
/* Serial */
static struct plat_sci_port scif0_platform_data = {
.port_reg = 0xa4050160,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xffe00000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc00)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct plat_sci_port scif1_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
static struct resource scif1_resources[] = {
DEFINE_RES_MEM(0xffe10000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc20)),
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.resource = scif1_resources,
.num_resources = ARRAY_SIZE(scif1_resources),
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct plat_sci_port scif2_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
};
static struct resource scif2_resources[] = {
DEFINE_RES_MEM(0xffe20000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xc40)),
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.resource = scif2_resources,
.num_resources = ARRAY_SIZE(scif2_resources),
.dev = {
.platform_data = &scif2_platform_data,
},
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.port_reg = SCIx_NOT_SUPPORTED,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.sampling_rate = 8,
.type = PORT_SCIFA,
};
static struct resource scif3_resources[] = {
DEFINE_RES_MEM(0xa4e30000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x900)),
};
static struct platform_device scif3_device = {
.name = "sh-sci",
.id = 3,
.resource = scif3_resources,
.num_resources = ARRAY_SIZE(scif3_resources),
.dev = {
.platform_data = &scif3_platform_data,
},
};
static struct plat_sci_port scif4_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.sampling_rate = 8,
.type = PORT_SCIFA,
};
static struct resource scif4_resources[] = {
DEFINE_RES_MEM(0xa4e40000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xd00)),
};
static struct platform_device scif4_device = {
.name = "sh-sci",
.id = 4,
.resource = scif4_resources,
.num_resources = ARRAY_SIZE(scif4_resources),
.dev = {
.platform_data = &scif4_platform_data,
},
};
static struct plat_sci_port scif5_platform_data = {
.port_reg = SCIx_NOT_SUPPORTED,
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.sampling_rate = 8,
.type = PORT_SCIFA,
};
static struct resource scif5_resources[] = {
DEFINE_RES_MEM(0xa4e50000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xfa0)),
};
static struct platform_device scif5_device = {
.name = "sh-sci",
.id = 5,
.resource = scif5_resources,
.num_resources = ARRAY_SIZE(scif5_resources),
.dev = {
.platform_data = &scif5_platform_data,
},
};
static struct uio_info vpu_platform_data = {
.name = "VPU5",
.version = "0",
.irq = evt2irq(0x980),
};
static struct resource vpu_resources[] = {
[0] = {
.name = "VPU",
.start = 0xfe900000,
.end = 0xfe902807,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device vpu_device = {
.name = "uio_pdrv_genirq",
.id = 0,
.dev = {
.platform_data = &vpu_platform_data,
},
.resource = vpu_resources,
.num_resources = ARRAY_SIZE(vpu_resources),
};
static struct uio_info veu0_platform_data = {
.name = "VEU2H",
.version = "0",
.irq = evt2irq(0x8c0),
};
static struct resource veu0_resources[] = {
[0] = {
.name = "VEU2H0",
.start = 0xfe920000,
.end = 0xfe92027b,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device veu0_device = {
.name = "uio_pdrv_genirq",
.id = 1,
.dev = {
.platform_data = &veu0_platform_data,
},
.resource = veu0_resources,
.num_resources = ARRAY_SIZE(veu0_resources),
};
static struct uio_info veu1_platform_data = {
.name = "VEU2H",
.version = "0",
.irq = evt2irq(0x560),
};
static struct resource veu1_resources[] = {
[0] = {
.name = "VEU2H1",
.start = 0xfe924000,
.end = 0xfe92427b,
.flags = IORESOURCE_MEM,
},
[1] = {
/* place holder for contiguous memory */
},
};
static struct platform_device veu1_device = {
.name = "uio_pdrv_genirq",
.id = 2,
.dev = {
.platform_data = &veu1_platform_data,
},
.resource = veu1_resources,
.num_resources = ARRAY_SIZE(veu1_resources),
};
static struct sh_timer_config cmt_platform_data = {
.channels_mask = 0x20,
};
static struct resource cmt_resources[] = {
DEFINE_RES_MEM(0x044a0000, 0x70),
DEFINE_RES_IRQ(evt2irq(0xf00)),
};
static struct platform_device cmt_device = {
.name = "sh-cmt-32",
.id = 0,
.dev = {
.platform_data = &cmt_platform_data,
},
.resource = cmt_resources,
.num_resources = ARRAY_SIZE(cmt_resources),
};
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffd80000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0x400)),
DEFINE_RES_IRQ(evt2irq(0x420)),
DEFINE_RES_IRQ(evt2irq(0x440)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct sh_timer_config tmu1_platform_data = {
.channels_mask = 7,
};
static struct resource tmu1_resources[] = {
DEFINE_RES_MEM(0xffd90000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0x920)),
DEFINE_RES_IRQ(evt2irq(0x940)),
DEFINE_RES_IRQ(evt2irq(0x960)),
};
static struct platform_device tmu1_device = {
.name = "sh-tmu",
.id = 1,
.dev = {
.platform_data = &tmu1_platform_data,
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
};
static struct resource rtc_resources[] = {
[0] = {
.start = 0xa465fec0,
.end = 0xa465fec0 + 0x58 - 1,
.flags = IORESOURCE_IO,
},
[1] = {
/* Period IRQ */
.start = evt2irq(0xaa0),
.flags = IORESOURCE_IRQ,
},
[2] = {
/* Carry IRQ */
.start = evt2irq(0xac0),
.flags = IORESOURCE_IRQ,
},
[3] = {
/* Alarm IRQ */
.start = evt2irq(0xa80),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device rtc_device = {
.name = "sh-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
};
static struct r8a66597_platdata r8a66597_data = {
.on_chip = 1,
};
static struct resource sh7723_usb_host_resources[] = {
[0] = {
.start = 0xa4d80000,
.end = 0xa4d800ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xa20),
.end = evt2irq(0xa20),
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
},
};
static struct platform_device sh7723_usb_host_device = {
.name = "r8a66597_hcd",
.id = 0,
.dev = {
.dma_mask = NULL, /* not use dma */
.coherent_dma_mask = 0xffffffff,
.platform_data = &r8a66597_data,
},
.num_resources = ARRAY_SIZE(sh7723_usb_host_resources),
.resource = sh7723_usb_host_resources,
};
static struct resource iic_resources[] = {
[0] = {
.name = "IIC",
.start = 0x04470000,
.end = 0x04470017,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xe00),
.end = evt2irq(0xe60),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device iic_device = {
.name = "i2c-sh_mobile",
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic_resources),
.resource = iic_resources,
};
static struct platform_device *sh7723_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&cmt_device,
&tmu0_device,
&tmu1_device,
&rtc_device,
&iic_device,
&sh7723_usb_host_device,
&vpu_device,
&veu0_device,
&veu1_device,
};
static int __init sh7723_devices_setup(void)
{
platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20);
platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20);
platform_resource_setup_memory(&veu1_device, "veu1", 2 << 20);
return platform_add_devices(sh7723_devices,
ARRAY_SIZE(sh7723_devices));
}
arch_initcall(sh7723_devices_setup);
static struct platform_device *sh7723_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&cmt_device,
&tmu0_device,
&tmu1_device,
};
void __init plat_early_device_setup(void)
{
early_platform_add_devices(sh7723_early_devices,
ARRAY_SIZE(sh7723_early_devices));
}
#define RAMCR_CACHE_L2FC 0x0002
#define RAMCR_CACHE_L2E 0x0001
#define L2_CACHE_ENABLE (RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC)
void l2_cache_init(void)
{
/* Enable L2 cache */
__raw_writel(L2_CACHE_ENABLE, RAMCR);
}
enum {
UNUSED=0,
ENABLED,
DISABLED,
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
HUDI,
DMAC1A_DEI0,DMAC1A_DEI1,DMAC1A_DEI2,DMAC1A_DEI3,
_2DG_TRI,_2DG_INI,_2DG_CEI,
DMAC0A_DEI0,DMAC0A_DEI1,DMAC0A_DEI2,DMAC0A_DEI3,
VIO_CEUI,VIO_BEUI,VIO_VEU2HI,VIO_VOUI,
SCIFA_SCIFA0,
VPU_VPUI,
TPU_TPUI,
ADC_ADI,
USB_USI0,
RTC_ATI,RTC_PRI,RTC_CUI,
DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR,
DMAC0B_DEI4,DMAC0B_DEI5,DMAC0B_DADERR,
KEYSC_KEYI,
SCIF_SCIF0,SCIF_SCIF1,SCIF_SCIF2,
MSIOF_MSIOFI0,MSIOF_MSIOFI1,
SCIFA_SCIFA1,
FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I,
I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI,
CMT_CMTI,
TSIF_TSIFI,
SIU_SIUI,
SCIFA_SCIFA2,
TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2,
IRDA_IRDAI,
ATAPI_ATAPII,
VEU2H1_VEU2HI,
LCDC_LCDCI,
TMU1_TUNI0,TMU1_TUNI1,TMU1_TUNI2,
/* interrupt groups */
DMAC1A, DMAC0A, VIO, DMAC0B, FLCTL, I2C, _2DG,
SDHI1, RTC, DMAC1B, SDHI0,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0),
INTC_VECT(DMAC1A_DEI0,0x700),
INTC_VECT(DMAC1A_DEI1,0x720),
INTC_VECT(DMAC1A_DEI2,0x740),
INTC_VECT(DMAC1A_DEI3,0x760),
INTC_VECT(_2DG_TRI, 0x780),
INTC_VECT(_2DG_INI, 0x7A0),
INTC_VECT(_2DG_CEI, 0x7C0),
INTC_VECT(DMAC0A_DEI0,0x800),
INTC_VECT(DMAC0A_DEI1,0x820),
INTC_VECT(DMAC0A_DEI2,0x840),
INTC_VECT(DMAC0A_DEI3,0x860),
INTC_VECT(VIO_CEUI,0x880),
INTC_VECT(VIO_BEUI,0x8A0),
INTC_VECT(VIO_VEU2HI,0x8C0),
INTC_VECT(VIO_VOUI,0x8E0),
INTC_VECT(SCIFA_SCIFA0,0x900),
INTC_VECT(VPU_VPUI,0x980),
INTC_VECT(TPU_TPUI,0x9A0),
INTC_VECT(ADC_ADI,0x9E0),
INTC_VECT(USB_USI0,0xA20),
INTC_VECT(RTC_ATI,0xA80),
INTC_VECT(RTC_PRI,0xAA0),
INTC_VECT(RTC_CUI,0xAC0),
INTC_VECT(DMAC1B_DEI4,0xB00),
INTC_VECT(DMAC1B_DEI5,0xB20),
INTC_VECT(DMAC1B_DADERR,0xB40),
INTC_VECT(DMAC0B_DEI4,0xB80),
INTC_VECT(DMAC0B_DEI5,0xBA0),
INTC_VECT(DMAC0B_DADERR,0xBC0),
INTC_VECT(KEYSC_KEYI,0xBE0),
INTC_VECT(SCIF_SCIF0,0xC00),
INTC_VECT(SCIF_SCIF1,0xC20),
INTC_VECT(SCIF_SCIF2,0xC40),
INTC_VECT(MSIOF_MSIOFI0,0xC80),
INTC_VECT(MSIOF_MSIOFI1,0xCA0),
INTC_VECT(SCIFA_SCIFA1,0xD00),
INTC_VECT(FLCTL_FLSTEI,0xD80),
INTC_VECT(FLCTL_FLTENDI,0xDA0),
INTC_VECT(FLCTL_FLTREQ0I,0xDC0),
INTC_VECT(FLCTL_FLTREQ1I,0xDE0),
INTC_VECT(I2C_ALI,0xE00),
INTC_VECT(I2C_TACKI,0xE20),
INTC_VECT(I2C_WAITI,0xE40),
INTC_VECT(I2C_DTEI,0xE60),
INTC_VECT(SDHI0, 0xE80),
INTC_VECT(SDHI0, 0xEA0),
INTC_VECT(SDHI0, 0xEC0),
INTC_VECT(CMT_CMTI,0xF00),
INTC_VECT(TSIF_TSIFI,0xF20),
INTC_VECT(SIU_SIUI,0xF80),
INTC_VECT(SCIFA_SCIFA2,0xFA0),
INTC_VECT(TMU0_TUNI0,0x400),
INTC_VECT(TMU0_TUNI1,0x420),
INTC_VECT(TMU0_TUNI2,0x440),
INTC_VECT(IRDA_IRDAI,0x480),
INTC_VECT(ATAPI_ATAPII,0x4A0),
INTC_VECT(SDHI1, 0x4E0),
INTC_VECT(SDHI1, 0x500),
INTC_VECT(SDHI1, 0x520),
INTC_VECT(VEU2H1_VEU2HI,0x560),
INTC_VECT(LCDC_LCDCI,0x580),
INTC_VECT(TMU1_TUNI0,0x920),
INTC_VECT(TMU1_TUNI1,0x940),
INTC_VECT(TMU1_TUNI2,0x960),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(DMAC1A,DMAC1A_DEI0,DMAC1A_DEI1,DMAC1A_DEI2,DMAC1A_DEI3),
INTC_GROUP(DMAC0A,DMAC0A_DEI0,DMAC0A_DEI1,DMAC0A_DEI2,DMAC0A_DEI3),
INTC_GROUP(VIO, VIO_CEUI,VIO_BEUI,VIO_VEU2HI,VIO_VOUI),
INTC_GROUP(DMAC0B, DMAC0B_DEI4,DMAC0B_DEI5,DMAC0B_DADERR),
INTC_GROUP(FLCTL,FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I),
INTC_GROUP(I2C,I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI),
INTC_GROUP(_2DG, _2DG_TRI,_2DG_INI,_2DG_CEI),
INTC_GROUP(RTC, RTC_ATI,RTC_PRI,RTC_CUI),
INTC_GROUP(DMAC1B, DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR),
};
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
{ 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
0, ENABLED, ENABLED, ENABLED } },
{ 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
{ VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } },
{ 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */
{ 0, 0, 0, VPU_VPUI,0,0,0,SCIFA_SCIFA0 } },
{ 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */
{ DMAC1A_DEI3,DMAC1A_DEI2,DMAC1A_DEI1,DMAC1A_DEI0,0,0,0,IRDA_IRDAI } },
{ 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */
{ 0,TMU0_TUNI2,TMU0_TUNI1,TMU0_TUNI0,VEU2H1_VEU2HI,0,0,LCDC_LCDCI } },
{ 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */
{ KEYSC_KEYI,DMAC0B_DADERR,DMAC0B_DEI5,DMAC0B_DEI4,0,SCIF_SCIF2,SCIF_SCIF1,SCIF_SCIF0 } },
{ 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */
{ 0,0,0,SCIFA_SCIFA1,ADC_ADI,0,MSIOF_MSIOFI1,MSIOF_MSIOFI0 } },
{ 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */
{ I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI,
FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
{ 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */
{ 0, ENABLED, ENABLED, ENABLED,
0, 0, SCIFA_SCIFA2, SIU_SIUI } },
{ 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */
{ 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } },
{ 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */
{ 0, DMAC1B_DADERR,DMAC1B_DEI5,DMAC1B_DEI4,0,RTC_ATI,RTC_PRI,RTC_CUI } },
{ 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */
{ 0,_2DG_CEI,_2DG_INI,_2DG_TRI,0,TPU_TPUI,0,TSIF_TSIFI } },
{ 0xa40800b0, 0xa40800f0, 8, /* IMR12 / IMCR12 */
{ 0,0,0,0,0,0,0,ATAPI_ATAPII } },
{ 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2, IRDA_IRDAI } },
{ 0xa4080004, 0, 16, 4, /* IPRB */ { VEU2H1_VEU2HI, LCDC_LCDCI, DMAC1A, 0} },
{ 0xa4080008, 0, 16, 4, /* IPRC */ { TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2, 0} },
{ 0xa408000c, 0, 16, 4, /* IPRD */ { } },
{ 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0A, VIO, SCIFA_SCIFA0, VPU_VPUI } },
{ 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC_KEYI, DMAC0B, USB_USI0, CMT_CMTI } },
{ 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF_SCIF0, SCIF_SCIF1, SCIF_SCIF2,0 } },
{ 0xa408001c, 0, 16, 4, /* IPRH */ { MSIOF_MSIOFI0,MSIOF_MSIOFI1, FLCTL, I2C } },
{ 0xa4080020, 0, 16, 4, /* IPRI */ { SCIFA_SCIFA1,0,TSIF_TSIFI,_2DG } },
{ 0xa4080024, 0, 16, 4, /* IPRJ */ { ADC_ADI,0,SIU_SIUI,SDHI1 } },
{ 0xa4080028, 0, 16, 4, /* IPRK */ { RTC,DMAC1B,0,SDHI0 } },
{ 0xa408002c, 0, 16, 4, /* IPRL */ { SCIFA_SCIFA2,0,TPU_TPUI,ATAPI_ATAPII } },
{ 0xa4140010, 0, 32, 4, /* INTPRI00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_sense_reg sense_registers[] __initdata = {
{ 0xa414001c, 16, 2, /* ICR1 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_mask_reg ack_registers[] __initdata = {
{ 0xa4140024, 0, 8, /* INTREQ00 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_desc intc_desc __initdata = {
.name = "sh7723",
.force_enable = ENABLED,
.force_disable = DISABLED,
.hw = INTC_HW_DESC(vectors, groups, mask_registers,
prio_registers, sense_registers, ack_registers),
};
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,629 @@
/*
* arch/sh/kernel/cpu/sh4a/setup-sh7734.c
* SH7734 Setup
*
* Copyright (C) 2011,2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
* Copyright (C) 2011,2012 Renesas Solutions Corp.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/serial_sci.h>
#include <linux/sh_timer.h>
#include <linux/io.h>
#include <asm/clock.h>
#include <asm/irq.h>
#include <cpu/sh7734.h>
/* SCIF */
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_REGTYPE,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xffe40000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x8c0)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_REGTYPE,
};
static struct resource scif1_resources[] = {
DEFINE_RES_MEM(0xffe41000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x8e0)),
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.resource = scif1_resources,
.num_resources = ARRAY_SIZE(scif1_resources),
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_REGTYPE,
};
static struct resource scif2_resources[] = {
DEFINE_RES_MEM(0xffe42000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x900)),
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.resource = scif2_resources,
.num_resources = ARRAY_SIZE(scif2_resources),
.dev = {
.platform_data = &scif2_platform_data,
},
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_REGTYPE,
};
static struct resource scif3_resources[] = {
DEFINE_RES_MEM(0xffe43000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x920)),
};
static struct platform_device scif3_device = {
.name = "sh-sci",
.id = 3,
.resource = scif3_resources,
.num_resources = ARRAY_SIZE(scif3_resources),
.dev = {
.platform_data = &scif3_platform_data,
},
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_REGTYPE,
};
static struct resource scif4_resources[] = {
DEFINE_RES_MEM(0xffe44000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x940)),
};
static struct platform_device scif4_device = {
.name = "sh-sci",
.id = 4,
.resource = scif4_resources,
.num_resources = ARRAY_SIZE(scif4_resources),
.dev = {
.platform_data = &scif4_platform_data,
},
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_REGTYPE,
};
static struct resource scif5_resources[] = {
DEFINE_RES_MEM(0xffe43000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x960)),
};
static struct platform_device scif5_device = {
.name = "sh-sci",
.id = 5,
.resource = scif5_resources,
.num_resources = ARRAY_SIZE(scif5_resources),
.dev = {
.platform_data = &scif5_platform_data,
},
};
/* RTC */
static struct resource rtc_resources[] = {
[0] = {
.name = "rtc",
.start = 0xFFFC5000,
.end = 0xFFFC5000 + 0x26 - 1,
.flags = IORESOURCE_IO,
},
[1] = {
.start = evt2irq(0xC00),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device rtc_device = {
.name = "sh-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
};
/* I2C 0 */
static struct resource i2c0_resources[] = {
[0] = {
.name = "IIC0",
.start = 0xFFC70000,
.end = 0xFFC7000A - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0x860),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device i2c0_device = {
.name = "i2c-sh7734",
.id = 0,
.num_resources = ARRAY_SIZE(i2c0_resources),
.resource = i2c0_resources,
};
/* TMU */
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffd80000, 0x30),
DEFINE_RES_IRQ(evt2irq(0x400)),
DEFINE_RES_IRQ(evt2irq(0x420)),
DEFINE_RES_IRQ(evt2irq(0x440)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct sh_timer_config tmu1_platform_data = {
.channels_mask = 7,
};
static struct resource tmu1_resources[] = {
DEFINE_RES_MEM(0xffd81000, 0x30),
DEFINE_RES_IRQ(evt2irq(0x480)),
DEFINE_RES_IRQ(evt2irq(0x4a0)),
DEFINE_RES_IRQ(evt2irq(0x4c0)),
};
static struct platform_device tmu1_device = {
.name = "sh-tmu",
.id = 1,
.dev = {
.platform_data = &tmu1_platform_data,
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
};
static struct sh_timer_config tmu2_platform_data = {
.channels_mask = 7,
};
static struct resource tmu2_resources[] = {
DEFINE_RES_MEM(0xffd82000, 0x30),
DEFINE_RES_IRQ(evt2irq(0x500)),
DEFINE_RES_IRQ(evt2irq(0x520)),
DEFINE_RES_IRQ(evt2irq(0x540)),
};
static struct platform_device tmu2_device = {
.name = "sh-tmu",
.id = 2,
.dev = {
.platform_data = &tmu2_platform_data,
},
.resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources),
};
static struct platform_device *sh7734_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&tmu0_device,
&tmu1_device,
&tmu2_device,
&rtc_device,
};
static struct platform_device *sh7734_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&tmu0_device,
&tmu1_device,
&tmu2_device,
};
void __init plat_early_device_setup(void)
{
early_platform_add_devices(sh7734_early_devices,
ARRAY_SIZE(sh7734_early_devices));
}
#define GROUP 0
enum {
UNUSED = 0,
/* interrupt sources */
IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
IRL0_HHLL, IRL0_HHLH, IRL0_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3,
DU,
TMU00, TMU10, TMU20, TMU21,
TMU30, TMU40, TMU50, TMU51,
TMU60, TMU70, TMU80,
RESET_WDT,
USB,
HUDI,
SHDMAC,
SSI0, SSI1, SSI2, SSI3,
VIN0,
RGPVG,
_2DG,
MMC,
HSPI,
LBSCATA,
I2C0,
RCAN0,
MIMLB,
SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5,
LBSCDMAC0, LBSCDMAC1, LBSCDMAC2,
RCAN1,
SDHI0, SDHI1,
IEBUS,
HPBDMAC0_3, HPBDMAC4_10, HPBDMAC11_18, HPBDMAC19_22, HPBDMAC23_25_27_28,
RTC,
VIN1,
LCDC,
SRC0, SRC1,
GETHER,
SDHI2,
GPIO0_3, GPIO4_5,
STIF0, STIF1,
ADMAC,
HIF,
FLCTL,
ADC,
MTU2,
RSPI,
QSPI,
HSCIF,
VEU3F_VE3,
/* Group */
/* Mask */
STIF_M,
GPIO_M,
HPBDMAC_M,
LBSCDMAC_M,
RCAN_M,
SRC_M,
SCIF_M,
LCDC_M,
_2DG_M,
VIN_M,
TMU_3_M,
TMU_0_M,
/* Priority */
RCAN_P,
LBSCDMAC_P,
/* Common */
SDHI,
SSI,
SPI,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(DU, 0x3E0),
INTC_VECT(TMU00, 0x400),
INTC_VECT(TMU10, 0x420),
INTC_VECT(TMU20, 0x440),
INTC_VECT(TMU30, 0x480),
INTC_VECT(TMU40, 0x4A0),
INTC_VECT(TMU50, 0x4C0),
INTC_VECT(TMU51, 0x4E0),
INTC_VECT(TMU60, 0x500),
INTC_VECT(TMU70, 0x520),
INTC_VECT(TMU80, 0x540),
INTC_VECT(RESET_WDT, 0x560),
INTC_VECT(USB, 0x580),
INTC_VECT(HUDI, 0x600),
INTC_VECT(SHDMAC, 0x620),
INTC_VECT(SSI0, 0x6C0),
INTC_VECT(SSI1, 0x6E0),
INTC_VECT(SSI2, 0x700),
INTC_VECT(SSI3, 0x720),
INTC_VECT(VIN0, 0x740),
INTC_VECT(RGPVG, 0x760),
INTC_VECT(_2DG, 0x780),
INTC_VECT(MMC, 0x7A0),
INTC_VECT(HSPI, 0x7E0),
INTC_VECT(LBSCATA, 0x840),
INTC_VECT(I2C0, 0x860),
INTC_VECT(RCAN0, 0x880),
INTC_VECT(SCIF0, 0x8A0),
INTC_VECT(SCIF1, 0x8C0),
INTC_VECT(SCIF2, 0x900),
INTC_VECT(SCIF3, 0x920),
INTC_VECT(SCIF4, 0x940),
INTC_VECT(SCIF5, 0x960),
INTC_VECT(LBSCDMAC0, 0x9E0),
INTC_VECT(LBSCDMAC1, 0xA00),
INTC_VECT(LBSCDMAC2, 0xA20),
INTC_VECT(RCAN1, 0xA60),
INTC_VECT(SDHI0, 0xAE0),
INTC_VECT(SDHI1, 0xB00),
INTC_VECT(IEBUS, 0xB20),
INTC_VECT(HPBDMAC0_3, 0xB60),
INTC_VECT(HPBDMAC4_10, 0xB80),
INTC_VECT(HPBDMAC11_18, 0xBA0),
INTC_VECT(HPBDMAC19_22, 0xBC0),
INTC_VECT(HPBDMAC23_25_27_28, 0xBE0),
INTC_VECT(RTC, 0xC00),
INTC_VECT(VIN1, 0xC20),
INTC_VECT(LCDC, 0xC40),
INTC_VECT(SRC0, 0xC60),
INTC_VECT(SRC1, 0xC80),
INTC_VECT(GETHER, 0xCA0),
INTC_VECT(SDHI2, 0xCC0),
INTC_VECT(GPIO0_3, 0xCE0),
INTC_VECT(GPIO4_5, 0xD00),
INTC_VECT(STIF0, 0xD20),
INTC_VECT(STIF1, 0xD40),
INTC_VECT(ADMAC, 0xDA0),
INTC_VECT(HIF, 0xDC0),
INTC_VECT(FLCTL, 0xDE0),
INTC_VECT(ADC, 0xE00),
INTC_VECT(MTU2, 0xE20),
INTC_VECT(RSPI, 0xE40),
INTC_VECT(QSPI, 0xE60),
INTC_VECT(HSCIF, 0xFC0),
INTC_VECT(VEU3F_VE3, 0xF40),
};
static struct intc_group groups[] __initdata = {
/* Common */
INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2),
INTC_GROUP(SPI, HSPI, RSPI, QSPI),
INTC_GROUP(SSI, SSI0, SSI1, SSI2, SSI3),
/* Mask group */
INTC_GROUP(STIF_M, STIF0, STIF1), /* 22 */
INTC_GROUP(GPIO_M, GPIO0_3, GPIO4_5), /* 21 */
INTC_GROUP(HPBDMAC_M, HPBDMAC0_3, HPBDMAC4_10, HPBDMAC11_18,
HPBDMAC19_22, HPBDMAC23_25_27_28), /* 19 */
INTC_GROUP(LBSCDMAC_M, LBSCDMAC0, LBSCDMAC1, LBSCDMAC2), /* 18 */
INTC_GROUP(RCAN_M, RCAN0, RCAN1, IEBUS), /* 17 */
INTC_GROUP(SRC_M, SRC0, SRC1), /* 16 */
INTC_GROUP(SCIF_M, SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5,
HSCIF), /* 14 */
INTC_GROUP(LCDC_M, LCDC, MIMLB), /* 13 */
INTC_GROUP(_2DG_M, _2DG, RGPVG), /* 12 */
INTC_GROUP(VIN_M, VIN0, VIN1), /* 10 */
INTC_GROUP(TMU_3_M, TMU30, TMU40, TMU50, TMU51,
TMU60, TMU60, TMU70, TMU80), /* 2 */
INTC_GROUP(TMU_0_M, TMU00, TMU10, TMU20, TMU21), /* 1 */
/* Priority group*/
INTC_GROUP(RCAN_P, RCAN0, RCAN1), /* INT2PRI5 */
INTC_GROUP(LBSCDMAC_P, LBSCDMAC0, LBSCDMAC1), /* INT2PRI5 */
};
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xFF804040, 0xFF804044, 32, /* INT2MSKRG / INT2MSKCR */
{ 0,
VEU3F_VE3,
SDHI, /* SDHI 0-2 */
ADMAC,
FLCTL,
RESET_WDT,
HIF,
ADC,
MTU2,
STIF_M, /* STIF 0,1 */
GPIO_M, /* GPIO 0-5*/
GETHER,
HPBDMAC_M, /* HPBDMAC 0_3 - 23_25_27_28 */
LBSCDMAC_M, /* LBSCDMAC 0 - 2 */
RCAN_M, /* RCAN, IEBUS */
SRC_M, /* SRC 0,1 */
LBSCATA,
SCIF_M, /* SCIF 0-5, HSCIF */
LCDC_M, /* LCDC, MIMLB */
_2DG_M, /* 2DG, RGPVG */
SPI, /* HSPI, RSPI, QSPI */
VIN_M, /* VIN0, 1 */
SSI, /* SSI 0-3 */
USB,
SHDMAC,
HUDI,
MMC,
RTC,
I2C0, /* I2C */ /* I2C 0, 1*/
TMU_3_M, /* TMU30 - TMU80 */
TMU_0_M, /* TMU00 - TMU21 */
DU } },
};
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xFF804000, 0, 32, 8, /* INT2PRI0 */
{ DU, TMU00, TMU10, TMU20 } },
{ 0xFF804004, 0, 32, 8, /* INT2PRI1 */
{ TMU30, TMU60, RTC, SDHI } },
{ 0xFF804008, 0, 32, 8, /* INT2PRI2 */
{ HUDI, SHDMAC, USB, SSI } },
{ 0xFF80400C, 0, 32, 8, /* INT2PRI3 */
{ VIN0, SPI, _2DG, LBSCATA } },
{ 0xFF804010, 0, 32, 8, /* INT2PRI4 */
{ SCIF0, SCIF3, HSCIF, LCDC } },
{ 0xFF804014, 0, 32, 8, /* INT2PRI5 */
{ RCAN_P, LBSCDMAC_P, LBSCDMAC2, MMC } },
{ 0xFF804018, 0, 32, 8, /* INT2PRI6 */
{ HPBDMAC0_3, HPBDMAC4_10, HPBDMAC11_18, HPBDMAC19_22 } },
{ 0xFF80401C, 0, 32, 8, /* INT2PRI7 */
{ HPBDMAC23_25_27_28, I2C0, SRC0, SRC1 } },
{ 0xFF804020, 0, 32, 8, /* INT2PRI8 */
{ 0 /* ADIF */, VIN1, RESET_WDT, HIF } },
{ 0xFF804024, 0, 32, 8, /* INT2PRI9 */
{ ADMAC, FLCTL, GPIO0_3, GPIO4_5 } },
{ 0xFF804028, 0, 32, 8, /* INT2PRI10 */
{ STIF0, STIF1, VEU3F_VE3, GETHER } },
{ 0xFF80402C, 0, 32, 8, /* INT2PRI11 */
{ MTU2, RGPVG, MIMLB, IEBUS } },
};
static DECLARE_INTC_DESC(intc_desc, "sh7734", vectors, groups,
mask_registers, prio_registers, NULL);
/* Support for external interrupt pins in IRQ mode */
static struct intc_vect irq3210_vectors[] __initdata = {
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
INTC_VECT(IRQ2, 0x2C0), INTC_VECT(IRQ3, 0x300),
};
static struct intc_sense_reg irq3210_sense_registers[] __initdata = {
{ 0xFF80201C, 32, 2, /* ICR1 */
{ IRQ0, IRQ1, IRQ2, IRQ3, } },
};
static struct intc_mask_reg irq3210_ack_registers[] __initdata = {
{ 0xFF802024, 0, 32, /* INTREQ */
{ IRQ0, IRQ1, IRQ2, IRQ3, } },
};
static struct intc_mask_reg irq3210_mask_registers[] __initdata = {
{ 0xFF802044, 0xFF802064, 32, /* INTMSK0 / INTMSKCLR0 */
{ IRQ0, IRQ1, IRQ2, IRQ3, } },
};
static struct intc_prio_reg irq3210_prio_registers[] __initdata = {
{ 0xFF802010, 0, 32, 4, /* INTPRI */
{ IRQ0, IRQ1, IRQ2, IRQ3, } },
};
static DECLARE_INTC_DESC_ACK(intc_desc_irq3210, "sh7734-irq3210",
irq3210_vectors, NULL,
irq3210_mask_registers, irq3210_prio_registers,
irq3210_sense_registers, irq3210_ack_registers);
/* External interrupt pins in IRL mode */
static struct intc_vect vectors_irl3210[] __initdata = {
INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220),
INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260),
INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0),
INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0),
INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320),
INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360),
INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0),
INTC_VECT(IRL0_HHHL, 0x3c0),
};
static DECLARE_INTC_DESC(intc_desc_irl3210, "sh7734-irl3210",
vectors_irl3210, NULL, mask_registers, NULL, NULL);
#define INTC_ICR0 0xFF802000
#define INTC_INTMSK0 0xFF802044
#define INTC_INTMSK1 0xFF802048
#define INTC_INTMSKCLR0 0xFF802064
#define INTC_INTMSKCLR1 0xFF802068
void __init plat_irq_setup(void)
{
/* disable IRQ3-0 */
__raw_writel(0xF0000000, INTC_INTMSK0);
/* disable IRL3-0 */
__raw_writel(0x80000000, INTC_INTMSK1);
/* select IRL mode for IRL3-0 */
__raw_writel(__raw_readl(INTC_ICR0) & ~0x00800000, INTC_ICR0);
/* disable holding function, ie enable "SH-4 Mode (LVLMODE)" */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
register_intc_controller(&intc_desc);
}
void __init plat_irq_setup_pins(int mode)
{
switch (mode) {
case IRQ_MODE_IRQ3210:
/* select IRQ mode for IRL3-0 */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0);
register_intc_controller(&intc_desc_irq3210);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
__raw_writel(0xf0000000, INTC_INTMSKCLR0);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
__raw_writel(0x80000000, INTC_INTMSKCLR0);
register_intc_controller(&intc_desc_irl3210);
break;
default:
BUG();
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,460 @@
/*
* SH7763 Setup
*
* Copyright (C) 2006 Paul Mundt
* Copyright (C) 2007 Yoshihiro Shimoda
* Copyright (C) 2008, 2009 Nobuhiro Iwamatsu
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <linux/io.h>
#include <linux/serial_sci.h>
#include <linux/usb/ohci_pdriver.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xffe00000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x700)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif1_resources[] = {
DEFINE_RES_MEM(0xffe08000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xb80)),
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.resource = scif1_resources,
.num_resources = ARRAY_SIZE(scif1_resources),
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif2_resources[] = {
DEFINE_RES_MEM(0xffe10000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xf00)),
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.resource = scif2_resources,
.num_resources = ARRAY_SIZE(scif2_resources),
.dev = {
.platform_data = &scif2_platform_data,
},
};
static struct resource rtc_resources[] = {
[0] = {
.start = 0xffe80000,
.end = 0xffe80000 + 0x58 - 1,
.flags = IORESOURCE_IO,
},
[1] = {
/* Shared Period/Carry/Alarm IRQ */
.start = evt2irq(0x480),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device rtc_device = {
.name = "sh-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
};
static struct resource usb_ohci_resources[] = {
[0] = {
.start = 0xffec8000,
.end = 0xffec80ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xc60),
.end = evt2irq(0xc60),
.flags = IORESOURCE_IRQ,
},
};
static u64 usb_ohci_dma_mask = 0xffffffffUL;
static struct usb_ohci_pdata usb_ohci_pdata;
static struct platform_device usb_ohci_device = {
.name = "ohci-platform",
.id = -1,
.dev = {
.dma_mask = &usb_ohci_dma_mask,
.coherent_dma_mask = 0xffffffff,
.platform_data = &usb_ohci_pdata,
},
.num_resources = ARRAY_SIZE(usb_ohci_resources),
.resource = usb_ohci_resources,
};
static struct resource usbf_resources[] = {
[0] = {
.start = 0xffec0000,
.end = 0xffec00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xc80),
.end = evt2irq(0xc80),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device usbf_device = {
.name = "sh_udc",
.id = -1,
.dev = {
.dma_mask = NULL,
.coherent_dma_mask = 0xffffffff,
},
.num_resources = ARRAY_SIZE(usbf_resources),
.resource = usbf_resources,
};
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffd80000, 0x30),
DEFINE_RES_IRQ(evt2irq(0x580)),
DEFINE_RES_IRQ(evt2irq(0x5a0)),
DEFINE_RES_IRQ(evt2irq(0x5c0)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct sh_timer_config tmu1_platform_data = {
.channels_mask = 7,
};
static struct resource tmu1_resources[] = {
DEFINE_RES_MEM(0xffd88000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0xe00)),
DEFINE_RES_IRQ(evt2irq(0xe20)),
DEFINE_RES_IRQ(evt2irq(0xe40)),
};
static struct platform_device tmu1_device = {
.name = "sh-tmu",
.id = 1,
.dev = {
.platform_data = &tmu1_platform_data,
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
};
static struct platform_device *sh7763_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&tmu0_device,
&tmu1_device,
&rtc_device,
&usb_ohci_device,
&usbf_device,
};
static int __init sh7763_devices_setup(void)
{
return platform_add_devices(sh7763_devices,
ARRAY_SIZE(sh7763_devices));
}
arch_initcall(sh7763_devices_setup);
static struct platform_device *sh7763_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&tmu0_device,
&tmu1_device,
};
void __init plat_early_device_setup(void)
{
early_platform_add_devices(sh7763_early_devices,
ARRAY_SIZE(sh7763_early_devices));
}
enum {
UNUSED = 0,
/* interrupt sources */
IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
HUDI, LCDC, DMAC, SCIF0, IIC0, IIC1, CMT, GETHER, HAC,
PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
STIF0, STIF1, SCIF1, SIOF0, SIOF1, SIOF2,
USBH, USBF, TPU, PCC, MMCIF, SIM,
TMU3, TMU4, TMU5, ADC, SSI0, SSI1, SSI2, SSI3,
SCIF2, GPIO,
/* interrupt groups */
TMU012, TMU345,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
INTC_VECT(RTC, 0x4c0),
INTC_VECT(WDT, 0x560), INTC_VECT(TMU0, 0x580),
INTC_VECT(TMU1, 0x5a0), INTC_VECT(TMU2, 0x5c0),
INTC_VECT(TMU2_TICPI, 0x5e0), INTC_VECT(HUDI, 0x600),
INTC_VECT(LCDC, 0x620),
INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
INTC_VECT(DMAC, 0x6c0),
INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
INTC_VECT(DMAC, 0x780), INTC_VECT(DMAC, 0x7a0),
INTC_VECT(IIC0, 0x8A0), INTC_VECT(IIC1, 0x8C0),
INTC_VECT(CMT, 0x900), INTC_VECT(GETHER, 0x920),
INTC_VECT(GETHER, 0x940), INTC_VECT(GETHER, 0x960),
INTC_VECT(HAC, 0x980),
INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
INTC_VECT(STIF0, 0xb40), INTC_VECT(STIF1, 0xb60),
INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),
INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),
INTC_VECT(SIOF0, 0xc00), INTC_VECT(SIOF1, 0xc20),
INTC_VECT(USBH, 0xc60), INTC_VECT(USBF, 0xc80),
INTC_VECT(USBF, 0xca0),
INTC_VECT(TPU, 0xcc0), INTC_VECT(PCC, 0xce0),
INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
INTC_VECT(SIM, 0xd80), INTC_VECT(SIM, 0xda0),
INTC_VECT(SIM, 0xdc0), INTC_VECT(SIM, 0xde0),
INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
INTC_VECT(TMU5, 0xe40), INTC_VECT(ADC, 0xe60),
INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
INTC_VECT(SSI2, 0xec0), INTC_VECT(SSI3, 0xee0),
INTC_VECT(SCIF2, 0xf00), INTC_VECT(SCIF2, 0xf20),
INTC_VECT(SCIF2, 0xf40), INTC_VECT(SCIF2, 0xf60),
INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
};
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
{ 0, 0, 0, 0, 0, 0, GPIO, 0,
SSI0, MMCIF, 0, SIOF0, PCIC5, PCIINTD, PCIINTC, PCIINTB,
PCIINTA, PCISERR, HAC, CMT, 0, 0, 0, DMAC,
HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },
{ 0xffd400d0, 0xffd400d4, 32, /* INT2MSKR1 / INT2MSKCR1 */
{ 0, 0, 0, 0, 0, 0, SCIF2, USBF,
0, 0, STIF1, STIF0, 0, 0, USBH, GETHER,
PCC, 0, 0, ADC, TPU, SIM, SIOF2, SIOF1,
LCDC, 0, IIC1, IIC0, SSI3, SSI2, SSI1, 0 } },
};
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
TMU2, TMU2_TICPI } },
{ 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },
{ 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },
{ 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC, ADC } },
{ 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC,
PCISERR, PCIINTA } },
{ 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,
PCIINTD, PCIC5 } },
{ 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF0, USBF, MMCIF, SSI0 } },
{ 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { SCIF2, GPIO } },
{ 0xffd400a0, 0, 32, 8, /* INT2PRI8 */ { SSI3, SSI2, SSI1, 0 } },
{ 0xffd400a4, 0, 32, 8, /* INT2PRI9 */ { LCDC, 0, IIC1, IIC0 } },
{ 0xffd400a8, 0, 32, 8, /* INT2PRI10 */ { TPU, SIM, SIOF2, SIOF1 } },
{ 0xffd400ac, 0, 32, 8, /* INT2PRI11 */ { PCC } },
{ 0xffd400b0, 0, 32, 8, /* INT2PRI12 */ { 0, 0, USBH, GETHER } },
{ 0xffd400b4, 0, 32, 8, /* INT2PRI13 */ { 0, 0, STIF1, STIF0 } },
};
static DECLARE_INTC_DESC(intc_desc, "sh7763", vectors, groups,
mask_registers, prio_registers, NULL);
/* Support for external interrupt pins in IRQ mode */
static struct intc_vect irq_vectors[] __initdata = {
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
};
static struct intc_mask_reg irq_mask_registers[] __initdata = {
{ 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_prio_reg irq_prio_registers[] __initdata = {
{ 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_sense_reg irq_sense_registers[] __initdata = {
{ 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_mask_reg irq_ack_registers[] __initdata = {
{ 0xffd00024, 0, 32, /* INTREQ */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7763-irq", irq_vectors,
NULL, irq_mask_registers, irq_prio_registers,
irq_sense_registers, irq_ack_registers);
/* External interrupt pins in IRL mode */
static struct intc_vect irl_vectors[] __initdata = {
INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
INTC_VECT(IRL_HHHL, 0x3c0),
};
static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
{ IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
};
static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
};
static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7763-irl7654", irl_vectors,
NULL, irl7654_mask_registers, NULL, NULL);
static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors,
NULL, irl3210_mask_registers, NULL, NULL);
#define INTC_ICR0 0xffd00000
#define INTC_INTMSK0 0xffd00044
#define INTC_INTMSK1 0xffd00048
#define INTC_INTMSK2 0xffd40080
#define INTC_INTMSKCLR1 0xffd00068
#define INTC_INTMSKCLR2 0xffd40084
void __init plat_irq_setup(void)
{
/* disable IRQ7-0 */
__raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
__raw_writel(0xc0000000, INTC_INTMSK1);
__raw_writel(0xfffefffe, INTC_INTMSK2);
register_intc_controller(&intc_desc);
}
void __init plat_irq_setup_pins(int mode)
{
switch (mode) {
case IRQ_MODE_IRQ:
/* select IRQ mode for IRL3-0 + IRL7-4 */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
register_intc_controller(&intc_irq_desc);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
__raw_writel(0x40000000, INTC_INTMSKCLR1);
__raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
__raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl7654_desc);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl3210_desc);
break;
default:
BUG();
}
}

View file

@ -0,0 +1,583 @@
/*
* SH7770 Setup
*
* Copyright (C) 2006 - 2008 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <linux/io.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xff923000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x9a0)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
static struct resource scif1_resources[] = {
DEFINE_RES_MEM(0xff924000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x9c0)),
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.resource = scif1_resources,
.num_resources = ARRAY_SIZE(scif1_resources),
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
static struct resource scif2_resources[] = {
DEFINE_RES_MEM(0xff925000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x9e0)),
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.resource = scif2_resources,
.num_resources = ARRAY_SIZE(scif2_resources),
.dev = {
.platform_data = &scif2_platform_data,
},
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
static struct resource scif3_resources[] = {
DEFINE_RES_MEM(0xff926000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xa00)),
};
static struct platform_device scif3_device = {
.name = "sh-sci",
.id = 3,
.resource = scif3_resources,
.num_resources = ARRAY_SIZE(scif3_resources),
.dev = {
.platform_data = &scif3_platform_data,
},
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
static struct resource scif4_resources[] = {
DEFINE_RES_MEM(0xff927000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xa20)),
};
static struct platform_device scif4_device = {
.name = "sh-sci",
.id = 4,
.resource = scif4_resources,
.num_resources = ARRAY_SIZE(scif4_resources),
.dev = {
.platform_data = &scif4_platform_data,
},
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
static struct resource scif5_resources[] = {
DEFINE_RES_MEM(0xff928000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xa40)),
};
static struct platform_device scif5_device = {
.name = "sh-sci",
.id = 5,
.resource = scif5_resources,
.num_resources = ARRAY_SIZE(scif5_resources),
.dev = {
.platform_data = &scif5_platform_data,
},
};
static struct plat_sci_port scif6_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
static struct resource scif6_resources[] = {
DEFINE_RES_MEM(0xff929000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xa60)),
};
static struct platform_device scif6_device = {
.name = "sh-sci",
.id = 6,
.resource = scif6_resources,
.num_resources = ARRAY_SIZE(scif6_resources),
.dev = {
.platform_data = &scif6_platform_data,
},
};
static struct plat_sci_port scif7_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
static struct resource scif7_resources[] = {
DEFINE_RES_MEM(0xff92a000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xa80)),
};
static struct platform_device scif7_device = {
.name = "sh-sci",
.id = 7,
.resource = scif7_resources,
.num_resources = ARRAY_SIZE(scif7_resources),
.dev = {
.platform_data = &scif7_platform_data,
},
};
static struct plat_sci_port scif8_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
static struct resource scif8_resources[] = {
DEFINE_RES_MEM(0xff92b000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xaa0)),
};
static struct platform_device scif8_device = {
.name = "sh-sci",
.id = 8,
.resource = scif8_resources,
.num_resources = ARRAY_SIZE(scif8_resources),
.dev = {
.platform_data = &scif8_platform_data,
},
};
static struct plat_sci_port scif9_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE,
.type = PORT_SCIF,
};
static struct resource scif9_resources[] = {
DEFINE_RES_MEM(0xff92c000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xac0)),
};
static struct platform_device scif9_device = {
.name = "sh-sci",
.id = 9,
.resource = scif9_resources,
.num_resources = ARRAY_SIZE(scif9_resources),
.dev = {
.platform_data = &scif9_platform_data,
},
};
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffd80000, 0x30),
DEFINE_RES_IRQ(evt2irq(0x400)),
DEFINE_RES_IRQ(evt2irq(0x420)),
DEFINE_RES_IRQ(evt2irq(0x440)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct sh_timer_config tmu1_platform_data = {
.channels_mask = 7,
};
static struct resource tmu1_resources[] = {
DEFINE_RES_MEM(0xffd81000, 0x30),
DEFINE_RES_IRQ(evt2irq(0x460)),
DEFINE_RES_IRQ(evt2irq(0x480)),
DEFINE_RES_IRQ(evt2irq(0x4a0)),
};
static struct platform_device tmu1_device = {
.name = "sh-tmu",
.id = 1,
.dev = {
.platform_data = &tmu1_platform_data,
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
};
static struct sh_timer_config tmu2_platform_data = {
.channels_mask = 7,
};
static struct resource tmu2_resources[] = {
DEFINE_RES_MEM(0xffd82000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0x4c0)),
DEFINE_RES_IRQ(evt2irq(0x4e0)),
DEFINE_RES_IRQ(evt2irq(0x500)),
};
static struct platform_device tmu2_device = {
.name = "sh-tmu",
.id = 2,
.dev = {
.platform_data = &tmu2_platform_data,
},
.resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources),
};
static struct platform_device *sh7770_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&scif6_device,
&scif7_device,
&scif8_device,
&scif9_device,
&tmu0_device,
&tmu1_device,
&tmu2_device,
};
static int __init sh7770_devices_setup(void)
{
return platform_add_devices(sh7770_devices,
ARRAY_SIZE(sh7770_devices));
}
arch_initcall(sh7770_devices_setup);
static struct platform_device *sh7770_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&scif6_device,
&scif7_device,
&scif8_device,
&scif9_device,
&tmu0_device,
&tmu1_device,
&tmu2_device,
};
void __init plat_early_device_setup(void)
{
early_platform_add_devices(sh7770_early_devices,
ARRAY_SIZE(sh7770_early_devices));
}
enum {
UNUSED = 0,
/* interrupt sources */
IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
GPIO,
TMU0, TMU1, TMU2, TMU2_TICPI,
TMU3, TMU4, TMU5, TMU5_TICPI,
TMU6, TMU7, TMU8,
HAC, IPI, SPDIF, HUDI, I2C,
DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
I2S0, I2S1, I2S2, I2S3,
SRC_RX, SRC_TX, SRC_SPDIF,
DU, VIDEO_IN, REMOTE, YUV, USB, ATAPI, CAN, GPS, GFX2D,
GFX3D_MBX, GFX3D_DMAC,
EXBUS_ATA,
SPI0, SPI1,
SCIF089, SCIF1234, SCIF567,
ADC,
BBDMAC_0_3, BBDMAC_4_7, BBDMAC_8_10, BBDMAC_11_14,
BBDMAC_15_18, BBDMAC_19_22, BBDMAC_23_26, BBDMAC_27,
BBDMAC_28, BBDMAC_29, BBDMAC_30, BBDMAC_31,
/* interrupt groups */
TMU, DMAC, I2S, SRC, GFX3D, SPI, SCIF, BBDMAC,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(GPIO, 0x3e0),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
INTC_VECT(TMU3, 0x480), INTC_VECT(TMU4, 0x4a0),
INTC_VECT(TMU5, 0x4c0), INTC_VECT(TMU5_TICPI, 0x4e0),
INTC_VECT(TMU6, 0x500), INTC_VECT(TMU7, 0x520),
INTC_VECT(TMU8, 0x540),
INTC_VECT(HAC, 0x580), INTC_VECT(IPI, 0x5c0),
INTC_VECT(SPDIF, 0x5e0),
INTC_VECT(HUDI, 0x600), INTC_VECT(I2C, 0x620),
INTC_VECT(DMAC0_DMINT0, 0x640), INTC_VECT(DMAC0_DMINT1, 0x660),
INTC_VECT(DMAC0_DMINT2, 0x680),
INTC_VECT(I2S0, 0x6a0), INTC_VECT(I2S1, 0x6c0),
INTC_VECT(I2S2, 0x6e0), INTC_VECT(I2S3, 0x700),
INTC_VECT(SRC_RX, 0x720), INTC_VECT(SRC_TX, 0x740),
INTC_VECT(SRC_SPDIF, 0x760),
INTC_VECT(DU, 0x780), INTC_VECT(VIDEO_IN, 0x7a0),
INTC_VECT(REMOTE, 0x7c0), INTC_VECT(YUV, 0x7e0),
INTC_VECT(USB, 0x840), INTC_VECT(ATAPI, 0x860),
INTC_VECT(CAN, 0x880), INTC_VECT(GPS, 0x8a0),
INTC_VECT(GFX2D, 0x8c0),
INTC_VECT(GFX3D_MBX, 0x900), INTC_VECT(GFX3D_DMAC, 0x920),
INTC_VECT(EXBUS_ATA, 0x940),
INTC_VECT(SPI0, 0x960), INTC_VECT(SPI1, 0x980),
INTC_VECT(SCIF089, 0x9a0), INTC_VECT(SCIF1234, 0x9c0),
INTC_VECT(SCIF1234, 0x9e0), INTC_VECT(SCIF1234, 0xa00),
INTC_VECT(SCIF1234, 0xa20), INTC_VECT(SCIF567, 0xa40),
INTC_VECT(SCIF567, 0xa60), INTC_VECT(SCIF567, 0xa80),
INTC_VECT(SCIF089, 0xaa0), INTC_VECT(SCIF089, 0xac0),
INTC_VECT(ADC, 0xb20),
INTC_VECT(BBDMAC_0_3, 0xba0), INTC_VECT(BBDMAC_0_3, 0xbc0),
INTC_VECT(BBDMAC_0_3, 0xbe0), INTC_VECT(BBDMAC_0_3, 0xc00),
INTC_VECT(BBDMAC_4_7, 0xc20), INTC_VECT(BBDMAC_4_7, 0xc40),
INTC_VECT(BBDMAC_4_7, 0xc60), INTC_VECT(BBDMAC_4_7, 0xc80),
INTC_VECT(BBDMAC_8_10, 0xca0), INTC_VECT(BBDMAC_8_10, 0xcc0),
INTC_VECT(BBDMAC_8_10, 0xce0), INTC_VECT(BBDMAC_11_14, 0xd00),
INTC_VECT(BBDMAC_11_14, 0xd20), INTC_VECT(BBDMAC_11_14, 0xd40),
INTC_VECT(BBDMAC_11_14, 0xd60), INTC_VECT(BBDMAC_15_18, 0xd80),
INTC_VECT(BBDMAC_15_18, 0xda0), INTC_VECT(BBDMAC_15_18, 0xdc0),
INTC_VECT(BBDMAC_15_18, 0xde0), INTC_VECT(BBDMAC_19_22, 0xe00),
INTC_VECT(BBDMAC_19_22, 0xe20), INTC_VECT(BBDMAC_19_22, 0xe40),
INTC_VECT(BBDMAC_19_22, 0xe60), INTC_VECT(BBDMAC_23_26, 0xe80),
INTC_VECT(BBDMAC_23_26, 0xea0), INTC_VECT(BBDMAC_23_26, 0xec0),
INTC_VECT(BBDMAC_23_26, 0xee0), INTC_VECT(BBDMAC_27, 0xf00),
INTC_VECT(BBDMAC_28, 0xf20), INTC_VECT(BBDMAC_29, 0xf40),
INTC_VECT(BBDMAC_30, 0xf60), INTC_VECT(BBDMAC_31, 0xf80),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(TMU, TMU0, TMU1, TMU2, TMU2_TICPI, TMU3, TMU4, TMU5,
TMU5_TICPI, TMU6, TMU7, TMU8),
INTC_GROUP(DMAC, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2),
INTC_GROUP(I2S, I2S0, I2S1, I2S2, I2S3),
INTC_GROUP(SRC, SRC_RX, SRC_TX, SRC_SPDIF),
INTC_GROUP(GFX3D, GFX3D_MBX, GFX3D_DMAC),
INTC_GROUP(SPI, SPI0, SPI1),
INTC_GROUP(SCIF, SCIF089, SCIF1234, SCIF567),
INTC_GROUP(BBDMAC,
BBDMAC_0_3, BBDMAC_4_7, BBDMAC_8_10, BBDMAC_11_14,
BBDMAC_15_18, BBDMAC_19_22, BBDMAC_23_26, BBDMAC_27,
BBDMAC_28, BBDMAC_29, BBDMAC_30, BBDMAC_31),
};
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xffe00040, 0xffe00044, 32, /* INT2MSKR / INT2MSKCR */
{ 0, BBDMAC, ADC, SCIF, SPI, EXBUS_ATA, GFX3D, GFX2D,
GPS, CAN, ATAPI, USB, YUV, REMOTE, VIDEO_IN, DU, SRC, I2S,
DMAC, I2C, HUDI, SPDIF, IPI, HAC, TMU, GPIO } },
};
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xffe00000, 0, 32, 8, /* INT2PRI0 */ { GPIO, TMU0, 0, HAC } },
{ 0xffe00004, 0, 32, 8, /* INT2PRI1 */ { IPI, SPDIF, HUDI, I2C } },
{ 0xffe00008, 0, 32, 8, /* INT2PRI2 */ { DMAC, I2S, SRC, DU } },
{ 0xffe0000c, 0, 32, 8, /* INT2PRI3 */ { VIDEO_IN, REMOTE, YUV, USB } },
{ 0xffe00010, 0, 32, 8, /* INT2PRI4 */ { ATAPI, CAN, GPS, GFX2D } },
{ 0xffe00014, 0, 32, 8, /* INT2PRI5 */ { 0, GFX3D, EXBUS_ATA, SPI } },
{ 0xffe00018, 0, 32, 8, /* INT2PRI6 */ { SCIF1234, SCIF567, SCIF089 } },
{ 0xffe0001c, 0, 32, 8, /* INT2PRI7 */ { ADC, 0, 0, BBDMAC_0_3 } },
{ 0xffe00020, 0, 32, 8, /* INT2PRI8 */
{ BBDMAC_4_7, BBDMAC_8_10, BBDMAC_11_14, BBDMAC_15_18 } },
{ 0xffe00024, 0, 32, 8, /* INT2PRI9 */
{ BBDMAC_19_22, BBDMAC_23_26, BBDMAC_27, BBDMAC_28 } },
{ 0xffe00028, 0, 32, 8, /* INT2PRI10 */
{ BBDMAC_29, BBDMAC_30, BBDMAC_31 } },
{ 0xffe0002c, 0, 32, 8, /* INT2PRI11 */
{ TMU1, TMU2, TMU2_TICPI, TMU3 } },
{ 0xffe00030, 0, 32, 8, /* INT2PRI12 */
{ TMU4, TMU5, TMU5_TICPI, TMU6 } },
{ 0xffe00034, 0, 32, 8, /* INT2PRI13 */
{ TMU7, TMU8 } },
};
static DECLARE_INTC_DESC(intc_desc, "sh7770", vectors, groups,
mask_registers, prio_registers, NULL);
/* Support for external interrupt pins in IRQ mode */
static struct intc_vect irq_vectors[] __initdata = {
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
};
static struct intc_mask_reg irq_mask_registers[] __initdata = {
{ 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, } },
};
static struct intc_prio_reg irq_prio_registers[] __initdata = {
{ 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, } },
};
static struct intc_sense_reg irq_sense_registers[] __initdata = {
{ 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, } },
};
static DECLARE_INTC_DESC(intc_irq_desc, "sh7770-irq", irq_vectors,
NULL, irq_mask_registers, irq_prio_registers,
irq_sense_registers);
/* External interrupt pins in IRL mode */
static struct intc_vect irl_vectors[] __initdata = {
INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
INTC_VECT(IRL_HHHL, 0x3c0),
};
static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
{ IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
};
static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
};
static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors,
NULL, irl7654_mask_registers, NULL, NULL);
static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
NULL, irl3210_mask_registers, NULL, NULL);
#define INTC_ICR0 0xffd00000
#define INTC_INTMSK0 0xffd00044
#define INTC_INTMSK1 0xffd00048
#define INTC_INTMSK2 0xffd40080
#define INTC_INTMSKCLR1 0xffd00068
#define INTC_INTMSKCLR2 0xffd40084
void __init plat_irq_setup(void)
{
/* disable IRQ7-0 */
__raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
__raw_writel(0xc0000000, INTC_INTMSK1);
__raw_writel(0xfffefffe, INTC_INTMSK2);
/* select IRL mode for IRL3-0 + IRL7-4 */
__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
/* disable holding function, ie enable "SH-4 Mode" */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
register_intc_controller(&intc_desc);
}
void __init plat_irq_setup_pins(int mode)
{
switch (mode) {
case IRQ_MODE_IRQ:
/* select IRQ mode for IRL3-0 + IRL7-4 */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
register_intc_controller(&intc_irq_desc);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
__raw_writel(0x40000000, INTC_INTMSKCLR1);
__raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
__raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl7654_desc);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl3210_desc);
break;
default:
BUG();
}
}

View file

@ -0,0 +1,509 @@
/*
* SH7780 Setup
*
* Copyright (C) 2006 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/io.h>
#include <linux/serial_sci.h>
#include <linux/sh_dma.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <cpu/dma-register.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xffe00000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x700)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif1_resources[] = {
DEFINE_RES_MEM(0xffe10000, 0x100),
DEFINE_RES_IRQ(evt2irq(0xb80)),
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.resource = scif1_resources,
.num_resources = ARRAY_SIZE(scif1_resources),
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffd80000, 0x30),
DEFINE_RES_IRQ(evt2irq(0x580)),
DEFINE_RES_IRQ(evt2irq(0x5a0)),
DEFINE_RES_IRQ(evt2irq(0x5c0)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct sh_timer_config tmu1_platform_data = {
.channels_mask = 7,
};
static struct resource tmu1_resources[] = {
DEFINE_RES_MEM(0xffdc0000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0xe00)),
DEFINE_RES_IRQ(evt2irq(0xe20)),
DEFINE_RES_IRQ(evt2irq(0xe40)),
};
static struct platform_device tmu1_device = {
.name = "sh-tmu",
.id = 1,
.dev = {
.platform_data = &tmu1_platform_data,
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
};
static struct resource rtc_resources[] = {
[0] = {
.start = 0xffe80000,
.end = 0xffe80000 + 0x58 - 1,
.flags = IORESOURCE_IO,
},
[1] = {
/* Shared Period/Carry/Alarm IRQ */
.start = evt2irq(0x480),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device rtc_device = {
.name = "sh-rtc",
.id = -1,
.num_resources = ARRAY_SIZE(rtc_resources),
.resource = rtc_resources,
};
/* DMA */
static const struct sh_dmae_channel sh7780_dmae0_channels[] = {
{
.offset = 0,
.dmars = 0,
.dmars_bit = 0,
}, {
.offset = 0x10,
.dmars = 0,
.dmars_bit = 8,
}, {
.offset = 0x20,
.dmars = 4,
.dmars_bit = 0,
}, {
.offset = 0x30,
.dmars = 4,
.dmars_bit = 8,
}, {
.offset = 0x50,
.dmars = 8,
.dmars_bit = 0,
}, {
.offset = 0x60,
.dmars = 8,
.dmars_bit = 8,
}
};
static const struct sh_dmae_channel sh7780_dmae1_channels[] = {
{
.offset = 0,
}, {
.offset = 0x10,
}, {
.offset = 0x20,
}, {
.offset = 0x30,
}, {
.offset = 0x50,
}, {
.offset = 0x60,
}
};
static const unsigned int ts_shift[] = TS_SHIFT;
static struct sh_dmae_pdata dma0_platform_data = {
.channel = sh7780_dmae0_channels,
.channel_num = ARRAY_SIZE(sh7780_dmae0_channels),
.ts_low_shift = CHCR_TS_LOW_SHIFT,
.ts_low_mask = CHCR_TS_LOW_MASK,
.ts_high_shift = CHCR_TS_HIGH_SHIFT,
.ts_high_mask = CHCR_TS_HIGH_MASK,
.ts_shift = ts_shift,
.ts_shift_num = ARRAY_SIZE(ts_shift),
.dmaor_init = DMAOR_INIT,
};
static struct sh_dmae_pdata dma1_platform_data = {
.channel = sh7780_dmae1_channels,
.channel_num = ARRAY_SIZE(sh7780_dmae1_channels),
.ts_low_shift = CHCR_TS_LOW_SHIFT,
.ts_low_mask = CHCR_TS_LOW_MASK,
.ts_high_shift = CHCR_TS_HIGH_SHIFT,
.ts_high_mask = CHCR_TS_HIGH_MASK,
.ts_shift = ts_shift,
.ts_shift_num = ARRAY_SIZE(ts_shift),
.dmaor_init = DMAOR_INIT,
};
static struct resource sh7780_dmae0_resources[] = {
[0] = {
/* Channel registers and DMAOR */
.start = 0xfc808020,
.end = 0xfc80808f,
.flags = IORESOURCE_MEM,
},
[1] = {
/* DMARSx */
.start = 0xfc809000,
.end = 0xfc80900b,
.flags = IORESOURCE_MEM,
},
{
/*
* Real DMA error vector is 0x6c0, and channel
* vectors are 0x640-0x6a0, 0x780-0x7a0
*/
.name = "error_irq",
.start = evt2irq(0x640),
.end = evt2irq(0x640),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
};
static struct resource sh7780_dmae1_resources[] = {
[0] = {
/* Channel registers and DMAOR */
.start = 0xfc818020,
.end = 0xfc81808f,
.flags = IORESOURCE_MEM,
},
/* DMAC1 has no DMARS */
{
/*
* Real DMA error vector is 0x6c0, and channel
* vectors are 0x7c0-0x7e0, 0xd80-0xde0
*/
.name = "error_irq",
.start = evt2irq(0x7c0),
.end = evt2irq(0x7c0),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
};
static struct platform_device dma0_device = {
.name = "sh-dma-engine",
.id = 0,
.resource = sh7780_dmae0_resources,
.num_resources = ARRAY_SIZE(sh7780_dmae0_resources),
.dev = {
.platform_data = &dma0_platform_data,
},
};
static struct platform_device dma1_device = {
.name = "sh-dma-engine",
.id = 1,
.resource = sh7780_dmae1_resources,
.num_resources = ARRAY_SIZE(sh7780_dmae1_resources),
.dev = {
.platform_data = &dma1_platform_data,
},
};
static struct platform_device *sh7780_devices[] __initdata = {
&scif0_device,
&scif1_device,
&tmu0_device,
&tmu1_device,
&rtc_device,
&dma0_device,
&dma1_device,
};
static int __init sh7780_devices_setup(void)
{
return platform_add_devices(sh7780_devices,
ARRAY_SIZE(sh7780_devices));
}
arch_initcall(sh7780_devices_setup);
static struct platform_device *sh7780_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&tmu0_device,
&tmu1_device,
};
void __init plat_early_device_setup(void)
{
if (mach_is_sh2007()) {
scif0_platform_data.scscr &= ~SCSCR_CKE1;
scif1_platform_data.scscr &= ~SCSCR_CKE1;
}
early_platform_add_devices(sh7780_early_devices,
ARRAY_SIZE(sh7780_early_devices));
}
enum {
UNUSED = 0,
/* interrupt sources */
IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
HUDI, DMAC0, SCIF0, DMAC1, CMT, HAC,
PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
SCIF1, SIOF, HSPI, MMCIF, TMU3, TMU4, TMU5, SSI, FLCTL, GPIO,
/* interrupt groups */
TMU012, TMU345,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
INTC_VECT(RTC, 0x4c0),
INTC_VECT(WDT, 0x560),
INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
INTC_VECT(HUDI, 0x600),
INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660),
INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0),
INTC_VECT(DMAC0, 0x6c0),
INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0),
INTC_VECT(DMAC1, 0x7c0), INTC_VECT(DMAC1, 0x7e0),
INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980),
INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),
INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),
INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80),
INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
INTC_VECT(DMAC1, 0xd80), INTC_VECT(DMAC1, 0xda0),
INTC_VECT(DMAC1, 0xdc0), INTC_VECT(DMAC1, 0xde0),
INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
INTC_VECT(TMU5, 0xe40),
INTC_VECT(SSI, 0xe80),
INTC_VECT(FLCTL, 0xf00), INTC_VECT(FLCTL, 0xf20),
INTC_VECT(FLCTL, 0xf40), INTC_VECT(FLCTL, 0xf60),
INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
};
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
{ 0, 0, 0, 0, 0, 0, GPIO, FLCTL,
SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB,
PCIINTA, PCISERR, HAC, CMT, 0, 0, DMAC1, DMAC0,
HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },
};
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
TMU2, TMU2_TICPI } },
{ 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },
{ 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },
{ 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } },
{ 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC,
PCISERR, PCIINTA, } },
{ 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,
PCIINTD, PCIC5 } },
{ 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } },
{ 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } },
};
static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups,
mask_registers, prio_registers, NULL);
/* Support for external interrupt pins in IRQ mode */
static struct intc_vect irq_vectors[] __initdata = {
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
};
static struct intc_mask_reg irq_mask_registers[] __initdata = {
{ 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_prio_reg irq_prio_registers[] __initdata = {
{ 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_sense_reg irq_sense_registers[] __initdata = {
{ 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_mask_reg irq_ack_registers[] __initdata = {
{ 0xffd00024, 0, 32, /* INTREQ */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7780-irq", irq_vectors,
NULL, irq_mask_registers, irq_prio_registers,
irq_sense_registers, irq_ack_registers);
/* External interrupt pins in IRL mode */
static struct intc_vect irl_vectors[] __initdata = {
INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
INTC_VECT(IRL_HHHL, 0x3c0),
};
static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
{ IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
};
static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
};
static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors,
NULL, irl7654_mask_registers, NULL, NULL);
static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
NULL, irl3210_mask_registers, NULL, NULL);
#define INTC_ICR0 0xffd00000
#define INTC_INTMSK0 0xffd00044
#define INTC_INTMSK1 0xffd00048
#define INTC_INTMSK2 0xffd40080
#define INTC_INTMSKCLR1 0xffd00068
#define INTC_INTMSKCLR2 0xffd40084
void __init plat_irq_setup(void)
{
/* disable IRQ7-0 */
__raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
__raw_writel(0xc0000000, INTC_INTMSK1);
__raw_writel(0xfffefffe, INTC_INTMSK2);
/* select IRL mode for IRL3-0 + IRL7-4 */
__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
/* disable holding function, ie enable "SH-4 Mode" */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
register_intc_controller(&intc_desc);
}
void __init plat_irq_setup_pins(int mode)
{
switch (mode) {
case IRQ_MODE_IRQ:
/* select IRQ mode for IRL3-0 + IRL7-4 */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
register_intc_controller(&intc_irq_desc);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
__raw_writel(0x40000000, INTC_INTMSKCLR1);
__raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
__raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl7654_desc);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_irl3210_desc);
break;
default:
BUG();
}
}

View file

@ -0,0 +1,616 @@
/*
* SH7785 Setup
*
* Copyright (C) 2007 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/sh_dma.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <asm/mmzone.h>
#include <cpu/dma-register.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xffea0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x700)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif1_resources[] = {
DEFINE_RES_MEM(0xffeb0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x780)),
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.resource = scif1_resources,
.num_resources = ARRAY_SIZE(scif1_resources),
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif2_resources[] = {
DEFINE_RES_MEM(0xffec0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x980)),
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.resource = scif2_resources,
.num_resources = ARRAY_SIZE(scif2_resources),
.dev = {
.platform_data = &scif2_platform_data,
},
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif3_resources[] = {
DEFINE_RES_MEM(0xffed0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x9a0)),
};
static struct platform_device scif3_device = {
.name = "sh-sci",
.id = 3,
.resource = scif3_resources,
.num_resources = ARRAY_SIZE(scif3_resources),
.dev = {
.platform_data = &scif3_platform_data,
},
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif4_resources[] = {
DEFINE_RES_MEM(0xffee0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x9c0)),
};
static struct platform_device scif4_device = {
.name = "sh-sci",
.id = 4,
.resource = scif4_resources,
.num_resources = ARRAY_SIZE(scif4_resources),
.dev = {
.platform_data = &scif4_platform_data,
},
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif5_resources[] = {
DEFINE_RES_MEM(0xffef0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x9e0)),
};
static struct platform_device scif5_device = {
.name = "sh-sci",
.id = 5,
.resource = scif5_resources,
.num_resources = ARRAY_SIZE(scif5_resources),
.dev = {
.platform_data = &scif5_platform_data,
},
};
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffd80000, 0x30),
DEFINE_RES_IRQ(evt2irq(0x580)),
DEFINE_RES_IRQ(evt2irq(0x5a0)),
DEFINE_RES_IRQ(evt2irq(0x5c0)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct sh_timer_config tmu1_platform_data = {
.channels_mask = 7,
};
static struct resource tmu1_resources[] = {
DEFINE_RES_MEM(0xffdc0000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0xe00)),
DEFINE_RES_IRQ(evt2irq(0xe20)),
DEFINE_RES_IRQ(evt2irq(0xe40)),
};
static struct platform_device tmu1_device = {
.name = "sh-tmu",
.id = 1,
.dev = {
.platform_data = &tmu1_platform_data,
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
};
/* DMA */
static const struct sh_dmae_channel sh7785_dmae0_channels[] = {
{
.offset = 0,
.dmars = 0,
.dmars_bit = 0,
}, {
.offset = 0x10,
.dmars = 0,
.dmars_bit = 8,
}, {
.offset = 0x20,
.dmars = 4,
.dmars_bit = 0,
}, {
.offset = 0x30,
.dmars = 4,
.dmars_bit = 8,
}, {
.offset = 0x50,
.dmars = 8,
.dmars_bit = 0,
}, {
.offset = 0x60,
.dmars = 8,
.dmars_bit = 8,
}
};
static const struct sh_dmae_channel sh7785_dmae1_channels[] = {
{
.offset = 0,
}, {
.offset = 0x10,
}, {
.offset = 0x20,
}, {
.offset = 0x30,
}, {
.offset = 0x50,
}, {
.offset = 0x60,
}
};
static const unsigned int ts_shift[] = TS_SHIFT;
static struct sh_dmae_pdata dma0_platform_data = {
.channel = sh7785_dmae0_channels,
.channel_num = ARRAY_SIZE(sh7785_dmae0_channels),
.ts_low_shift = CHCR_TS_LOW_SHIFT,
.ts_low_mask = CHCR_TS_LOW_MASK,
.ts_high_shift = CHCR_TS_HIGH_SHIFT,
.ts_high_mask = CHCR_TS_HIGH_MASK,
.ts_shift = ts_shift,
.ts_shift_num = ARRAY_SIZE(ts_shift),
.dmaor_init = DMAOR_INIT,
};
static struct sh_dmae_pdata dma1_platform_data = {
.channel = sh7785_dmae1_channels,
.channel_num = ARRAY_SIZE(sh7785_dmae1_channels),
.ts_low_shift = CHCR_TS_LOW_SHIFT,
.ts_low_mask = CHCR_TS_LOW_MASK,
.ts_high_shift = CHCR_TS_HIGH_SHIFT,
.ts_high_mask = CHCR_TS_HIGH_MASK,
.ts_shift = ts_shift,
.ts_shift_num = ARRAY_SIZE(ts_shift),
.dmaor_init = DMAOR_INIT,
};
static struct resource sh7785_dmae0_resources[] = {
[0] = {
/* Channel registers and DMAOR */
.start = 0xfc808020,
.end = 0xfc80808f,
.flags = IORESOURCE_MEM,
},
[1] = {
/* DMARSx */
.start = 0xfc809000,
.end = 0xfc80900b,
.flags = IORESOURCE_MEM,
},
{
/*
* Real DMA error vector is 0x6e0, and channel
* vectors are 0x620-0x6c0
*/
.name = "error_irq",
.start = evt2irq(0x620),
.end = evt2irq(0x620),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
};
static struct resource sh7785_dmae1_resources[] = {
[0] = {
/* Channel registers and DMAOR */
.start = 0xfcc08020,
.end = 0xfcc0808f,
.flags = IORESOURCE_MEM,
},
/* DMAC1 has no DMARS */
{
/*
* Real DMA error vector is 0x940, and channel
* vectors are 0x880-0x920
*/
.name = "error_irq",
.start = evt2irq(0x880),
.end = evt2irq(0x880),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
},
};
static struct platform_device dma0_device = {
.name = "sh-dma-engine",
.id = 0,
.resource = sh7785_dmae0_resources,
.num_resources = ARRAY_SIZE(sh7785_dmae0_resources),
.dev = {
.platform_data = &dma0_platform_data,
},
};
static struct platform_device dma1_device = {
.name = "sh-dma-engine",
.id = 1,
.resource = sh7785_dmae1_resources,
.num_resources = ARRAY_SIZE(sh7785_dmae1_resources),
.dev = {
.platform_data = &dma1_platform_data,
},
};
static struct platform_device *sh7785_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&tmu0_device,
&tmu1_device,
&dma0_device,
&dma1_device,
};
static int __init sh7785_devices_setup(void)
{
return platform_add_devices(sh7785_devices,
ARRAY_SIZE(sh7785_devices));
}
arch_initcall(sh7785_devices_setup);
static struct platform_device *sh7785_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&tmu0_device,
&tmu1_device,
};
void __init plat_early_device_setup(void)
{
early_platform_add_devices(sh7785_early_devices,
ARRAY_SIZE(sh7785_early_devices));
}
enum {
UNUSED = 0,
/* interrupt sources */
IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
IRL0_HHLL, IRL0_HHLH, IRL0_HHHL,
IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
HUDI, DMAC0, SCIF0, SCIF1, DMAC1, HSPI,
SCIF2, SCIF3, SCIF4, SCIF5,
PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
SIOF, MMCIF, DU, GDTA,
TMU3, TMU4, TMU5,
SSI0, SSI1,
HAC0, HAC1,
FLCTL, GPIO,
/* interrupt groups */
TMU012, TMU345
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(WDT, 0x560),
INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
INTC_VECT(HUDI, 0x600),
INTC_VECT(DMAC0, 0x620), INTC_VECT(DMAC0, 0x640),
INTC_VECT(DMAC0, 0x660), INTC_VECT(DMAC0, 0x680),
INTC_VECT(DMAC0, 0x6a0), INTC_VECT(DMAC0, 0x6c0),
INTC_VECT(DMAC0, 0x6e0),
INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
INTC_VECT(SCIF1, 0x780), INTC_VECT(SCIF1, 0x7a0),
INTC_VECT(SCIF1, 0x7c0), INTC_VECT(SCIF1, 0x7e0),
INTC_VECT(DMAC1, 0x880), INTC_VECT(DMAC1, 0x8a0),
INTC_VECT(DMAC1, 0x8c0), INTC_VECT(DMAC1, 0x8e0),
INTC_VECT(DMAC1, 0x900), INTC_VECT(DMAC1, 0x920),
INTC_VECT(DMAC1, 0x940),
INTC_VECT(HSPI, 0x960),
INTC_VECT(SCIF2, 0x980), INTC_VECT(SCIF3, 0x9a0),
INTC_VECT(SCIF4, 0x9c0), INTC_VECT(SCIF5, 0x9e0),
INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
INTC_VECT(SIOF, 0xc00),
INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
INTC_VECT(DU, 0xd80),
INTC_VECT(GDTA, 0xda0), INTC_VECT(GDTA, 0xdc0),
INTC_VECT(GDTA, 0xde0),
INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
INTC_VECT(TMU5, 0xe40),
INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
INTC_VECT(HAC0, 0xec0), INTC_VECT(HAC1, 0xee0),
INTC_VECT(FLCTL, 0xf00), INTC_VECT(FLCTL, 0xf20),
INTC_VECT(FLCTL, 0xf40), INTC_VECT(FLCTL, 0xf60),
INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
};
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
{ IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, 0,
IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } },
{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
{ 0, 0, 0, GDTA, DU, SSI0, SSI1, GPIO,
FLCTL, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB,
PCIINTA, PCISERR, HAC1, HAC0, DMAC1, DMAC0, HUDI, WDT,
SCIF5, SCIF4, SCIF3, SCIF2, SCIF1, SCIF0, TMU345, TMU012 } },
};
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, IRQ6, IRQ7 } },
{ 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
TMU2, TMU2_TICPI } },
{ 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, } },
{ 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1,
SCIF2, SCIF3 } },
{ 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { SCIF4, SCIF5, WDT, } },
{ 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { HUDI, DMAC0, DMAC1, } },
{ 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { HAC0, HAC1,
PCISERR, PCIINTA } },
{ 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { PCIINTB, PCIINTC,
PCIINTD, PCIC5 } },
{ 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { SIOF, HSPI, MMCIF, } },
{ 0xffd40020, 0, 32, 8, /* INT2PRI8 */ { FLCTL, GPIO, SSI0, SSI1, } },
{ 0xffd40024, 0, 32, 8, /* INT2PRI9 */ { DU, GDTA, } },
};
static DECLARE_INTC_DESC(intc_desc, "sh7785", vectors, groups,
mask_registers, prio_registers, NULL);
/* Support for external interrupt pins in IRQ mode */
static struct intc_vect vectors_irq0123[] __initdata = {
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
};
static struct intc_vect vectors_irq4567[] __initdata = {
INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
};
static struct intc_sense_reg sense_registers[] __initdata = {
{ 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_mask_reg ack_registers[] __initdata = {
{ 0xffd00024, 0, 32, /* INTREQ */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh7785-irq0123",
vectors_irq0123, NULL, mask_registers,
prio_registers, sense_registers, ack_registers);
static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7785-irq4567",
vectors_irq4567, NULL, mask_registers,
prio_registers, sense_registers, ack_registers);
/* External interrupt pins in IRL mode */
static struct intc_vect vectors_irl0123[] __initdata = {
INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220),
INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260),
INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0),
INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0),
INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320),
INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360),
INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0),
INTC_VECT(IRL0_HHHL, 0x3c0),
};
static struct intc_vect vectors_irl4567[] __initdata = {
INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20),
INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60),
INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0),
INTC_VECT(IRL4_LHHL, 0xbc0), INTC_VECT(IRL4_LHHH, 0xbe0),
INTC_VECT(IRL4_HLLL, 0xc00), INTC_VECT(IRL4_HLLH, 0xc20),
INTC_VECT(IRL4_HLHL, 0xc40), INTC_VECT(IRL4_HLHH, 0xc60),
INTC_VECT(IRL4_HHLL, 0xc80), INTC_VECT(IRL4_HHLH, 0xca0),
INTC_VECT(IRL4_HHHL, 0xcc0),
};
static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7785-irl0123", vectors_irl0123,
NULL, mask_registers, NULL, NULL);
static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567,
NULL, mask_registers, NULL, NULL);
#define INTC_ICR0 0xffd00000
#define INTC_INTMSK0 0xffd00044
#define INTC_INTMSK1 0xffd00048
#define INTC_INTMSK2 0xffd40080
#define INTC_INTMSKCLR1 0xffd00068
#define INTC_INTMSKCLR2 0xffd40084
void __init plat_irq_setup(void)
{
/* disable IRQ3-0 + IRQ7-4 */
__raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
__raw_writel(0xc0000000, INTC_INTMSK1);
__raw_writel(0xfffefffe, INTC_INTMSK2);
/* select IRL mode for IRL3-0 + IRL7-4 */
__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
/* disable holding function, ie enable "SH-4 Mode" */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);
register_intc_controller(&intc_desc);
}
void __init plat_irq_setup_pins(int mode)
{
switch (mode) {
case IRQ_MODE_IRQ7654:
/* select IRQ mode for IRL7-4 */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0);
register_intc_controller(&intc_desc_irq4567);
break;
case IRQ_MODE_IRQ3210:
/* select IRQ mode for IRL3-0 */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0);
register_intc_controller(&intc_desc_irq0123);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
__raw_writel(0x40000000, INTC_INTMSKCLR1);
__raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
__raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_desc_irl4567);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_desc_irl0123);
break;
default:
BUG();
}
}
void __init plat_mem_setup(void)
{
/* Register the URAM space as Node 1 */
setup_bootmem_node(1, 0xe55f0000, 0xe5610000);
}

View file

@ -0,0 +1,848 @@
/*
* SH7786 Setup
*
* Copyright (C) 2009 - 2011 Renesas Solutions Corp.
* Kuninori Morimoto <morimoto.kuninori@renesas.com>
* Paul Mundt <paul.mundt@renesas.com>
*
* Based on SH7785 Setup
*
* Copyright (C) 2007 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/sh_timer.h>
#include <linux/sh_dma.h>
#include <linux/sh_intc.h>
#include <linux/usb/ohci_pdriver.h>
#include <cpu/dma-register.h>
#include <asm/mmzone.h>
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xffea0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x700)),
DEFINE_RES_IRQ(evt2irq(0x720)),
DEFINE_RES_IRQ(evt2irq(0x760)),
DEFINE_RES_IRQ(evt2irq(0x740)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
/*
* The rest of these all have multiplexed IRQs
*/
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif1_resources[] = {
DEFINE_RES_MEM(0xffeb0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x780)),
};
static struct resource scif1_demux_resources[] = {
DEFINE_RES_MEM(0xffeb0000, 0x100),
/* Placeholders, see sh7786_devices_setup() */
DEFINE_RES_IRQ(0),
DEFINE_RES_IRQ(0),
DEFINE_RES_IRQ(0),
DEFINE_RES_IRQ(0),
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.resource = scif1_resources,
.num_resources = ARRAY_SIZE(scif1_resources),
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif2_resources[] = {
DEFINE_RES_MEM(0xffec0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x840)),
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.resource = scif2_resources,
.num_resources = ARRAY_SIZE(scif2_resources),
.dev = {
.platform_data = &scif2_platform_data,
},
};
static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif3_resources[] = {
DEFINE_RES_MEM(0xffed0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x860)),
};
static struct platform_device scif3_device = {
.name = "sh-sci",
.id = 3,
.resource = scif3_resources,
.num_resources = ARRAY_SIZE(scif3_resources),
.dev = {
.platform_data = &scif3_platform_data,
},
};
static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif4_resources[] = {
DEFINE_RES_MEM(0xffee0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x880)),
};
static struct platform_device scif4_device = {
.name = "sh-sci",
.id = 4,
.resource = scif4_resources,
.num_resources = ARRAY_SIZE(scif4_resources),
.dev = {
.platform_data = &scif4_platform_data,
},
};
static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1,
.type = PORT_SCIF,
.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
};
static struct resource scif5_resources[] = {
DEFINE_RES_MEM(0xffef0000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x8a0)),
};
static struct platform_device scif5_device = {
.name = "sh-sci",
.id = 5,
.resource = scif5_resources,
.num_resources = ARRAY_SIZE(scif5_resources),
.dev = {
.platform_data = &scif5_platform_data,
},
};
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffd80000, 0x30),
DEFINE_RES_IRQ(evt2irq(0x400)),
DEFINE_RES_IRQ(evt2irq(0x420)),
DEFINE_RES_IRQ(evt2irq(0x440)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct sh_timer_config tmu1_platform_data = {
.channels_mask = 7,
};
static struct resource tmu1_resources[] = {
DEFINE_RES_MEM(0xffda0000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0x480)),
DEFINE_RES_IRQ(evt2irq(0x4a0)),
DEFINE_RES_IRQ(evt2irq(0x4c0)),
};
static struct platform_device tmu1_device = {
.name = "sh-tmu",
.id = 1,
.dev = {
.platform_data = &tmu1_platform_data,
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
};
static struct sh_timer_config tmu2_platform_data = {
.channels_mask = 7,
};
static struct resource tmu2_resources[] = {
DEFINE_RES_MEM(0xffdc0000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0x7a0)),
DEFINE_RES_IRQ(evt2irq(0x7a0)),
DEFINE_RES_IRQ(evt2irq(0x7a0)),
};
static struct platform_device tmu2_device = {
.name = "sh-tmu",
.id = 2,
.dev = {
.platform_data = &tmu2_platform_data,
},
.resource = tmu2_resources,
.num_resources = ARRAY_SIZE(tmu2_resources),
};
static struct sh_timer_config tmu3_platform_data = {
.channels_mask = 7,
};
static struct resource tmu3_resources[] = {
DEFINE_RES_MEM(0xffde0000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0x7c0)),
DEFINE_RES_IRQ(evt2irq(0x7c0)),
DEFINE_RES_IRQ(evt2irq(0x7c0)),
};
static struct platform_device tmu3_device = {
.name = "sh-tmu",
.id = 3,
.dev = {
.platform_data = &tmu3_platform_data,
},
.resource = tmu3_resources,
.num_resources = ARRAY_SIZE(tmu3_resources),
};
static const struct sh_dmae_channel dmac0_channels[] = {
{
.offset = 0,
.dmars = 0,
.dmars_bit = 0,
}, {
.offset = 0x10,
.dmars = 0,
.dmars_bit = 8,
}, {
.offset = 0x20,
.dmars = 4,
.dmars_bit = 0,
}, {
.offset = 0x30,
.dmars = 4,
.dmars_bit = 8,
}, {
.offset = 0x50,
.dmars = 8,
.dmars_bit = 0,
}, {
.offset = 0x60,
.dmars = 8,
.dmars_bit = 8,
}
};
static const unsigned int ts_shift[] = TS_SHIFT;
static struct sh_dmae_pdata dma0_platform_data = {
.channel = dmac0_channels,
.channel_num = ARRAY_SIZE(dmac0_channels),
.ts_low_shift = CHCR_TS_LOW_SHIFT,
.ts_low_mask = CHCR_TS_LOW_MASK,
.ts_high_shift = CHCR_TS_HIGH_SHIFT,
.ts_high_mask = CHCR_TS_HIGH_MASK,
.ts_shift = ts_shift,
.ts_shift_num = ARRAY_SIZE(ts_shift),
.dmaor_init = DMAOR_INIT,
};
/* Resource order important! */
static struct resource dmac0_resources[] = {
{
/* Channel registers and DMAOR */
.start = 0xfe008020,
.end = 0xfe00808f,
.flags = IORESOURCE_MEM,
}, {
/* DMARSx */
.start = 0xfe009000,
.end = 0xfe00900b,
.flags = IORESOURCE_MEM,
}, {
.name = "error_irq",
.start = evt2irq(0x5c0),
.end = evt2irq(0x5c0),
.flags = IORESOURCE_IRQ,
}, {
/* IRQ for channels 0-5 */
.start = evt2irq(0x500),
.end = evt2irq(0x5a0),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dma0_device = {
.name = "sh-dma-engine",
.id = 0,
.resource = dmac0_resources,
.num_resources = ARRAY_SIZE(dmac0_resources),
.dev = {
.platform_data = &dma0_platform_data,
},
};
#define USB_EHCI_START 0xffe70000
#define USB_OHCI_START 0xffe70400
static struct resource usb_ehci_resources[] = {
[0] = {
.start = USB_EHCI_START,
.end = USB_EHCI_START + 0x3ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xba0),
.end = evt2irq(0xba0),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device usb_ehci_device = {
.name = "sh_ehci",
.id = -1,
.dev = {
.dma_mask = &usb_ehci_device.dev.coherent_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(usb_ehci_resources),
.resource = usb_ehci_resources,
};
static struct resource usb_ohci_resources[] = {
[0] = {
.start = USB_OHCI_START,
.end = USB_OHCI_START + 0x3ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0xba0),
.end = evt2irq(0xba0),
.flags = IORESOURCE_IRQ,
},
};
static struct usb_ohci_pdata usb_ohci_pdata;
static struct platform_device usb_ohci_device = {
.name = "ohci-platform",
.id = -1,
.dev = {
.dma_mask = &usb_ohci_device.dev.coherent_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &usb_ohci_pdata,
},
.num_resources = ARRAY_SIZE(usb_ohci_resources),
.resource = usb_ohci_resources,
};
static struct platform_device *sh7786_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&tmu0_device,
&tmu1_device,
&tmu2_device,
};
static struct platform_device *sh7786_devices[] __initdata = {
&dma0_device,
&usb_ehci_device,
&usb_ohci_device,
};
/*
* Please call this function if your platform board
* use external clock for USB
* */
#define USBCTL0 0xffe70858
#define CLOCK_MODE_MASK 0xffffff7f
#define EXT_CLOCK_MODE 0x00000080
void __init sh7786_usb_use_exclock(void)
{
u32 val = __raw_readl(USBCTL0) & CLOCK_MODE_MASK;
__raw_writel(val | EXT_CLOCK_MODE, USBCTL0);
}
#define USBINITREG1 0xffe70094
#define USBINITREG2 0xffe7009c
#define USBINITVAL1 0x00ff0040
#define USBINITVAL2 0x00000001
#define USBPCTL1 0xffe70804
#define USBST 0xffe70808
#define PHY_ENB 0x00000001
#define PLL_ENB 0x00000002
#define PHY_RST 0x00000004
#define ACT_PLL_STATUS 0xc0000000
static void __init sh7786_usb_setup(void)
{
int i = 1000000;
/*
* USB initial settings
*
* The following settings are necessary
* for using the USB modules.
*
* see "USB Initial Settings" for detail
*/
__raw_writel(USBINITVAL1, USBINITREG1);
__raw_writel(USBINITVAL2, USBINITREG2);
/*
* Set the PHY and PLL enable bit
*/
__raw_writel(PHY_ENB | PLL_ENB, USBPCTL1);
while (i--) {
if (ACT_PLL_STATUS == (__raw_readl(USBST) & ACT_PLL_STATUS)) {
/* Set the PHY RST bit */
__raw_writel(PHY_ENB | PLL_ENB | PHY_RST, USBPCTL1);
printk(KERN_INFO "sh7786 usb setup done\n");
break;
}
cpu_relax();
}
}
enum {
UNUSED = 0,
/* interrupt sources */
IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
IRL0_HHLL, IRL0_HHLH, IRL0_HHHL,
IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
WDT,
TMU0_0, TMU0_1, TMU0_2, TMU0_3,
TMU1_0, TMU1_1, TMU1_2,
DMAC0_0, DMAC0_1, DMAC0_2, DMAC0_3, DMAC0_4, DMAC0_5, DMAC0_6,
HUDI1, HUDI0,
DMAC1_0, DMAC1_1, DMAC1_2, DMAC1_3,
HPB_0, HPB_1, HPB_2,
SCIF0_0, SCIF0_1, SCIF0_2, SCIF0_3,
SCIF1,
TMU2, TMU3,
SCIF2, SCIF3, SCIF4, SCIF5,
Eth_0, Eth_1,
PCIeC0_0, PCIeC0_1, PCIeC0_2,
PCIeC1_0, PCIeC1_1, PCIeC1_2,
USB,
I2C0, I2C1,
DU,
SSI0, SSI1, SSI2, SSI3,
PCIeC2_0, PCIeC2_1, PCIeC2_2,
HAC0, HAC1,
FLCTL,
HSPI,
GPIO0, GPIO1,
Thermal,
INTICI0, INTICI1, INTICI2, INTICI3,
INTICI4, INTICI5, INTICI6, INTICI7,
/* Muxed sub-events */
TXI1, BRI1, RXI1, ERI1,
};
static struct intc_vect sh7786_vectors[] __initdata = {
INTC_VECT(WDT, 0x3e0),
INTC_VECT(TMU0_0, 0x400), INTC_VECT(TMU0_1, 0x420),
INTC_VECT(TMU0_2, 0x440), INTC_VECT(TMU0_3, 0x460),
INTC_VECT(TMU1_0, 0x480), INTC_VECT(TMU1_1, 0x4a0),
INTC_VECT(TMU1_2, 0x4c0),
INTC_VECT(DMAC0_0, 0x500), INTC_VECT(DMAC0_1, 0x520),
INTC_VECT(DMAC0_2, 0x540), INTC_VECT(DMAC0_3, 0x560),
INTC_VECT(DMAC0_4, 0x580), INTC_VECT(DMAC0_5, 0x5a0),
INTC_VECT(DMAC0_6, 0x5c0),
INTC_VECT(HUDI1, 0x5e0), INTC_VECT(HUDI0, 0x600),
INTC_VECT(DMAC1_0, 0x620), INTC_VECT(DMAC1_1, 0x640),
INTC_VECT(DMAC1_2, 0x660), INTC_VECT(DMAC1_3, 0x680),
INTC_VECT(HPB_0, 0x6a0), INTC_VECT(HPB_1, 0x6c0),
INTC_VECT(HPB_2, 0x6e0),
INTC_VECT(SCIF0_0, 0x700), INTC_VECT(SCIF0_1, 0x720),
INTC_VECT(SCIF0_2, 0x740), INTC_VECT(SCIF0_3, 0x760),
INTC_VECT(SCIF1, 0x780),
INTC_VECT(TMU2, 0x7a0), INTC_VECT(TMU3, 0x7c0),
INTC_VECT(SCIF2, 0x840), INTC_VECT(SCIF3, 0x860),
INTC_VECT(SCIF4, 0x880), INTC_VECT(SCIF5, 0x8a0),
INTC_VECT(Eth_0, 0x8c0), INTC_VECT(Eth_1, 0x8e0),
INTC_VECT(PCIeC0_0, 0xae0), INTC_VECT(PCIeC0_1, 0xb00),
INTC_VECT(PCIeC0_2, 0xb20),
INTC_VECT(PCIeC1_0, 0xb40), INTC_VECT(PCIeC1_1, 0xb60),
INTC_VECT(PCIeC1_2, 0xb80),
INTC_VECT(USB, 0xba0),
INTC_VECT(I2C0, 0xcc0), INTC_VECT(I2C1, 0xce0),
INTC_VECT(DU, 0xd00),
INTC_VECT(SSI0, 0xd20), INTC_VECT(SSI1, 0xd40),
INTC_VECT(SSI2, 0xd60), INTC_VECT(SSI3, 0xd80),
INTC_VECT(PCIeC2_0, 0xda0), INTC_VECT(PCIeC2_1, 0xdc0),
INTC_VECT(PCIeC2_2, 0xde0),
INTC_VECT(HAC0, 0xe00), INTC_VECT(HAC1, 0xe20),
INTC_VECT(FLCTL, 0xe40),
INTC_VECT(HSPI, 0xe80),
INTC_VECT(GPIO0, 0xea0), INTC_VECT(GPIO1, 0xec0),
INTC_VECT(Thermal, 0xee0),
INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
};
#define CnINTMSK0 0xfe410030
#define CnINTMSK1 0xfe410040
#define CnINTMSKCLR0 0xfe410050
#define CnINTMSKCLR1 0xfe410060
#define CnINT2MSKR0 0xfe410a20
#define CnINT2MSKR1 0xfe410a24
#define CnINT2MSKR2 0xfe410a28
#define CnINT2MSKR3 0xfe410a2c
#define CnINT2MSKCR0 0xfe410a30
#define CnINT2MSKCR1 0xfe410a34
#define CnINT2MSKCR2 0xfe410a38
#define CnINT2MSKCR3 0xfe410a3c
#define INTMSK2 0xfe410068
#define INTMSKCLR2 0xfe41006c
#define INTDISTCR0 0xfe4100b0
#define INTDISTCR1 0xfe4100b4
#define INT2DISTCR0 0xfe410900
#define INT2DISTCR1 0xfe410904
#define INT2DISTCR2 0xfe410908
#define INT2DISTCR3 0xfe41090c
static struct intc_mask_reg sh7786_mask_registers[] __initdata = {
{ CnINTMSK0, CnINTMSKCLR0, 32,
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 },
INTC_SMP_BALANCING(INTDISTCR0) },
{ INTMSK2, INTMSKCLR2, 32,
{ IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, 0,
IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } },
{ CnINT2MSKR0, CnINT2MSKCR0 , 32,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WDT },
INTC_SMP_BALANCING(INT2DISTCR0) },
{ CnINT2MSKR1, CnINT2MSKCR1, 32,
{ TMU0_0, TMU0_1, TMU0_2, TMU0_3, TMU1_0, TMU1_1, TMU1_2, 0,
DMAC0_0, DMAC0_1, DMAC0_2, DMAC0_3, DMAC0_4, DMAC0_5, DMAC0_6,
HUDI1, HUDI0,
DMAC1_0, DMAC1_1, DMAC1_2, DMAC1_3,
HPB_0, HPB_1, HPB_2,
SCIF0_0, SCIF0_1, SCIF0_2, SCIF0_3,
SCIF1,
TMU2, TMU3, 0, }, INTC_SMP_BALANCING(INT2DISTCR1) },
{ CnINT2MSKR2, CnINT2MSKCR2, 32,
{ 0, 0, SCIF2, SCIF3, SCIF4, SCIF5,
Eth_0, Eth_1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
PCIeC0_0, PCIeC0_1, PCIeC0_2,
PCIeC1_0, PCIeC1_1, PCIeC1_2,
USB, 0, 0 }, INTC_SMP_BALANCING(INT2DISTCR2) },
{ CnINT2MSKR3, CnINT2MSKCR3, 32,
{ 0, 0, 0, 0, 0, 0,
I2C0, I2C1,
DU, SSI0, SSI1, SSI2, SSI3,
PCIeC2_0, PCIeC2_1, PCIeC2_2,
HAC0, HAC1,
FLCTL, 0,
HSPI, GPIO0, GPIO1, Thermal,
0, 0, 0, 0, 0, 0, 0, 0 }, INTC_SMP_BALANCING(INT2DISTCR3) },
};
static struct intc_prio_reg sh7786_prio_registers[] __initdata = {
{ 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, IRQ6, IRQ7 } },
{ 0xfe410800, 0, 32, 8, /* INT2PRI0 */ { 0, 0, 0, WDT } },
{ 0xfe410804, 0, 32, 8, /* INT2PRI1 */ { TMU0_0, TMU0_1,
TMU0_2, TMU0_3 } },
{ 0xfe410808, 0, 32, 8, /* INT2PRI2 */ { TMU1_0, TMU1_1,
TMU1_2, 0 } },
{ 0xfe41080c, 0, 32, 8, /* INT2PRI3 */ { DMAC0_0, DMAC0_1,
DMAC0_2, DMAC0_3 } },
{ 0xfe410810, 0, 32, 8, /* INT2PRI4 */ { DMAC0_4, DMAC0_5,
DMAC0_6, HUDI1 } },
{ 0xfe410814, 0, 32, 8, /* INT2PRI5 */ { HUDI0, DMAC1_0,
DMAC1_1, DMAC1_2 } },
{ 0xfe410818, 0, 32, 8, /* INT2PRI6 */ { DMAC1_3, HPB_0,
HPB_1, HPB_2 } },
{ 0xfe41081c, 0, 32, 8, /* INT2PRI7 */ { SCIF0_0, SCIF0_1,
SCIF0_2, SCIF0_3 } },
{ 0xfe410820, 0, 32, 8, /* INT2PRI8 */ { SCIF1, TMU2, TMU3, 0 } },
{ 0xfe410824, 0, 32, 8, /* INT2PRI9 */ { 0, 0, SCIF2, SCIF3 } },
{ 0xfe410828, 0, 32, 8, /* INT2PRI10 */ { SCIF4, SCIF5,
Eth_0, Eth_1 } },
{ 0xfe41082c, 0, 32, 8, /* INT2PRI11 */ { 0, 0, 0, 0 } },
{ 0xfe410830, 0, 32, 8, /* INT2PRI12 */ { 0, 0, 0, 0 } },
{ 0xfe410834, 0, 32, 8, /* INT2PRI13 */ { 0, 0, 0, 0 } },
{ 0xfe410838, 0, 32, 8, /* INT2PRI14 */ { 0, 0, 0, PCIeC0_0 } },
{ 0xfe41083c, 0, 32, 8, /* INT2PRI15 */ { PCIeC0_1, PCIeC0_2,
PCIeC1_0, PCIeC1_1 } },
{ 0xfe410840, 0, 32, 8, /* INT2PRI16 */ { PCIeC1_2, USB, 0, 0 } },
{ 0xfe410844, 0, 32, 8, /* INT2PRI17 */ { 0, 0, 0, 0 } },
{ 0xfe410848, 0, 32, 8, /* INT2PRI18 */ { 0, 0, I2C0, I2C1 } },
{ 0xfe41084c, 0, 32, 8, /* INT2PRI19 */ { DU, SSI0, SSI1, SSI2 } },
{ 0xfe410850, 0, 32, 8, /* INT2PRI20 */ { SSI3, PCIeC2_0,
PCIeC2_1, PCIeC2_2 } },
{ 0xfe410854, 0, 32, 8, /* INT2PRI21 */ { HAC0, HAC1, FLCTL, 0 } },
{ 0xfe410858, 0, 32, 8, /* INT2PRI22 */ { HSPI, GPIO0,
GPIO1, Thermal } },
{ 0xfe41085c, 0, 32, 8, /* INT2PRI23 */ { 0, 0, 0, 0 } },
{ 0xfe410860, 0, 32, 8, /* INT2PRI24 */ { 0, 0, 0, 0 } },
{ 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
{ INTICI7, INTICI6, INTICI5, INTICI4,
INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 2) },
};
static struct intc_subgroup sh7786_subgroups[] __initdata = {
{ 0xfe410c20, 32, SCIF1,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TXI1, BRI1, RXI1, ERI1 } },
};
static struct intc_desc sh7786_intc_desc __initdata = {
.name = "sh7786",
.hw = {
.vectors = sh7786_vectors,
.nr_vectors = ARRAY_SIZE(sh7786_vectors),
.mask_regs = sh7786_mask_registers,
.nr_mask_regs = ARRAY_SIZE(sh7786_mask_registers),
.subgroups = sh7786_subgroups,
.nr_subgroups = ARRAY_SIZE(sh7786_subgroups),
.prio_regs = sh7786_prio_registers,
.nr_prio_regs = ARRAY_SIZE(sh7786_prio_registers),
},
};
/* Support for external interrupt pins in IRQ mode */
static struct intc_vect vectors_irq0123[] __initdata = {
INTC_VECT(IRQ0, 0x200), INTC_VECT(IRQ1, 0x240),
INTC_VECT(IRQ2, 0x280), INTC_VECT(IRQ3, 0x2c0),
};
static struct intc_vect vectors_irq4567[] __initdata = {
INTC_VECT(IRQ4, 0x300), INTC_VECT(IRQ5, 0x340),
INTC_VECT(IRQ6, 0x380), INTC_VECT(IRQ7, 0x3c0),
};
static struct intc_sense_reg sh7786_sense_registers[] __initdata = {
{ 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static struct intc_mask_reg sh7786_ack_registers[] __initdata = {
{ 0xfe410024, 0, 32, /* INTREQ */
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
};
static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh7786-irq0123",
vectors_irq0123, NULL, sh7786_mask_registers,
sh7786_prio_registers, sh7786_sense_registers,
sh7786_ack_registers);
static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7786-irq4567",
vectors_irq4567, NULL, sh7786_mask_registers,
sh7786_prio_registers, sh7786_sense_registers,
sh7786_ack_registers);
/* External interrupt pins in IRL mode */
static struct intc_vect vectors_irl0123[] __initdata = {
INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220),
INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260),
INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0),
INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0),
INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320),
INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360),
INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0),
INTC_VECT(IRL0_HHHL, 0x3c0),
};
static struct intc_vect vectors_irl4567[] __initdata = {
INTC_VECT(IRL4_LLLL, 0x900), INTC_VECT(IRL4_LLLH, 0x920),
INTC_VECT(IRL4_LLHL, 0x940), INTC_VECT(IRL4_LLHH, 0x960),
INTC_VECT(IRL4_LHLL, 0x980), INTC_VECT(IRL4_LHLH, 0x9a0),
INTC_VECT(IRL4_LHHL, 0x9c0), INTC_VECT(IRL4_LHHH, 0x9e0),
INTC_VECT(IRL4_HLLL, 0xa00), INTC_VECT(IRL4_HLLH, 0xa20),
INTC_VECT(IRL4_HLHL, 0xa40), INTC_VECT(IRL4_HLHH, 0xa60),
INTC_VECT(IRL4_HHLL, 0xa80), INTC_VECT(IRL4_HHLH, 0xaa0),
INTC_VECT(IRL4_HHHL, 0xac0),
};
static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7786-irl0123", vectors_irl0123,
NULL, sh7786_mask_registers, NULL, NULL);
static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567,
NULL, sh7786_mask_registers, NULL, NULL);
#define INTC_ICR0 0xfe410000
#define INTC_INTMSK0 CnINTMSK0
#define INTC_INTMSK1 CnINTMSK1
#define INTC_INTMSK2 INTMSK2
#define INTC_INTMSKCLR1 CnINTMSKCLR1
#define INTC_INTMSKCLR2 INTMSKCLR2
void __init plat_irq_setup(void)
{
/* disable IRQ3-0 + IRQ7-4 */
__raw_writel(0xff000000, INTC_INTMSK0);
/* disable IRL3-0 + IRL7-4 */
__raw_writel(0xc0000000, INTC_INTMSK1);
__raw_writel(0xfffefffe, INTC_INTMSK2);
/* select IRL mode for IRL3-0 + IRL7-4 */
__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
register_intc_controller(&sh7786_intc_desc);
}
void __init plat_irq_setup_pins(int mode)
{
switch (mode) {
case IRQ_MODE_IRQ7654:
/* select IRQ mode for IRL7-4 */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0);
register_intc_controller(&intc_desc_irq4567);
break;
case IRQ_MODE_IRQ3210:
/* select IRQ mode for IRL3-0 */
__raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0);
register_intc_controller(&intc_desc_irq0123);
break;
case IRQ_MODE_IRL7654:
/* enable IRL7-4 but don't provide any masking */
__raw_writel(0x40000000, INTC_INTMSKCLR1);
__raw_writel(0x0000fffe, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL3210:
/* enable IRL0-3 but don't provide any masking */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
__raw_writel(0xfffe0000, INTC_INTMSKCLR2);
break;
case IRQ_MODE_IRL7654_MASK:
/* enable IRL7-4 and mask using cpu intc controller */
__raw_writel(0x40000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_desc_irl4567);
break;
case IRQ_MODE_IRL3210_MASK:
/* enable IRL0-3 and mask using cpu intc controller */
__raw_writel(0x80000000, INTC_INTMSKCLR1);
register_intc_controller(&intc_desc_irl0123);
break;
default:
BUG();
}
}
void __init plat_mem_setup(void)
{
}
static int __init sh7786_devices_setup(void)
{
int ret, irq;
sh7786_usb_setup();
/*
* De-mux SCIF1 IRQs if possible
*/
irq = intc_irq_lookup(sh7786_intc_desc.name, TXI1);
if (irq > 0) {
scif1_demux_resources[1].start =
intc_irq_lookup(sh7786_intc_desc.name, ERI1);
scif1_demux_resources[2].start =
intc_irq_lookup(sh7786_intc_desc.name, RXI1);
scif1_demux_resources[3].start = irq;
scif1_demux_resources[4].start =
intc_irq_lookup(sh7786_intc_desc.name, BRI1);
scif1_device.resource = scif1_demux_resources;
scif1_device.num_resources = ARRAY_SIZE(scif1_demux_resources);
}
ret = platform_add_devices(sh7786_early_devices,
ARRAY_SIZE(sh7786_early_devices));
if (unlikely(ret != 0))
return ret;
return platform_add_devices(sh7786_devices,
ARRAY_SIZE(sh7786_devices));
}
arch_initcall(sh7786_devices_setup);
void __init plat_early_device_setup(void)
{
early_platform_add_devices(sh7786_early_devices,
ARRAY_SIZE(sh7786_early_devices));
}

View file

@ -0,0 +1,401 @@
/*
* SH-X3 Prototype Setup
*
* Copyright (C) 2007 - 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/sh_timer.h>
#include <linux/sh_intc.h>
#include <cpu/shx3.h>
#include <asm/mmzone.h>
/*
* This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2
* INTEVT values overlap with the FPU EXPEVT ones, requiring special
* demuxing in the exception dispatch path.
*
* As this overlap is something that never should have made it in to
* silicon in the first place, we just refuse to deal with the port at
* all rather than adding infrastructure to hack around it.
*/
static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
};
static struct resource scif0_resources[] = {
DEFINE_RES_MEM(0xffc30000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x700)),
DEFINE_RES_IRQ(evt2irq(0x720)),
DEFINE_RES_IRQ(evt2irq(0x760)),
DEFINE_RES_IRQ(evt2irq(0x740)),
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.resource = scif0_resources,
.num_resources = ARRAY_SIZE(scif0_resources),
.dev = {
.platform_data = &scif0_platform_data,
},
};
static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
};
static struct resource scif1_resources[] = {
DEFINE_RES_MEM(0xffc40000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x780)),
DEFINE_RES_IRQ(evt2irq(0x7a0)),
DEFINE_RES_IRQ(evt2irq(0x7e0)),
DEFINE_RES_IRQ(evt2irq(0x7c0)),
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.resource = scif1_resources,
.num_resources = ARRAY_SIZE(scif1_resources),
.dev = {
.platform_data = &scif1_platform_data,
},
};
static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
.type = PORT_SCIF,
};
static struct resource scif2_resources[] = {
DEFINE_RES_MEM(0xffc60000, 0x100),
DEFINE_RES_IRQ(evt2irq(0x880)),
DEFINE_RES_IRQ(evt2irq(0x8a0)),
DEFINE_RES_IRQ(evt2irq(0x8e0)),
DEFINE_RES_IRQ(evt2irq(0x8c0)),
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.resource = scif2_resources,
.num_resources = ARRAY_SIZE(scif2_resources),
.dev = {
.platform_data = &scif2_platform_data,
},
};
static struct sh_timer_config tmu0_platform_data = {
.channels_mask = 7,
};
static struct resource tmu0_resources[] = {
DEFINE_RES_MEM(0xffc10000, 0x30),
DEFINE_RES_IRQ(evt2irq(0x400)),
DEFINE_RES_IRQ(evt2irq(0x420)),
DEFINE_RES_IRQ(evt2irq(0x440)),
};
static struct platform_device tmu0_device = {
.name = "sh-tmu",
.id = 0,
.dev = {
.platform_data = &tmu0_platform_data,
},
.resource = tmu0_resources,
.num_resources = ARRAY_SIZE(tmu0_resources),
};
static struct sh_timer_config tmu1_platform_data = {
.channels_mask = 7,
};
static struct resource tmu1_resources[] = {
DEFINE_RES_MEM(0xffc20000, 0x2c),
DEFINE_RES_IRQ(evt2irq(0x460)),
DEFINE_RES_IRQ(evt2irq(0x480)),
DEFINE_RES_IRQ(evt2irq(0x4a0)),
};
static struct platform_device tmu1_device = {
.name = "sh-tmu",
.id = 1,
.dev = {
.platform_data = &tmu1_platform_data,
},
.resource = tmu1_resources,
.num_resources = ARRAY_SIZE(tmu1_resources),
};
static struct platform_device *shx3_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&tmu0_device,
&tmu1_device,
};
static int __init shx3_devices_setup(void)
{
return platform_add_devices(shx3_early_devices,
ARRAY_SIZE(shx3_early_devices));
}
arch_initcall(shx3_devices_setup);
void __init plat_early_device_setup(void)
{
early_platform_add_devices(shx3_early_devices,
ARRAY_SIZE(shx3_early_devices));
}
enum {
UNUSED = 0,
/* interrupt sources */
IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3,
HUDII,
TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
PCII0, PCII1, PCII2, PCII3, PCII4,
PCII5, PCII6, PCII7, PCII8, PCII9,
SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI,
DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
DU,
DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
IIC, VIN0, VIN1, VCORE0, ATAPI,
DTU0, DTU1, DTU2, DTU3,
FE0, FE1,
GPIO0, GPIO1, GPIO2, GPIO3,
PAM, IRM,
INTICI0, INTICI1, INTICI2, INTICI3,
INTICI4, INTICI5, INTICI6, INTICI7,
/* interrupt groups */
IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
DMAC0, DMAC1,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(HUDII, 0x3e0),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460),
INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0),
INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520),
INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560),
INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0),
INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0),
INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620),
INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960),
INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0),
INTC_VECT(DMAC0_DMAE, 0x9c0),
INTC_VECT(DU, 0x9e0),
INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20),
INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60),
INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0),
INTC_VECT(DMAC1_DMAE, 0xac0),
INTC_VECT(IIC, 0xae0),
INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
INTC_VECT(DTU0, 0xc00), INTC_VECT(DTU0, 0xc20),
INTC_VECT(DTU0, 0xc40),
INTC_VECT(DTU1, 0xc60), INTC_VECT(DTU1, 0xc80),
INTC_VECT(DTU1, 0xca0),
INTC_VECT(DTU2, 0xcc0), INTC_VECT(DTU2, 0xce0),
INTC_VECT(DTU2, 0xd00),
INTC_VECT(DTU3, 0xd20), INTC_VECT(DTU3, 0xd40),
INTC_VECT(DTU3, 0xd60),
INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0),
INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
IRL_HHLL, IRL_HHLH, IRL_HHHL),
INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
};
#define INT2DISTCR0 0xfe4108a0
#define INT2DISTCR1 0xfe4108a4
#define INT2DISTCR2 0xfe4108a8
static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
{ IRQ0, IRQ1, IRQ2, IRQ3 } },
{ 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */
{ IRL } },
{ 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */
{ FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, },
INTC_SMP_BALANCING(INT2DISTCR0) },
{ 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
{ 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 },
INTC_SMP_BALANCING(INT2DISTCR1) },
{ 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI },
INTC_SMP_BALANCING(INT2DISTCR2) },
};
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
{ 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4,
TMU3, TMU2, TMU1, TMU0 } },
{ 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0,
SCIF3, SCIF2,
SCIF1, SCIF0 } },
{ 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0,
PCII56789, PCII4,
PCII3, PCII2,
PCII1, PCII0 } },
{ 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0,
VIN1, VIN0, IIC, DU} },
{ 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3,
GPIO2, GPIO1, GPIO0, IRM } },
{ 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
{ INTICI7, INTICI6, INTICI5, INTICI4,
INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) },
};
static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups,
mask_registers, prio_registers, NULL);
/* Support for external interrupt pins in IRQ mode */
static struct intc_vect vectors_irq[] __initdata = {
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
};
static struct intc_sense_reg sense_registers[] __initdata = {
{ 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
};
static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
mask_registers, prio_registers, sense_registers);
/* External interrupt pins in IRL mode */
static struct intc_vect vectors_irl[] __initdata = {
INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
INTC_VECT(IRL_HHHL, 0x3c0),
};
static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
mask_registers, prio_registers, NULL);
void __init plat_irq_setup_pins(int mode)
{
int ret = 0;
switch (mode) {
case IRQ_MODE_IRQ:
ret |= gpio_request(GPIO_FN_IRQ3, intc_desc_irq.name);
ret |= gpio_request(GPIO_FN_IRQ2, intc_desc_irq.name);
ret |= gpio_request(GPIO_FN_IRQ1, intc_desc_irq.name);
ret |= gpio_request(GPIO_FN_IRQ0, intc_desc_irq.name);
if (unlikely(ret)) {
pr_err("Failed to set IRQ mode\n");
return;
}
register_intc_controller(&intc_desc_irq);
break;
case IRQ_MODE_IRL3210:
ret |= gpio_request(GPIO_FN_IRL3, intc_desc_irl.name);
ret |= gpio_request(GPIO_FN_IRL2, intc_desc_irl.name);
ret |= gpio_request(GPIO_FN_IRL1, intc_desc_irl.name);
ret |= gpio_request(GPIO_FN_IRL0, intc_desc_irl.name);
if (unlikely(ret)) {
pr_err("Failed to set IRL mode\n");
return;
}
register_intc_controller(&intc_desc_irl);
break;
default:
BUG();
}
}
void __init plat_irq_setup(void)
{
register_intc_controller(&intc_desc);
}
void __init plat_mem_setup(void)
{
unsigned int nid = 1;
/* Register CPU#0 URAM space as Node 1 */
setup_bootmem_node(nid++, 0x145f0000, 0x14610000); /* CPU0 */
#if 0
/* XXX: Not yet.. */
setup_bootmem_node(nid++, 0x14df0000, 0x14e10000); /* CPU1 */
setup_bootmem_node(nid++, 0x155f0000, 0x15610000); /* CPU2 */
setup_bootmem_node(nid++, 0x15df0000, 0x15e10000); /* CPU3 */
#endif
setup_bootmem_node(nid++, 0x16000000, 0x16020000); /* CSM */
}

View file

@ -0,0 +1,166 @@
/*
* SH-X3 SMP
*
* Copyright (C) 2007 - 2010 Paul Mundt
* Copyright (C) 2007 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/cpumask.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/cpu.h>
#include <asm/sections.h>
#define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12))
#define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12))
#define STBCR_MSTP 0x00000001
#define STBCR_RESET 0x00000002
#define STBCR_SLEEP 0x00000004
#define STBCR_LTSLP 0x80000000
static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
{
unsigned int message = (unsigned int)(long)arg;
unsigned int cpu = hard_smp_processor_id();
unsigned int offs = 4 * cpu;
unsigned int x;
x = __raw_readl(0xfe410070 + offs); /* C0INITICI..CnINTICI */
x &= (1 << (message << 2));
__raw_writel(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */
smp_message_recv(message);
return IRQ_HANDLED;
}
static void shx3_smp_setup(void)
{
unsigned int cpu = 0;
int i, num;
init_cpu_possible(cpumask_of(cpu));
/* Enable light sleep for the boot CPU */
__raw_writel(__raw_readl(STBCR_REG(cpu)) | STBCR_LTSLP, STBCR_REG(cpu));
__cpu_number_map[0] = 0;
__cpu_logical_map[0] = 0;
/*
* Do this stupidly for now.. we don't have an easy way to probe
* for the total number of cores.
*/
for (i = 1, num = 0; i < NR_CPUS; i++) {
set_cpu_possible(i, true);
__cpu_number_map[i] = ++num;
__cpu_logical_map[num] = i;
}
printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
}
static void shx3_prepare_cpus(unsigned int max_cpus)
{
int i;
local_timer_setup(0);
BUILD_BUG_ON(SMP_MSG_NR >= 8);
for (i = 0; i < SMP_MSG_NR; i++)
request_irq(104 + i, ipi_interrupt_handler,
IRQF_PERCPU, "IPI", (void *)(long)i);
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
}
static void shx3_start_cpu(unsigned int cpu, unsigned long entry_point)
{
if (__in_29bit_mode())
__raw_writel(entry_point, RESET_REG(cpu));
else
__raw_writel(virt_to_phys(entry_point), RESET_REG(cpu));
if (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
__raw_writel(STBCR_MSTP, STBCR_REG(cpu));
while (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
cpu_relax();
/* Start up secondary processor by sending a reset */
__raw_writel(STBCR_RESET | STBCR_LTSLP, STBCR_REG(cpu));
}
static unsigned int shx3_smp_processor_id(void)
{
return __raw_readl(0xff000048); /* CPIDR */
}
static void shx3_send_ipi(unsigned int cpu, unsigned int message)
{
unsigned long addr = 0xfe410070 + (cpu * 4);
BUG_ON(cpu >= 4);
__raw_writel(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
}
static void shx3_update_boot_vector(unsigned int cpu)
{
__raw_writel(STBCR_MSTP, STBCR_REG(cpu));
while (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
cpu_relax();
__raw_writel(STBCR_RESET, STBCR_REG(cpu));
}
static int
shx3_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned int)hcpu;
switch (action) {
case CPU_UP_PREPARE:
shx3_update_boot_vector(cpu);
break;
case CPU_ONLINE:
pr_info("CPU %u is now online\n", cpu);
break;
case CPU_DEAD:
break;
}
return NOTIFY_OK;
}
static struct notifier_block shx3_cpu_notifier = {
.notifier_call = shx3_cpu_callback,
};
static int register_shx3_cpu_notifier(void)
{
register_hotcpu_notifier(&shx3_cpu_notifier);
return 0;
}
late_initcall(register_shx3_cpu_notifier);
struct plat_smp_ops shx3_smp_ops = {
.smp_setup = shx3_smp_setup,
.prepare_cpus = shx3_prepare_cpus,
.start_cpu = shx3_start_cpu,
.smp_processor_id = shx3_smp_processor_id,
.send_ipi = shx3_send_ipi,
.cpu_die = native_cpu_die,
.cpu_disable = native_cpu_disable,
.play_dead = native_play_dead,
};

View file

@ -0,0 +1,133 @@
/*
* arch/sh/kernel/cpu/sh4a/ubc.c
*
* On-chip UBC support for SH-4A CPUs.
*
* Copyright (C) 2009 - 2010 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <asm/hw_breakpoint.h>
#define UBC_CBR(idx) (0xff200000 + (0x20 * idx))
#define UBC_CRR(idx) (0xff200004 + (0x20 * idx))
#define UBC_CAR(idx) (0xff200008 + (0x20 * idx))
#define UBC_CAMR(idx) (0xff20000c + (0x20 * idx))
#define UBC_CCMFR 0xff200600
#define UBC_CBCR 0xff200620
/* CRR */
#define UBC_CRR_PCB (1 << 1)
#define UBC_CRR_BIE (1 << 0)
/* CBR */
#define UBC_CBR_CE (1 << 0)
static struct sh_ubc sh4a_ubc;
static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx)
{
__raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx));
__raw_writel(info->address, UBC_CAR(idx));
}
static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx)
{
__raw_writel(0, UBC_CBR(idx));
__raw_writel(0, UBC_CAR(idx));
}
static void sh4a_ubc_enable_all(unsigned long mask)
{
int i;
for (i = 0; i < sh4a_ubc.num_events; i++)
if (mask & (1 << i))
__raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE,
UBC_CBR(i));
}
static void sh4a_ubc_disable_all(void)
{
int i;
for (i = 0; i < sh4a_ubc.num_events; i++)
__raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE,
UBC_CBR(i));
}
static unsigned long sh4a_ubc_active_mask(void)
{
unsigned long active = 0;
int i;
for (i = 0; i < sh4a_ubc.num_events; i++)
if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE)
active |= (1 << i);
return active;
}
static unsigned long sh4a_ubc_triggered_mask(void)
{
return __raw_readl(UBC_CCMFR);
}
static void sh4a_ubc_clear_triggered_mask(unsigned long mask)
{
__raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR);
}
static struct sh_ubc sh4a_ubc = {
.name = "SH-4A",
.num_events = 2,
.trap_nr = 0x1e0,
.enable = sh4a_ubc_enable,
.disable = sh4a_ubc_disable,
.enable_all = sh4a_ubc_enable_all,
.disable_all = sh4a_ubc_disable_all,
.active_mask = sh4a_ubc_active_mask,
.triggered_mask = sh4a_ubc_triggered_mask,
.clear_triggered_mask = sh4a_ubc_clear_triggered_mask,
};
static int __init sh4a_ubc_init(void)
{
struct clk *ubc_iclk = clk_get(NULL, "ubc0");
int i;
/*
* The UBC MSTP bit is optional, as not all platforms will have
* it. Just ignore it if we can't find it.
*/
if (IS_ERR(ubc_iclk))
ubc_iclk = NULL;
clk_enable(ubc_iclk);
__raw_writel(0, UBC_CBCR);
for (i = 0; i < sh4a_ubc.num_events; i++) {
__raw_writel(0, UBC_CAMR(i));
__raw_writel(0, UBC_CBR(i));
__raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR(i));
/* dummy read for write posting */
(void)__raw_readl(UBC_CRR(i));
}
clk_disable(ubc_iclk);
sh4a_ubc.clk = ubc_iclk;
return register_sh_ubc(&sh4a_ubc);
}
arch_initcall(sh4a_ubc_init);