diff options
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r-- | arch/arm/mach-shmobile/Kconfig | 13 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/Makefile | 6 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 248 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-g3evm.c | 56 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-g4evm.c | 151 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7367.c | 357 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7372.c | 395 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7377.c | 369 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock.c | 44 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/common.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/irqs.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/memory.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/vmalloc.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/intc-sh7367.c | 178 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/intc-sh7372.c | 232 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/intc-sh7377.c | 300 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-sh7367.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-sh7372.c | 98 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-sh7377.c | 34 |
19 files changed, 2398 insertions, 135 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index f2b88c5fe142..1de8d171c6e9 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -7,6 +7,7 @@ config ARCH_SH7367 select CPU_V6 select HAVE_CLK select COMMON_CLKDEV + select SH_CLK_CPG select GENERIC_CLOCKEVENTS config ARCH_SH7377 @@ -14,6 +15,7 @@ config ARCH_SH7377 select CPU_V7 select HAVE_CLK select COMMON_CLKDEV + select SH_CLK_CPG select GENERIC_CLOCKEVENTS config ARCH_SH7372 @@ -21,6 +23,7 @@ config ARCH_SH7372 select CPU_V7 select HAVE_CLK select COMMON_CLKDEV + select SH_CLK_CPG select GENERIC_CLOCKEVENTS comment "SH-Mobile Board Type" @@ -39,6 +42,7 @@ config MACH_AP4EVB bool "AP4EVB board" depends on ARCH_SH7372 select ARCH_REQUIRE_GPIOLIB + select SH_LCD_MIPI_DSI comment "SH-Mobile System Configuration" @@ -76,6 +80,15 @@ config SH_TIMER_CMT help This enables build of the CMT timer driver. +config SH_TIMER_TMU + bool "TMU timer driver" + default y + help + This enables build of the TMU timer driver. + endmenu +config SH_CLK_CPG + bool + endif diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 6d385d371c33..5e16b4c69222 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -3,12 +3,12 @@ # # Common objects -obj-y := timer.o console.o +obj-y := timer.o console.o clock.o # CPU objects obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o -obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7367.o intc-sh7377.o -obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7367.o intc-sh7372.o +obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o +obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o # Pinmux setup pfc-$(CONFIG_ARCH_SH7367) := pfc-sh7367.o diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 1c2ec96ce261..353ff8d120b1 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <linux/clk.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/interrupt.h> @@ -26,16 +27,26 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> +#include <linux/i2c.h> +#include <linux/i2c/tsc2007.h> #include <linux/io.h> #include <linux/smsc911x.h> #include <linux/gpio.h> #include <linux/input.h> #include <linux/input/sh_keysc.h> +#include <linux/usb/r8a66597.h> + +#include <video/sh_mobile_lcdc.h> +#include <video/sh_mipi_dsi.h> + #include <mach/common.h> +#include <mach/irqs.h> #include <mach/sh7372.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/mach/time.h> /* * Address Interface BusWidth note @@ -80,12 +91,25 @@ */ /* - * KEYSC + * LCD / IRQ / KEYSC / IrDA + * + * IRQ = IRQ26 (TS), IRQ27 (VIO), IRQ28 (TouchScreen) + * LCD = 2nd LCDC + * + * | SW43 | + * SW3 | ON | OFF | + * -------------+-----------------------+---------------+ + * ON | KEY / IrDA | LCD | + * OFF | KEY / IrDA / IRQ | IRQ | + */ + +/* + * USB * - * SW43 KEYSC - * ------------------------- - * ON enable - * OFF disable + * J7 : 1-2 MAX3355E VBUS + * 2-3 DC 5.0V + * + * S39: bit2: off */ /* MTD */ @@ -148,7 +172,7 @@ static struct resource smc911x_resources[] = { .end = 0x16000000 - 1, .flags = IORESOURCE_MEM, }, { - .start = 6, + .start = evt2irq(0x02c0) /* IRQ6A */, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, }, }; @@ -191,7 +215,7 @@ static struct resource keysc_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 79, + .start = evt2irq(0x0be0), /* KEYSC_KEY */ .flags = IORESOURCE_IRQ, }, }; @@ -215,7 +239,7 @@ static struct resource sdhi0_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 96, + .start = evt2irq(0x0e00) /* SDHI0 */, .flags = IORESOURCE_IRQ, }, }; @@ -227,11 +251,147 @@ static struct platform_device sdhi0_device = { .id = 0, }; +/* USB1 */ +void usb1_host_port_power(int port, int power) +{ + if (!power) /* only power-on supported for now */ + return; + + /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */ + __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008); +} + +static struct r8a66597_platdata usb1_host_data = { + .on_chip = 1, + .port_power = usb1_host_port_power, +}; + +static struct resource usb1_host_resources[] = { + [0] = { + .name = "USBHS", + .start = 0xE68B0000, + .end = 0xE68B00E6 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x1ce0) /* USB1_USB1I0 */, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device usb1_host_device = { + .name = "r8a66597_hcd", + .id = 1, + .dev = { + .dma_mask = NULL, /* not use dma */ + .coherent_dma_mask = 0xffffffff, + .platform_data = &usb1_host_data, + }, + .num_resources = ARRAY_SIZE(usb1_host_resources), + .resource = usb1_host_resources, +}; + +static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = { + .clock_source = LCDC_CLK_PERIPHERAL, /* One of interface clocks */ + .ch[0] = { + .chan = LCDC_CHAN_MAINLCD, + .bpp = 16, + .interface_type = RGB24, + .clock_divider = 1, + .flags = LCDC_FLAGS_DWPOL, + .lcd_cfg = { + .name = "R63302(QHD)", + .xres = 544, + .yres = 961, + .left_margin = 72, + .right_margin = 600, + .hsync_len = 16, + .upper_margin = 8, + .lower_margin = 8, + .vsync_len = 2, + .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, + }, + .lcd_size_cfg = { + .width = 44, + .height = 79, + }, + } +}; + +static struct resource lcdc_resources[] = { + [0] = { + .name = "LCDC", + .start = 0xfe940000, /* P4-only space */ + .end = 0xfe943fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = intcs_evt2irq(0x580), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device lcdc_device = { + .name = "sh_mobile_lcdc_fb", + .num_resources = ARRAY_SIZE(lcdc_resources), + .resource = lcdc_resources, + .dev = { + .platform_data = &sh_mobile_lcdc_info, + .coherent_dma_mask = ~0, + }, +}; + +static struct resource mipidsi0_resources[] = { + [0] = { + .start = 0xffc60000, + .end = 0xffc68fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct sh_mipi_dsi_info mipidsi0_info = { + .data_format = MIPI_RGB888, + .lcd_chan = &sh_mobile_lcdc_info.ch[0], +}; + +static struct platform_device mipidsi0_device = { + .name = "sh-mipi-dsi", + .num_resources = ARRAY_SIZE(mipidsi0_resources), + .resource = mipidsi0_resources, + .id = 0, + .dev = { + .platform_data = &mipidsi0_info, + }, +}; + static struct platform_device *ap4evb_devices[] __initdata = { &nor_flash_device, &smc911x_device, &keysc_device, &sdhi0_device, + &usb1_host_device, + &lcdc_device, + &mipidsi0_device, +}; + +/* TouchScreen (Needs SW3 set to OFF) */ +#define IRQ28 evt2irq(0x3380) /* IRQ28A */ +struct tsc2007_platform_data tsc2007_info = { + .model = 2007, + .x_plate_ohms = 180, +}; + +/* I2C */ +static struct i2c_board_info i2c1_devices[] = { + { + I2C_BOARD_INFO("r2025sd", 0x32), + }, + { + I2C_BOARD_INFO("tsc2007", 0x48), + .type = "tsc2007", + .platform_data = &tsc2007_info, + .irq = IRQ28, + }, }; static struct map_desc ap4evb_io_desc[] __initdata = { @@ -250,12 +410,50 @@ static void __init ap4evb_map_io(void) { iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc)); - /* setup early devices, clocks and console here as well */ + /* setup early devices and console here as well */ sh7372_add_early_devices(); - sh7367_clock_init(); /* use g3 clocks for now */ shmobile_setup_console(); } +/* This function will disappear when we switch to (runtime) PM */ +static int __init ap4evb_init_display_clk(void) +{ + struct clk *lcdc_clk; + struct clk *dsitx_clk; + int ret; + + lcdc_clk = clk_get(&lcdc_device.dev, "sh_mobile_lcdc_fb.0"); + if (IS_ERR(lcdc_clk)) + return PTR_ERR(lcdc_clk); + + dsitx_clk = clk_get(&mipidsi0_device.dev, "sh-mipi-dsi.0"); + if (IS_ERR(dsitx_clk)) { + ret = PTR_ERR(dsitx_clk); + goto eclkdsitxget; + } + + ret = clk_enable(lcdc_clk); + if (ret < 0) + goto eclklcdcon; + + ret = clk_enable(dsitx_clk); + if (ret < 0) + goto eclkdsitxon; + + return 0; + +eclkdsitxon: + clk_disable(lcdc_clk); +eclklcdcon: + clk_put(dsitx_clk); +eclkdsitxget: + clk_put(lcdc_clk); + + return ret; +} + +device_initcall(ap4evb_init_display_clk); + static void __init ap4evb_init(void) { sh7372_pinmux_init(); @@ -318,16 +516,44 @@ static void __init ap4evb_init(void) gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL); + /* enable TouchScreen */ + gpio_request(GPIO_FN_IRQ28_123, NULL); + set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW); + + i2c_register_board_info(1, i2c1_devices, + ARRAY_SIZE(i2c1_devices)); + + /* USB enable */ + gpio_request(GPIO_FN_VBUS0_1, NULL); + gpio_request(GPIO_FN_IDIN_1_18, NULL); + gpio_request(GPIO_FN_PWEN_1_115, NULL); + gpio_request(GPIO_FN_OVCN_1_114, NULL); + gpio_request(GPIO_FN_EXTLP_1, NULL); + gpio_request(GPIO_FN_OVCN2_1, NULL); + + /* setup USB phy */ + __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */ + sh7372_add_standard_devices(); platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); } +static void __init ap4evb_timer_init(void) +{ + sh7372_clock_init(); + shmobile_timer.init(); +} + +static struct sys_timer ap4evb_timer = { + .init = ap4evb_timer_init, +}; + MACHINE_START(AP4EVB, "ap4evb") .phys_io = 0xe6000000, .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, .map_io = ap4evb_map_io, .init_irq = sh7372_init_irq, .init_machine = ap4evb_init, - .timer = &shmobile_timer, + .timer = &ap4evb_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c index 9247503296c4..a8f20cb0b7d2 100644 --- a/arch/arm/mach-shmobile/board-g3evm.c +++ b/arch/arm/mach-shmobile/board-g3evm.c @@ -37,6 +37,15 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/mach/time.h> + +/* + * IrDA + * + * S67: 5bit : ON power + * : 6bit : ON remote control + * OFF IrDA + */ static struct mtd_partition nor_flash_partitions[] = { { @@ -113,7 +122,7 @@ static struct resource usb_host_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 65, + .start = evt2irq(0xa20), /* USBHS_USHI0 */ .flags = IORESOURCE_IRQ, }, }; @@ -153,7 +162,7 @@ static struct resource keysc_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 79, + .start = evt2irq(0xbe0), /* KEYSC_KEY */ .flags = IORESOURCE_IRQ, }, }; @@ -209,11 +218,30 @@ static struct platform_device nand_flash_device = { }, }; +static struct resource irda_resources[] = { + [0] = { + .start = 0xE6D00000, + .end = 0xE6D01FD4 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x480), /* IRDA */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device irda_device = { + .name = "sh_irda", + .resource = irda_resources, + .num_resources = ARRAY_SIZE(irda_resources), +}; + static struct platform_device *g3evm_devices[] __initdata = { &nor_flash_device, &usb_host_device, &keysc_device, &nand_flash_device, + &irda_device, }; static struct map_desc g3evm_io_desc[] __initdata = { @@ -232,9 +260,8 @@ static void __init g3evm_map_io(void) { iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc)); - /* setup early devices, clocks and console here as well */ + /* setup early devices and console here as well */ sh7367_add_early_devices(); - sh7367_clock_init(); shmobile_setup_console(); } @@ -271,9 +298,6 @@ static void __init g3evm_init(void) gpio_request(GPIO_FN_EXTLP, NULL); gpio_request(GPIO_FN_IDIN, NULL); - /* enable clock in SYMSTPCR2 */ - __raw_writel(__raw_readl(0xe6158048) & ~(1 << 22), 0xe6158048); - /* setup USB phy */ __raw_writew(0x0300, 0xe605810a); /* USBCR1 */ __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ @@ -318,16 +342,32 @@ static void __init g3evm_init(void) /* FOE, FCDE, FSC on dedicated pins */ __raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048); + /* IrDA */ + gpio_request(GPIO_FN_IRDA_OUT, NULL); + gpio_request(GPIO_FN_IRDA_IN, NULL); + gpio_request(GPIO_FN_IRDA_FIRSEL, NULL); + set_irq_type(evt2irq(0x480), IRQ_TYPE_LEVEL_LOW); + sh7367_add_standard_devices(); platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices)); } +static void __init g3evm_timer_init(void) +{ + sh7367_clock_init(); + shmobile_timer.init(); +} + +static struct sys_timer g3evm_timer = { + .init = g3evm_timer_init, +}; + MACHINE_START(G3EVM, "g3evm") .phys_io = 0xe6000000, .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, .map_io = g3evm_map_io, .init_irq = sh7367_init_irq, .init_machine = g3evm_init, - .timer = &shmobile_timer, + .timer = &g3evm_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c index 10673a90be52..e256b7cc4275 100644 --- a/arch/arm/mach-shmobile/board-g4evm.c +++ b/arch/arm/mach-shmobile/board-g4evm.c @@ -30,12 +30,39 @@ #include <linux/io.h> #include <linux/input.h> #include <linux/input/sh_keysc.h> +#include <linux/mfd/sh_mobile_sdhi.h> #include <linux/gpio.h> #include <mach/sh7377.h> #include <mach/common.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/mach/time.h> + +/* + * SDHI + * + * SDHI0 : card detection is possible + * SDHI1 : card detection is impossible + * + * [G4-MAIN-BOARD] + * JP74 : short # DBG_2V8A for SDHI0 + * JP75 : NC # DBG_3V3A for SDHI0 + * JP76 : NC # DBG_3V3A_SD for SDHI0 + * JP77 : NC # 3V3A_SDIO for SDHI1 + * JP78 : short # DBG_2V8A for SDHI1 + * JP79 : NC # DBG_3V3A for SDHI1 + * JP80 : NC # DBG_3V3A_SD for SDHI1 + * + * [G4-CORE-BOARD] + * S32 : all off # to dissever from G3-CORE_DBG board + * S33 : all off # to dissever from G3-CORE_DBG board + * + * [G3-CORE_DBG-BOARD] + * S1 : all off # to dissever from G3-CORE_DBG board + * S3 : all off # to dissever from G3-CORE_DBG board + * S4 : all off # to dissever from G3-CORE_DBG board + */ static struct mtd_partition nor_flash_partitions[] = { { @@ -112,8 +139,7 @@ static struct resource usb_host_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 65, - .end = 65, + .start = evt2irq(0x0a20), /* USBHS_USHI0 */ .flags = IORESOURCE_IRQ, }, }; @@ -154,7 +180,7 @@ static struct resource keysc_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 79, + .start = evt2irq(0x0be0), /* KEYSC_KEY */ .flags = IORESOURCE_IRQ, }, }; @@ -169,10 +195,53 @@ static struct platform_device keysc_device = { }, }; +/* SDHI */ +static struct resource sdhi0_resources[] = { + [0] = { + .name = "SDHI0", + .start = 0xe6d50000, + .end = 0xe6d501ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x0e00), /* SDHI0 */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi0_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi0_resources), + .resource = sdhi0_resources, + .id = 0, +}; + +static struct resource sdhi1_resources[] = { + [0] = { + .name = "SDHI1", + .start = 0xe6d60000, + .end = 0xe6d601ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x0e80), /* SDHI1 */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi1_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi1_resources), + .resource = sdhi1_resources, + .id = 1, +}; + static struct platform_device *g4evm_devices[] __initdata = { &nor_flash_device, &usb_host_device, &keysc_device, + &sdhi0_device, + &sdhi1_device, }; static struct map_desc g4evm_io_desc[] __initdata = { @@ -191,12 +260,41 @@ static void __init g4evm_map_io(void) { iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc)); - /* setup early devices, clocks and console here as well */ + /* setup early devices and console here as well */ sh7377_add_early_devices(); - sh7367_clock_init(); /* use g3 clocks for now */ shmobile_setup_console(); } +#define GPIO_SDHID0_D0 0xe60520fc +#define GPIO_SDHID0_D1 0xe60520fd +#define GPIO_SDHID0_D2 0xe60520fe +#define GPIO_SDHID0_D3 0xe60520ff +#define GPIO_SDHICMD0 0xe6052100 + +#define GPIO_SDHID1_D0 0xe6052103 +#define GPIO_SDHID1_D1 0xe6052104 +#define GPIO_SDHID1_D2 0xe6052105 +#define GPIO_SDHID1_D3 0xe6052106 +#define GPIO_SDHICMD1 0xe6052107 + +/* + * FIXME !! + * + * gpio_pull_up is quick_hack. + * + * current gpio frame work doesn't have + * the method to control only pull up/down/free. + * this function should be replaced by correct gpio function + */ +static void __init gpio_pull_up(u32 addr) +{ + u8 data = __raw_readb(addr); + + data &= 0x0F; + data |= 0xC0; + __raw_writeb(data, addr); +} + static void __init g4evm_init(void) { sh7377_pinmux_init(); @@ -229,9 +327,6 @@ static void __init g4evm_init(void) gpio_request(GPIO_FN_EXTLP, NULL); gpio_request(GPIO_FN_IDIN, NULL); - /* enable clock in SMSTPCR3 */ - __raw_writel(__raw_readl(0xe615013c) & ~(1 << 22), 0xe615013c); - /* setup USB phy */ __raw_writew(0x0200, 0xe605810a); /* USBCR1 */ __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ @@ -253,16 +348,54 @@ static void __init g4evm_init(void) gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL); gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL); + /* SDHI0 */ + gpio_request(GPIO_FN_SDHICLK0, NULL); + gpio_request(GPIO_FN_SDHICD0, NULL); + gpio_request(GPIO_FN_SDHID0_0, NULL); + gpio_request(GPIO_FN_SDHID0_1, NULL); + gpio_request(GPIO_FN_SDHID0_2, NULL); + gpio_request(GPIO_FN_SDHID0_3, NULL); + gpio_request(GPIO_FN_SDHICMD0, NULL); + gpio_request(GPIO_FN_SDHIWP0, NULL); + gpio_pull_up(GPIO_SDHID0_D0); + gpio_pull_up(GPIO_SDHID0_D1); + gpio_pull_up(GPIO_SDHID0_D2); + gpio_pull_up(GPIO_SDHID0_D3); + gpio_pull_up(GPIO_SDHICMD0); + + /* SDHI1 */ + gpio_request(GPIO_FN_SDHICLK1, NULL); + gpio_request(GPIO_FN_SDHID1_0, NULL); + gpio_request(GPIO_FN_SDHID1_1, NULL); + gpio_request(GPIO_FN_SDHID1_2, NULL); + gpio_request(GPIO_FN_SDHID1_3, NULL); + gpio_request(GPIO_FN_SDHICMD1, NULL); + gpio_pull_up(GPIO_SDHID1_D0); + gpio_pull_up(GPIO_SDHID1_D1); + gpio_pull_up(GPIO_SDHID1_D2); + gpio_pull_up(GPIO_SDHID1_D3); + gpio_pull_up(GPIO_SDHICMD1); + sh7377_add_standard_devices(); platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices)); } +static void __init g4evm_timer_init(void) +{ + sh7377_clock_init(); + shmobile_timer.init(); +} + +static struct sys_timer g4evm_timer = { + .init = g4evm_timer_init, +}; + MACHINE_START(G4EVM, "g4evm") .phys_io = 0xe6000000, .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, .map_io = g4evm_map_io, .init_irq = sh7377_init_irq, .init_machine = g4evm_init, - .timer = &shmobile_timer, + .timer = &g4evm_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c index bb940c6e4e6c..b6454c9f2abb 100644 --- a/arch/arm/mach-shmobile/clock-sh7367.c +++ b/arch/arm/mach-shmobile/clock-sh7367.c @@ -1,5 +1,5 @@ /* - * Preliminary clock framework support for sh7367 + * SH7367 clock framework support * * Copyright (C) 2010 Magnus Damm * @@ -17,87 +17,342 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <linux/init.h> -#include <linux/module.h> #include <linux/kernel.h> -#include <linux/list.h> -#include <linux/clk.h> +#include <linux/io.h> +#include <linux/sh_clk.h> +#include <mach/common.h> +#include <asm/clkdev.h> + +/* SH7367 registers */ +#define RTFRQCR 0xe6150000 +#define SYFRQCR 0xe6150004 +#define CMFRQCR 0xe61500E0 +#define VCLKCR1 0xe6150008 +#define VCLKCR2 0xe615000C +#define VCLKCR3 0xe615001C +#define SCLKACR 0xe6150010 +#define SCLKBCR 0xe6150014 +#define SUBUSBCKCR 0xe6158080 +#define SPUCKCR 0xe6150084 +#define MSUCKCR 0xe6150088 +#define MVI3CKCR 0xe6150090 +#define VOUCKCR 0xe6150094 +#define MFCK1CR 0xe6150098 +#define MFCK2CR 0xe615009C +#define PLLC1CR 0xe6150028 +#define PLLC2CR 0xe615002C +#define RTMSTPCR0 0xe6158030 +#define RTMSTPCR2 0xe6158038 +#define SYMSTPCR0 0xe6158040 +#define SYMSTPCR2 0xe6158048 +#define CMMSTPCR0 0xe615804c -struct clk { - const char *name; - unsigned long rate; +/* Fixed 32 KHz root clock from EXTALR pin */ +static struct clk r_clk = { + .rate = 32768, }; -#include <asm/clkdev.h> +/* + * 26MHz default rate for the EXTALB1 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7367_extalb1_clk = { + .rate = 26666666, +}; -int __clk_get(struct clk *clk) -{ - return 1; -} -EXPORT_SYMBOL(__clk_get); +/* + * 48MHz default rate for the EXTAL2 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7367_extal2_clk = { + .rate = 48000000, +}; -void __clk_put(struct clk *clk) +/* A fixed divide-by-2 block */ +static unsigned long div2_recalc(struct clk *clk) { + return clk->parent->rate / 2; } -EXPORT_SYMBOL(__clk_put); +static struct clk_ops div2_clk_ops = { + .recalc = div2_recalc, +}; + +/* Divide extalb1 by two */ +static struct clk extalb1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7367_extalb1_clk, +}; + +/* Divide extal2 by two */ +static struct clk extal2_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7367_extal2_clk, +}; -int clk_enable(struct clk *clk) +/* PLLC1 */ +static unsigned long pllc1_recalc(struct clk *clk) { - return 0; + unsigned long mult = 1; + + if (__raw_readl(PLLC1CR) & (1 << 14)) + mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; } -EXPORT_SYMBOL(clk_enable); -void clk_disable(struct clk *clk) +static struct clk_ops pllc1_clk_ops = { + .recalc = pllc1_recalc, +}; + +static struct clk pllc1_clk = { + .ops = &pllc1_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extalb1_div2_clk, +}; + +/* Divide PLLC1 by two */ +static struct clk pllc1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &pllc1_clk, +}; + +/* PLLC2 */ +static unsigned long pllc2_recalc(struct clk *clk) { + unsigned long mult = 1; + + if (__raw_readl(PLLC2CR) & (1 << 31)) + mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; } -EXPORT_SYMBOL(clk_disable); -unsigned long clk_get_rate(struct clk *clk) +static struct clk_ops pllc2_clk_ops = { + .recalc = pllc2_recalc, +}; + +static struct clk pllc2_clk = { + .ops = &pllc2_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extalb1_div2_clk, +}; + +static struct clk *main_clks[] = { + &r_clk, + &sh7367_extalb1_clk, + &sh7367_extal2_clk, + &extalb1_div2_clk, + &extal2_div2_clk, + &pllc1_clk, + &pllc1_div2_clk, + &pllc2_clk, +}; + +static void div4_kick(struct clk *clk) { - return clk ? clk->rate : 0; + unsigned long value; + + /* set KICK bit in SYFRQCR to update hardware setting */ + value = __raw_readl(SYFRQCR); + value |= (1 << 31); + __raw_writel(value, SYFRQCR); } -EXPORT_SYMBOL(clk_get_rate); -/* a static peripheral clock for now - enough to get sh-sci working */ -static struct clk peripheral_clk = { - .name = "peripheral_clk", - .rate = 48000000, +static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, + 24, 32, 36, 48, 0, 72, 0, 0 }; + +static struct clk_div_mult_table div4_div_mult_table = { + .divisors = divisors, + .nr_divisors = ARRAY_SIZE(divisors), }; -/* a static rclk for now - enough to get sh_cmt working */ -static struct clk r_clk = { - .name = "r_clk", - .rate = 32768, +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, + .kick = div4_kick, +}; + +enum { DIV4_I, DIV4_G, DIV4_S, DIV4_B, + DIV4_ZX, DIV4_ZT, DIV4_Z, DIV4_ZD, DIV4_HP, + DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR }; + +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags) + +static struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_G] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_S] = DIV4(RTFRQCR, 12, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_ZX] = DIV4(SYFRQCR, 20, 0x6fff, 0), + [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0), + [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0), + [DIV4_ZD] = DIV4(SYFRQCR, 8, 0x6fff, 0), + [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0), + [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0), + [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0), + [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0), + [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0), }; -/* a static usb0 for now - enough to get r8a66597 working */ -static struct clk usb0_clk = { - .name = "usb0", +enum { DIV6_SUB, DIV6_SIUA, DIV6_SIUB, DIV6_MSU, DIV6_SPU, + DIV6_MVI3, DIV6_MF1, DIV6_MF2, + DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VOU, + DIV6_NR }; + +static struct clk div6_clks[DIV6_NR] = { + [DIV6_SUB] = SH_CLK_DIV6(&sh7367_extal2_clk, SUBUSBCKCR, 0), + [DIV6_SIUA] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKACR, 0), + [DIV6_SIUB] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKBCR, 0), + [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0), + [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), + [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0), + [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0), + [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0), + [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0), + [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0), + [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), + [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0), }; -/* a static keysc0 clk for now - enough to get sh_keysc working */ -static struct clk keysc0_clk = { - .name = "keysc0", +enum { RTMSTP001, + RTMSTP231, RTMSTP230, RTMSTP229, RTMSTP228, RTMSTP226, + RTMSTP216, RTMSTP206, RTMSTP205, RTMSTP201, + SYMSTP023, SYMSTP007, SYMSTP006, SYMSTP004, + SYMSTP003, SYMSTP002, SYMSTP001, SYMSTP000, + SYMSTP231, SYMSTP229, SYMSTP225, SYMSTP223, SYMSTP222, + SYMSTP215, SYMSTP214, SYMSTP213, SYMSTP211, + CMMSTP003, + MSTP_NR }; + +#define MSTP(_parent, _reg, _bit, _flags) \ + SH_CLK_MSTP32(_parent, _reg, _bit, _flags) + +static struct clk mstp_clks[MSTP_NR] = { + [RTMSTP001] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR0, 1, 0), /* IIC2 */ + [RTMSTP231] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 31, 0), /* VEU3 */ + [RTMSTP230] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 30, 0), /* VEU2 */ + [RTMSTP229] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 29, 0), /* VEU1 */ + [RTMSTP228] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 28, 0), /* VEU0 */ + [RTMSTP226] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 26, 0), /* VEU2H */ + [RTMSTP216] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR2, 16, 0), /* IIC0 */ + [RTMSTP206] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 6, 0), /* JPU */ + [RTMSTP205] = MSTP(&div6_clks[DIV6_VOU], RTMSTPCR2, 5, 0), /* VOU */ + [RTMSTP201] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 1, 0), /* VPU */ + [SYMSTP023] = MSTP(&div6_clks[DIV6_SPU], SYMSTPCR0, 23, 0), /* SPU1 */ + [SYMSTP007] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 7, 0), /* SCIFA5 */ + [SYMSTP006] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 6, 0), /* SCIFB */ + [SYMSTP004] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 4, 0), /* SCIFA0 */ + [SYMSTP003] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 3, 0), /* SCIFA1 */ + [SYMSTP002] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 2, 0), /* SCIFA2 */ + [SYMSTP001] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 1, 0), /* SCIFA3 */ + [SYMSTP000] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 0, 0), /* SCIFA4 */ + [SYMSTP231] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 31, 0), /* SIU */ + [SYMSTP229] = MSTP(&r_clk, SYMSTPCR2, 29, 0), /* CMT10 */ + [SYMSTP225] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 25, 0), /* IRDA */ + [SYMSTP223] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 23, 0), /* IIC1 */ + [SYMSTP222] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 22, 0), /* USBHS */ + [SYMSTP215] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 15, 0), /* FLCTL */ + [SYMSTP214] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 14, 0), /* SDHI0 */ + [SYMSTP213] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 13, 0), /* SDHI1 */ + [SYMSTP211] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 11, 0), /* SDHI2 */ + [CMMSTP003] = MSTP(&r_clk, CMMSTPCR0, 3, 0), /* KEYSC */ }; +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } +#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } + static struct clk_lookup lookups[] = { - { - .clk = &peripheral_clk, - }, { - .clk = &r_clk, - }, { - .clk = &usb0_clk, - }, { - .clk = &keysc0_clk, - } + /* main clocks */ + CLKDEV_CON_ID("r_clk", &r_clk), + CLKDEV_CON_ID("extalb1", &sh7367_extalb1_clk), + CLKDEV_CON_ID("extal2", &sh7367_extal2_clk), + CLKDEV_CON_ID("extalb1_div2_clk", &extalb1_div2_clk), + CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk), + CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), + CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), + CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), + + /* DIV4 clocks */ + CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("g_clk", &div4_clks[DIV4_G]), + CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]), + CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]), + CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]), + CLKDEV_CON_ID("zd_clk", &div4_clks[DIV4_ZD]), + CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]), + CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]), + CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]), + CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]), + CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]), + + /* DIV6 clocks */ + CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), + CLKDEV_CON_ID("siua_clk", &div6_clks[DIV6_SIUA]), + CLKDEV_CON_ID("siub_clk", &div6_clks[DIV6_SIUB]), + CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]), + CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), + CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]), + CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]), + CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]), + CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), + CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), + CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), + CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), + + /* MSTP32 clocks */ + CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[RTMSTP001]), /* IIC2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[RTMSTP231]), /* VEU3 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[RTMSTP230]), /* VEU2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[RTMSTP229]), /* VEU1 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[RTMSTP228]), /* VEU0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[RTMSTP226]), /* VEU2H */ + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[RTMSTP216]), /* IIC0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[RTMSTP206]), /* JPU */ + CLKDEV_DEV_ID("sh-vou", &mstp_clks[RTMSTP205]), /* VOU */ + CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[RTMSTP201]), /* VPU */ + CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[SYMSTP023]), /* SPU1 */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[SYMSTP007]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[SYMSTP006]), /* SCIFB */ + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[SYMSTP004]), /* SCIFA0 */ + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[SYMSTP003]), /* SCIFA1 */ + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[SYMSTP002]), /* SCIFA2 */ + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */ + CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */ + CLKDEV_CON_ID("cmt1", &mstp_clks[SYMSTP229]), /* CMT10 */ + CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */ + CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */ + CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */ + CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[SYMSTP222]), /* USBHS */ + CLKDEV_DEV_ID("sh_flctl", &mstp_clks[SYMSTP215]), /* FLCTL */ + CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[SYMSTP214]), /* SDHI0 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[SYMSTP213]), /* SDHI1 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[SYMSTP211]), /* SDHI2 */ + CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[CMMSTP003]), /* KEYSC */ }; void __init sh7367_clock_init(void) { - int i; + int k, ret = 0; + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + 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_mstp32_register(mstp_clks, MSTP_NR); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - for (i = 0; i < ARRAY_SIZE(lookups); i++) { - lookups[i].con_id = lookups[i].clk->name; - clkdev_add(&lookups[i]); - } + if (!ret) + clk_init(); + else + panic("failed to setup sh7367 clocks\n"); } diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c new file mode 100644 index 000000000000..f2f9a4ad53a4 --- /dev/null +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -0,0 +1,395 @@ +/* + * SH7372 clock framework support + * + * Copyright (C) 2010 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/sh_clk.h> +#include <mach/common.h> +#include <asm/clkdev.h> + +/* SH7372 registers */ +#define FRQCRA 0xe6150000 +#define FRQCRB 0xe6150004 +#define FRQCRC 0xe61500e0 +#define FRQCRD 0xe61500e4 +#define VCLKCR1 0xe6150008 +#define VCLKCR2 0xe615000c +#define VCLKCR3 0xe615001c +#define FMSICKCR 0xe6150010 +#define FMSOCKCR 0xe6150014 +#define FSIACKCR 0xe6150018 +#define FSIBCKCR 0xe6150090 +#define SUBCKCR 0xe6150080 +#define SPUCKCR 0xe6150084 +#define VOUCKCR 0xe6150088 +#define HDMICKCR 0xe6150094 +#define DSITCKCR 0xe6150060 +#define DSI0PCKCR 0xe6150064 +#define DSI1PCKCR 0xe6150098 +#define PLLC01CR 0xe6150028 +#define PLLC2CR 0xe615002c +#define SMSTPCR0 0xe6150130 +#define SMSTPCR1 0xe6150134 +#define SMSTPCR2 0xe6150138 +#define SMSTPCR3 0xe615013c +#define SMSTPCR4 0xe6150140 + +/* Fixed 32 KHz root clock from EXTALR pin */ +static struct clk r_clk = { + .rate = 32768, +}; + +/* + * 26MHz default rate for the EXTAL1 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7372_extal1_clk = { + .rate = 26666666, +}; + +/* + * 48MHz default rate for the EXTAL2 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7372_extal2_clk = { + .rate = 48000000, +}; + +/* A fixed divide-by-2 block */ +static unsigned long div2_recalc(struct clk *clk) +{ + return clk->parent->rate / 2; +} + +static struct clk_ops div2_clk_ops = { + .recalc = div2_recalc, +}; + +/* Divide extal1 by two */ +static struct clk extal1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7372_extal1_clk, +}; + +/* Divide extal2 by two */ +static struct clk extal2_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7372_extal2_clk, +}; + +/* Divide extal2 by four */ +static struct clk extal2_div4_clk = { + .ops = &div2_clk_ops, + .parent = &extal2_div2_clk, +}; + +/* PLLC0 and PLLC1 */ +static unsigned long pllc01_recalc(struct clk *clk) +{ + unsigned long mult = 1; + + if (__raw_readl(PLLC01CR) & (1 << 14)) + mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; +} + +static struct clk_ops pllc01_clk_ops = { + .recalc = pllc01_recalc, +}; + +static struct clk pllc0_clk = { + .ops = &pllc01_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extal1_div2_clk, + .enable_reg = (void __iomem *)FRQCRC, +}; + +static struct clk pllc1_clk = { + .ops = &pllc01_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extal1_div2_clk, + .enable_reg = (void __iomem *)FRQCRA, +}; + +/* Divide PLLC1 by two */ +static struct clk pllc1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &pllc1_clk, +}; + +/* PLLC2 */ +static unsigned long pllc2_recalc(struct clk *clk) +{ + unsigned long mult = 1; + + if (__raw_readl(PLLC2CR) & (1 << 31)) + mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; +} + +static struct clk_ops pllc2_clk_ops = { + .recalc = pllc2_recalc, +}; + +static struct clk pllc2_clk = { + .ops = &pllc2_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extal1_div2_clk, +}; + +static struct clk *main_clks[] = { + &r_clk, + &sh7372_extal1_clk, + &sh7372_extal2_clk, + &extal1_div2_clk, + &extal2_div2_clk, + &extal2_div4_clk, + &pllc0_clk, + &pllc1_clk, + &pllc1_div2_clk, + &pllc2_clk, +}; + +static void div4_kick(struct clk *clk) +{ + unsigned long value; + + /* set KICK bit in FRQCRB to update hardware setting */ + value = __raw_readl(FRQCRB); + value |= (1 << 31); + __raw_writel(value, FRQCRB); +} + +static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, + 24, 32, 36, 48, 0, 72, 96, 0 }; + +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_ZG, DIV4_B, DIV4_M1, DIV4_CSIR, + DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, + DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP, + DIV4_DDRP, DIV4_NR }; + +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags) + +static struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0), + [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0), + [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0), + [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0), + [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0), + [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0), + [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0), + [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0), + [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0), + [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0), + [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0), +}; + +enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, + DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU, + DIV6_VOU, DIV6_HDMI, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P, + DIV6_NR }; + +static struct clk div6_clks[DIV6_NR] = { + [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0), + [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0), + [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), + [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0), + [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0), + [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0), + [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0), + [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0), + [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), + [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0), + [DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0), + [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0), + [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0), + [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0), +}; + +enum { MSTP001, + MSTP131, MSTP130, + MSTP129, MSTP128, + MSTP118, MSTP117, MSTP116, + MSTP106, MSTP101, MSTP100, + MSTP223, + MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, + MSTP329, MSTP323, MSTP322, MSTP314, MSTP313, + MSTP415, MSTP410, MSTP411, MSTP406, MSTP403, + MSTP_NR }; + +#define MSTP(_parent, _reg, _bit, _flags) \ + SH_CLK_MSTP32(_parent, _reg, _bit, _flags) + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */ + [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */ + [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ + [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ + [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ + [MSTP118] = MSTP(&div6_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */ + [MSTP117] = MSTP(&div6_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ + [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ + [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */ + [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */ + [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ + [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */ + [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ + [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ + [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ + [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */ + [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */ + [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ + [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ + [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ + [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ + [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ + [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ + [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ + [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */ + [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */ + [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */ + [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */ + [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ +}; + +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } +#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("r_clk", &r_clk), + CLKDEV_CON_ID("extal1", &sh7372_extal1_clk), + CLKDEV_CON_ID("extal2", &sh7372_extal2_clk), + CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk), + CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk), + CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk), + CLKDEV_CON_ID("pllc0_clk", &pllc0_clk), + CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), + CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), + CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), + + /* DIV4 clocks */ + CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]), + CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]), + CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]), + CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]), + CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]), + CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]), + CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]), + CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]), + CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]), + CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]), + CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]), + CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]), + CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]), + + /* DIV6 clocks */ + CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), + CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), + CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), + CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), + CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), + CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]), + CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]), + CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), + CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), + CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), + CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]), + CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]), + CLKDEV_CON_ID("dsi0p_clk", &div6_clks[DIV6_DSI0P]), + CLKDEV_CON_ID("dsi1p_clk", &div6_clks[DIV6_DSI1P]), + + /* MSTP32 clocks */ + CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ + CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ + CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ + CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */ + CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */ + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ + CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */ + CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ + CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */ + CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */ + CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ + CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */ + CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ + CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ + CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ +}; + +void __init sh7372_clock_init(void) +{ + int k, ret = 0; + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + 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_mstp32_register(mstp_clks, MSTP_NR); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + clk_init(); + else + panic("failed to setup sh7372 clocks\n"); + +} diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c new file mode 100644 index 000000000000..e007c28cf0a8 --- /dev/null +++ b/arch/arm/mach-shmobile/clock-sh7377.c @@ -0,0 +1,369 @@ +/* + * SH7377 clock framework support + * + * Copyright (C) 2010 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/sh_clk.h> +#include <mach/common.h> +#include <asm/clkdev.h> + +/* SH7377 registers */ +#define RTFRQCR 0xe6150000 +#define SYFRQCR 0xe6150004 +#define CMFRQCR 0xe61500E0 +#define VCLKCR1 0xe6150008 +#define VCLKCR2 0xe615000C +#define VCLKCR3 0xe615001C +#define FMSICKCR 0xe6150010 +#define FMSOCKCR 0xe6150014 +#define FSICKCR 0xe6150018 +#define PLLC1CR 0xe6150028 +#define PLLC2CR 0xe615002C +#define SUBUSBCKCR 0xe6150080 +#define SPUCKCR 0xe6150084 +#define MSUCKCR 0xe6150088 +#define MVI3CKCR 0xe6150090 +#define HDMICKCR 0xe6150094 +#define MFCK1CR 0xe6150098 +#define MFCK2CR 0xe615009C +#define DSITCKCR 0xe6150060 +#define DSIPCKCR 0xe6150064 +#define SMSTPCR0 0xe6150130 +#define SMSTPCR1 0xe6150134 +#define SMSTPCR2 0xe6150138 +#define SMSTPCR3 0xe615013C +#define SMSTPCR4 0xe6150140 + +/* Fixed 32 KHz root clock from EXTALR pin */ +static struct clk r_clk = { + .rate = 32768, +}; + +/* + * 26MHz default rate for the EXTALC1 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7377_extalc1_clk = { + .rate = 26666666, +}; + +/* + * 48MHz default rate for the EXTAL2 root input clock. + * If needed, reset this with clk_set_rate() from the platform code. + */ +struct clk sh7377_extal2_clk = { + .rate = 48000000, +}; + +/* A fixed divide-by-2 block */ +static unsigned long div2_recalc(struct clk *clk) +{ + return clk->parent->rate / 2; +} + +static struct clk_ops div2_clk_ops = { + .recalc = div2_recalc, +}; + +/* Divide extalc1 by two */ +static struct clk extalc1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7377_extalc1_clk, +}; + +/* Divide extal2 by two */ +static struct clk extal2_div2_clk = { + .ops = &div2_clk_ops, + .parent = &sh7377_extal2_clk, +}; + +/* Divide extal2 by four */ +static struct clk extal2_div4_clk = { + .ops = &div2_clk_ops, + .parent = &extal2_div2_clk, +}; + +/* PLLC1 */ +static unsigned long pllc1_recalc(struct clk *clk) +{ + unsigned long mult = 1; + + if (__raw_readl(PLLC1CR) & (1 << 14)) + mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; +} + +static struct clk_ops pllc1_clk_ops = { + .recalc = pllc1_recalc, +}; + +static struct clk pllc1_clk = { + .ops = &pllc1_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extalc1_div2_clk, +}; + +/* Divide PLLC1 by two */ +static struct clk pllc1_div2_clk = { + .ops = &div2_clk_ops, + .parent = &pllc1_clk, +}; + +/* PLLC2 */ +static unsigned long pllc2_recalc(struct clk *clk) +{ + unsigned long mult = 1; + + if (__raw_readl(PLLC2CR) & (1 << 31)) + mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2; + + return clk->parent->rate * mult; +} + +static struct clk_ops pllc2_clk_ops = { + .recalc = pllc2_recalc, +}; + +static struct clk pllc2_clk = { + .ops = &pllc2_clk_ops, + .flags = CLK_ENABLE_ON_INIT, + .parent = &extalc1_div2_clk, +}; + +static struct clk *main_clks[] = { + &r_clk, + &sh7377_extalc1_clk, + &sh7377_extal2_clk, + &extalc1_div2_clk, + &extal2_div2_clk, + &extal2_div4_clk, + &pllc1_clk, + &pllc1_div2_clk, + &pllc2_clk, +}; + +static void div4_kick(struct clk *clk) +{ + unsigned long value; + + /* set KICK bit in SYFRQCR to update hardware setting */ + value = __raw_readl(SYFRQCR); + value |= (1 << 31); + __raw_writel(value, SYFRQCR); +} + +static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, + 24, 32, 36, 48, 0, 72, 96, 0 }; + +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_ZG, DIV4_B, DIV4_M1, DIV4_CSIR, + DIV4_ZTR, DIV4_ZT, DIV4_Z, DIV4_HP, + DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR }; + +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags) + +static struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_ZG] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_M1] = DIV4(RTFRQCR, 4, 0x6fff, CLK_ENABLE_ON_INIT), + [DIV4_CSIR] = DIV4(RTFRQCR, 0, 0x6fff, 0), + [DIV4_ZTR] = DIV4(SYFRQCR, 20, 0x6fff, 0), + [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0), + [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0), + [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0), + [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0), + [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0), + [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0), + [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0), +}; + +enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, + DIV6_FSI, DIV6_SUB, DIV6_SPU, DIV6_MSU, DIV6_MVI3, DIV6_HDMI, + DIV6_MF1, DIV6_MF2, DIV6_DSIT, DIV6_DSIP, + DIV6_NR }; + +static struct clk div6_clks[] = { + [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0), + [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0), + [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), + [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0), + [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0), + [DIV6_FSI] = SH_CLK_DIV6(&pllc1_div2_clk, FSICKCR, 0), + [DIV6_SUB] = SH_CLK_DIV6(&sh7377_extal2_clk, SUBUSBCKCR, 0), + [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), + [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0), + [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0), + [DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0), + [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0), + [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0), + [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0), + [DIV6_DSIP] = SH_CLK_DIV6(&pllc1_div2_clk, DSIPCKCR, 0), +}; + +enum { MSTP001, + MSTP131, MSTP130, MSTP129, MSTP128, MSTP116, MSTP106, MSTP101, + MSTP223, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, + MSTP331, MSTP329, MSTP325, MSTP323, MSTP322, + MSTP315, MSTP314, MSTP313, + MSTP403, + MSTP_NR }; + +#define MSTP(_parent, _reg, _bit, _flags) \ + SH_CLK_MSTP32(_parent, _reg, _bit, _flags) + +static struct clk mstp_clks[] = { + [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */ + [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */ + [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ + [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ + [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ + [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ + [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */ + [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */ + [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */ + [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ + [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ + [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ + [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */ + [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */ + [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ + [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ + [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */ + [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ + [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IRDA */ + [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ + [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ + [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL */ + [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ + [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ + [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ +}; + +#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } +#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("r_clk", &r_clk), + CLKDEV_CON_ID("extalc1", &sh7377_extalc1_clk), + CLKDEV_CON_ID("extal2", &sh7377_extal2_clk), + CLKDEV_CON_ID("extalc1_div2_clk", &extalc1_div2_clk), + CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk), + CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk), + CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), + CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), + CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), + + /* DIV4 clocks */ + CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), + CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]), + CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]), + CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]), + CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]), + CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]), + CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]), + CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]), + CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]), + CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]), + CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]), + CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]), + CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]), + + /* DIV6 clocks */ + CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), + CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), + CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), + CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), + CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), + CLKDEV_CON_ID("fsi_clk", &div6_clks[DIV6_FSI]), + CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), + CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), + CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]), + CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]), + CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]), + CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]), + CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]), + CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]), + CLKDEV_CON_ID("dsip_clk", &div6_clks[DIV6_DSIP]), + + /* MSTP32 clocks */ + CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ + CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ + CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */ + CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */ + CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP206]), /* SCIFB */ + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ + CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */ + CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */ + CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */ + CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ + CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */ + CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USBHS */ + CLKDEV_DEV_ID("sh_flctl", &mstp_clks[MSTP315]), /* FLCTL */ + CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ + CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ +}; + +void __init sh7377_clock_init(void) +{ + int k, ret = 0; + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + 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_mstp32_register(mstp_clks, MSTP_NR); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + clk_init(); + else + panic("failed to setup sh7377 clocks\n"); +} diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c new file mode 100644 index 000000000000..b7c705a213a2 --- /dev/null +++ b/arch/arm/mach-shmobile/clock.c @@ -0,0 +1,44 @@ +/* + * SH-Mobile Timer + * + * Copyright (C) 2010 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; 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/sh_clk.h> + +int __init clk_init(void) +{ + /* Kick the child clocks.. */ + recalculate_root_clocks(); + + /* Enable the necessary init clocks */ + clk_enable_init_clocks(); + + return 0; +} + +int __clk_get(struct clk *clk) +{ + return 1; +} +EXPORT_SYMBOL(__clk_get); + +void __clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(__clk_put); diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 57903605cc51..efeef778a875 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -3,21 +3,31 @@ extern struct sys_timer shmobile_timer; extern void shmobile_setup_console(void); +struct clk; +extern int clk_init(void); extern void sh7367_init_irq(void); extern void sh7367_add_early_devices(void); extern void sh7367_add_standard_devices(void); extern void sh7367_clock_init(void); extern void sh7367_pinmux_init(void); +extern struct clk sh7367_extalb1_clk; +extern struct clk sh7367_extal2_clk; extern void sh7377_init_irq(void); extern void sh7377_add_early_devices(void); extern void sh7377_add_standard_devices(void); +extern void sh7377_clock_init(void); extern void sh7377_pinmux_init(void); +extern struct clk sh7377_extalc1_clk; +extern struct clk sh7377_extal2_clk; extern void sh7372_init_irq(void); extern void sh7372_add_early_devices(void); extern void sh7372_add_standard_devices(void); +extern void sh7372_clock_init(void); extern void sh7372_pinmux_init(void); +extern struct clk sh7372_extal1_clk; +extern struct clk sh7372_extal2_clk; #endif /* __ARCH_MACH_COMMON_H */ diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h index 5179b72e1ee3..e881797648a9 100644 --- a/arch/arm/mach-shmobile/include/mach/irqs.h +++ b/arch/arm/mach-shmobile/include/mach/irqs.h @@ -4,7 +4,13 @@ #define NR_IRQS 512 #define NR_IRQS_LEGACY 8 +/* INTCA */ #define evt2irq(evt) (((evt) >> 5) - 16) #define irq2evt(irq) (((irq) + 16) << 5) +/* INTCS */ +#define INTCS_VECT_BASE 0x2200 +#define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect)) +#define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt)) + #endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-shmobile/include/mach/memory.h b/arch/arm/mach-shmobile/include/mach/memory.h index e188183f4dce..377584e57e03 100644 --- a/arch/arm/mach-shmobile/include/mach/memory.h +++ b/arch/arm/mach-shmobile/include/mach/memory.h @@ -4,4 +4,7 @@ #define PHYS_OFFSET UL(CONFIG_MEMORY_START) #define MEM_SIZE UL(CONFIG_MEMORY_SIZE) +/* DMA memory at 0xf6000000 - 0xffdfffff */ +#define CONSISTENT_DMA_SIZE (158 << 20) + #endif /* __ASM_MACH_MEMORY_H */ diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h index fb3c4f1ab252..4aecf6e3a859 100644 --- a/arch/arm/mach-shmobile/include/mach/vmalloc.h +++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h @@ -1,6 +1,7 @@ #ifndef __ASM_MACH_VMALLOC_H #define __ASM_MACH_VMALLOC_H -#define VMALLOC_END (PAGE_OFFSET + 0x24000000) +/* Vmalloc at ... - 0xe5ffffff */ +#define VMALLOC_END 0xe6000000 #endif /* __ASM_MACH_VMALLOC_H */ diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c index 5ff70cadfc32..1a20c489b20d 100644 --- a/arch/arm/mach-shmobile/intc-sh7367.c +++ b/arch/arm/mach-shmobile/intc-sh7367.c @@ -75,7 +75,7 @@ enum { ETM11, ARM11, USBHS, FLCTL, IIC1 }; -static struct intc_vect intca_vectors[] = { +static struct intc_vect intca_vectors[] __initdata = { INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220), INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260), INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0), @@ -162,7 +162,7 @@ static struct intc_group intca_groups[] __initdata = { INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1), }; -static struct intc_mask_reg intca_mask_registers[] = { +static struct intc_mask_reg intca_mask_registers[] __initdata = { { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */ @@ -211,7 +211,7 @@ static struct intc_mask_reg intca_mask_registers[] = { MISTY, CMT3, RWDT1, RWDT0 } }, }; -static struct intc_prio_reg intca_prio_registers[] = { +static struct intc_prio_reg intca_prio_registers[] __initdata = { { 0xe6900010, 0, 32, 4, /* INTPRI00A */ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, { 0xe6900014, 0, 32, 4, /* INTPRI10A */ @@ -263,8 +263,178 @@ static struct intc_desc intca_desc __initdata = { intca_sense_registers, intca_ack_registers), }; +enum { + UNUSED_INTCS = 0, + + INTCS, + + /* interrupt sources INTCS */ + VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3, + VIO3_VOU, + RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3, + VIO1_CEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2, + VPU, + SGX530, + _2DDMAC_2DDM0, _2DDMAC_2DDM1, _2DDMAC_2DDM2, _2DDMAC_2DDM3, + IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, + IPMMU_IPMMUB, IPMMU_IPMMUS, + RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR, + MSIOF, + IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, + TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, + CMT, + TSIF, + IPMMUI, + MVI3, + ICB, + PEP, + ASA, + BEM, + VE2HO, + HQE, + JPEG, + LCDC, + + /* interrupt groups INTCS */ + _2DDMAC, RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2, +}; + +static struct intc_vect intcs_vectors[] = { + INTCS_VECT(VIO2_VEU0, 0x700), INTCS_VECT(VIO2_VEU1, 0x720), + INTCS_VECT(VIO2_VEU2, 0x740), INTCS_VECT(VIO2_VEU3, 0x760), + INTCS_VECT(VIO3_VOU, 0x780), + INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820), + INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860), + INTCS_VECT(VIO1_CEU, 0x880), INTCS_VECT(VIO1_BEU0, 0x8a0), + INTCS_VECT(VIO1_BEU1, 0x8c0), INTCS_VECT(VIO1_BEU2, 0x8e0), + INTCS_VECT(VPU, 0x980), + INTCS_VECT(SGX530, 0x9e0), + INTCS_VECT(_2DDMAC_2DDM0, 0xa00), INTCS_VECT(_2DDMAC_2DDM1, 0xa20), + INTCS_VECT(_2DDMAC_2DDM2, 0xa40), INTCS_VECT(_2DDMAC_2DDM3, 0xa60), + INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0), + INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0), + INTCS_VECT(IPMMU_IPMMUB, 0xb20), INTCS_VECT(IPMMU_IPMMUS, 0xb60), + INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0), + INTCS_VECT(RTDMAC_2_DADERR, 0xbc0), + INTCS_VECT(MSIOF, 0xd20), + INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20), + INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60), + INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0), + INTCS_VECT(TMU_TUNI2, 0xec0), + INTCS_VECT(CMT, 0xf00), + INTCS_VECT(TSIF, 0xf20), + INTCS_VECT(IPMMUI, 0xf60), + INTCS_VECT(MVI3, 0x420), + INTCS_VECT(ICB, 0x480), + INTCS_VECT(PEP, 0x4a0), + INTCS_VECT(ASA, 0x4c0), + INTCS_VECT(BEM, 0x4e0), + INTCS_VECT(VE2HO, 0x520), + INTCS_VECT(HQE, 0x540), + INTCS_VECT(JPEG, 0x560), + INTCS_VECT(LCDC, 0x580), + + INTC_VECT(INTCS, 0xf80), +}; + +static struct intc_group intcs_groups[] __initdata = { + INTC_GROUP(_2DDMAC, _2DDMAC_2DDM0, _2DDMAC_2DDM1, + _2DDMAC_2DDM2, _2DDMAC_2DDM3), + INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1, + RTDMAC_1_DEI2, RTDMAC_1_DEI3), + INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR), + INTC_GROUP(VEU, VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3), + INTC_GROUP(BEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2), + INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0), + INTC_GROUP(IPMMU, IPMMU_IPMMUS, IPMMU_IPMMUB), + INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2), +}; + +static struct intc_mask_reg intcs_mask_registers[] = { + { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */ + { VIO1_BEU2, VIO1_BEU1, VIO1_BEU0, VIO1_CEU, + VIO2_VEU3, VIO2_VEU2, VIO2_VEU1, VIO2_VEU0 } }, + { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */ + { VIO3_VOU, 0, VE2HO, VPU, + 0, 0, 0, 0 } }, + { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */ + { _2DDMAC_2DDM3, _2DDMAC_2DDM2, _2DDMAC_2DDM1, _2DDMAC_2DDM0, + BEM, ASA, PEP, ICB } }, + { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */ + { 0, 0, MVI3, 0, + JPEG, HQE, 0, LCDC } }, + { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */ + { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4, + RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } }, + { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */ + { 0, 0, MSIOF, 0, + SGX530, 0, 0, 0 } }, + { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */ + { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, + 0, 0, 0, 0 } }, + { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */ + { 0, 0, 0, CMT, + IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } }, + { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */ + { IPMMU_IPMMUS, 0, IPMMU_IPMMUB, 0, + 0, 0, 0, 0 } }, + { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */ + { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0, + 0, 0, IPMMUI, TSIF } }, + { 0xffd20104, 0, 16, /* INTAMASK */ + { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, INTCS } }, +}; + +/* Priority is needed for INTCA to receive the INTCS interrupt */ +static struct intc_prio_reg intcs_prio_registers[] = { + { 0xffd20000, 0, 16, 4, /* IPRAS */ { 0, MVI3, _2DDMAC, ICB } }, + { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPEG, LCDC, 0, 0 } }, + { 0xffd20008, 0, 16, 4, /* IPRCS */ { BBIF2, 0, 0, 0 } }, + { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, VIO1_CEU, 0, VPU } }, + { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT } }, + { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1, + TMU_TUNI2, 0 } }, + { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, VIO3_VOU, VEU, BEU } }, + { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF, IIC0 } }, + { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, SGX530, 0, 0 } }, + { 0xffd20028, 0, 16, 4, /* IPRKS */ { BEM, ASA, IPMMUI, PEP } }, + { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, VE2HO, HQE } }, + { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } }, +}; + +static struct resource intcs_resources[] __initdata = { + [0] = { + .start = 0xffd20000, + .end = 0xffd2ffff, + .flags = IORESOURCE_MEM, + } +}; + +static struct intc_desc intcs_desc __initdata = { + .name = "sh7367-intcs", + .resource = intcs_resources, + .num_resources = ARRAY_SIZE(intcs_resources), + .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers, + intcs_prio_registers, NULL, NULL), +}; + +static void intcs_demux(unsigned int irq, struct irq_desc *desc) +{ + void __iomem *reg = (void *)get_irq_data(irq); + unsigned int evtcodeas = ioread32(reg); + + generic_handle_irq(intcs_evt2irq(evtcodeas)); +} + void __init sh7367_init_irq(void) { - /* INTCA */ + void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); + register_intc_controller(&intca_desc); + register_intc_controller(&intcs_desc); + + /* demux using INTEVTSA */ + set_irq_data(evt2irq(0xf80), (void *)intevtsa); + set_irq_chained_handler(evt2irq(0xf80), intcs_demux); } diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index 3ce9d9bd5899..e3551b56cd03 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c @@ -319,17 +319,17 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = { { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } }, { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S, CMT14, CMT15 } }, - { 0xe694003c, 0, 16, 4, /* IPRPA3 */ { 0, 0, + { 0xe695003c, 0, 16, 4, /* IPRPA3 */ { 0, 0, MMC_MMC_ERR, MMC_MMC_NOR } }, - { 0xe6940040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4, + { 0xe6950040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4, IIC4_WAITI4, IIC4_DTEI4 } }, - { 0xe6940044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3, + { 0xe6950044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3, IIC3_WAITI3, IIC3_DTEI3 } }, - { 0xe6940048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/, + { 0xe6950048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/, 0/*TXI*/, 0/*TEI*/} }, - { 0xe694004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0, + { 0xe695004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0, USB1_USB1I1, USB1_USB1I0 } }, - { 0xe6940050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } }, + { 0xe6950050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } }, }; static struct intc_sense_reg intca_sense_registers[] __initdata = { @@ -363,7 +363,227 @@ static struct intc_desc intca_desc __initdata = { intca_sense_registers, intca_ack_registers), }; +enum { + UNUSED_INTCS = 0, + + INTCS, + + /* interrupt sources INTCS */ + VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3, + RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3, + CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2, + VPU, + TSIF1, + _3DG_SGX530, + _2DDMAC, + IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, + IPMMU_IPMMUR, IPMMU_IPMMUR2, + RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR, + MSIOF, + IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, + TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, + CMT0, + TSIF0, + LMB, + CTI, + ICB, + JPU_JPEG, + LCDC, + LCRC, + RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3, + RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, + ISP, + LCDC1, + CSIRX, + DSITX_DSITX0, + DSITX_DSITX1, + TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2, + CMT4, + DSITX1_DSITX1_0, + DSITX1_DSITX1_1, + CPORTS2R, + JPU6E, + + /* interrupt groups INTCS */ + RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2, + RTDMAC2_1, RTDMAC2_2, TMU1, DSITX, +}; + +static struct intc_vect intcs_vectors[] = { + INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720), + INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760), + INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820), + INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860), + INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0), + INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0), + INTCS_VECT(VPU, 0x980), + INTCS_VECT(TSIF1, 0x9a0), + INTCS_VECT(_3DG_SGX530, 0x9e0), + INTCS_VECT(_2DDMAC, 0xa00), + INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0), + INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0), + INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20), + INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0), + INTCS_VECT(RTDMAC_2_DADERR, 0xbc0), + INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20), + INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60), + INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0), + INTCS_VECT(TMU_TUNI2, 0xec0), + INTCS_VECT(CMT0, 0xf00), + INTCS_VECT(TSIF0, 0xf20), + INTCS_VECT(LMB, 0xf60), + INTCS_VECT(CTI, 0x400), + INTCS_VECT(ICB, 0x480), + INTCS_VECT(JPU_JPEG, 0x560), + INTCS_VECT(LCDC, 0x580), + INTCS_VECT(LCRC, 0x5a0), + INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320), + INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360), + INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13a0), + INTCS_VECT(RTDMAC2_2_DADERR, 0x13c0), + INTCS_VECT(ISP, 0x1720), + INTCS_VECT(LCDC1, 0x1780), + INTCS_VECT(CSIRX, 0x17a0), + INTCS_VECT(DSITX_DSITX0, 0x17c0), + INTCS_VECT(DSITX_DSITX1, 0x17e0), + INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920), + INTCS_VECT(TMU1_TUNI2, 0x1940), + INTCS_VECT(CMT4, 0x1980), + INTCS_VECT(DSITX1_DSITX1_0, 0x19a0), + INTCS_VECT(DSITX1_DSITX1_1, 0x19c0), + INTCS_VECT(CPORTS2R, 0x1a20), + INTCS_VECT(JPU6E, 0x1a80), + + INTC_VECT(INTCS, 0xf80), +}; + +static struct intc_group intcs_groups[] __initdata = { + INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1, + RTDMAC_1_DEI2, RTDMAC_1_DEI3), + INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR), + INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3), + INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2), + INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0), + INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2), + INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2), + INTC_GROUP(RTDMAC2_1, RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, + RTDMAC2_1_DEI2, RTDMAC2_1_DEI3), + INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4, + RTDMAC2_2_DEI5, RTDMAC2_2_DADERR), + INTC_GROUP(TMU1, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0), + INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1), +}; + +static struct intc_mask_reg intcs_mask_registers[] = { + { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */ + { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU, + VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } }, + { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */ + { 0, 0, 0, VPU, + 0, 0, 0, 0 } }, + { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */ + { 0, 0, 0, _2DDMAC, + 0, 0, 0, ICB } }, + { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */ + { 0, 0, 0, CTI, + JPU_JPEG, 0, LCRC, LCDC } }, + { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */ + { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4, + RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } }, + { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */ + { 0, 0, MSIOF, 0, + _3DG_SGX530, 0, 0, 0 } }, + { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */ + { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, + 0, 0, 0, 0 } }, + { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */ + { 0, 0, 0, CMT0, + IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } }, + { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */ + { 0, 0, IPMMU_IPMMUR2, IPMMU_IPMMUR, + 0, 0, 0, 0 } }, + { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */ + { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0, + 0, TSIF1, LMB, TSIF0 } }, + { 0xffd50180, 0xffd501c0, 8, /* IMR0SA3 / IMCR0SA3 */ + { 0, RTDMAC2_2_DADERR, RTDMAC2_2_DEI5, RTDMAC2_2_DEI4, + RTDMAC2_1_DEI3, RTDMAC2_1_DEI2, RTDMAC2_1_DEI1, RTDMAC2_1_DEI0 } }, + { 0xffd50190, 0xffd501d0, 8, /* IMR4SA3 / IMCR4SA3 */ + { 0, ISP, 0, 0, + LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } }, + { 0xffd50198, 0xffd501d8, 8, /* IMR6SA3 / IMCR6SA3 */ + { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, + CMT4, DSITX1_DSITX1_0, DSITX1_DSITX1_1, 0 } }, + { 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */ + { 0, CPORTS2R, 0, 0, + JPU6E, 0, 0, 0 } }, + { 0xffd20104, 0, 16, /* INTAMASK */ + { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, INTCS } }, +}; + +/* Priority is needed for INTCA to receive the INTCS interrupt */ +static struct intc_prio_reg intcs_prio_registers[] = { + { 0xffd20000, 0, 16, 4, /* IPRAS */ { CTI, 0, _2DDMAC, ICB } }, + { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPU_JPEG, LCDC, 0, LCRC } }, + { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, CEU, 0, VPU } }, + { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT0 } }, + { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1, + TMU_TUNI2, TSIF1 } }, + { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0, VEU, BEU } }, + { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, IIC0 } }, + { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX530, 0, 0 } }, + { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, 0, LMB, 0 } }, + { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, 0, 0 } }, + { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } }, + { 0xffd50000, 0, 16, 4, /* IPRAS3 */ { RTDMAC2_1, 0, 0, 0 } }, + { 0xffd50004, 0, 16, 4, /* IPRBS3 */ { RTDMAC2_2, 0, 0, 0 } }, + { 0xffd50020, 0, 16, 4, /* IPRIS3 */ { 0, ISP, 0, 0 } }, + { 0xffd50024, 0, 16, 4, /* IPRJS3 */ { LCDC1, CSIRX, DSITX, 0 } }, + { 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, 0 } }, + { 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, DSITX1_DSITX1_0, + DSITX1_DSITX1_1, 0 } }, + { 0xffd50038, 0, 16, 4, /* IPROS3 */ { 0, CPORTS2R, 0, 0 } }, + { 0xffd5003c, 0, 16, 4, /* IPRPS3 */ { JPU6E, 0, 0, 0 } }, +}; + +static struct resource intcs_resources[] __initdata = { + [0] = { + .start = 0xffd20000, + .end = 0xffd201ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0xffd50000, + .end = 0xffd501ff, + .flags = IORESOURCE_MEM, + } +}; + +static struct intc_desc intcs_desc __initdata = { + .name = "sh7372-intcs", + .resource = intcs_resources, + .num_resources = ARRAY_SIZE(intcs_resources), + .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers, + intcs_prio_registers, NULL, NULL), +}; + +static void intcs_demux(unsigned int irq, struct irq_desc *desc) +{ + void __iomem *reg = (void *)get_irq_data(irq); + unsigned int evtcodeas = ioread32(reg); + + generic_handle_irq(intcs_evt2irq(evtcodeas)); +} + void __init sh7372_init_irq(void) { + void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); + register_intc_controller(&intca_desc); + register_intc_controller(&intcs_desc); + + /* demux using INTEVTSA */ + set_irq_data(evt2irq(0xf80), (void *)intevtsa); + set_irq_chained_handler(evt2irq(0xf80), intcs_demux); } diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c index 5c781e2d1897..2cdeb8ccd821 100644 --- a/arch/arm/mach-shmobile/intc-sh7377.c +++ b/arch/arm/mach-shmobile/intc-sh7377.c @@ -90,7 +90,7 @@ enum { ICUSB, ICUDMC }; -static struct intc_vect intca_vectors[] = { +static struct intc_vect intca_vectors[] __initdata = { INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220), INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260), INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0), @@ -202,7 +202,7 @@ static struct intc_group intca_groups[] __initdata = { INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2), }; -static struct intc_mask_reg intca_mask_registers[] = { +static struct intc_mask_reg intca_mask_registers[] __initdata = { { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */ @@ -272,7 +272,7 @@ static struct intc_mask_reg intca_mask_registers[] = { SCIFA6, 0, 0, 0 } }, }; -static struct intc_prio_reg intca_prio_registers[] = { +static struct intc_prio_reg intca_prio_registers[] __initdata = { { 0xe6900010, 0, 32, 4, /* INTPRI00A */ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, { 0xe6900014, 0, 32, 4, /* INTPRI10A */ @@ -346,7 +346,301 @@ static struct intc_desc intca_desc __initdata = { intca_sense_registers, intca_ack_registers), }; +/* this macro ignore entry which is also in INTCA */ +#define __IGNORE(a...) +#define __IGNORE0(a...) 0 + +enum { + UNUSED_INTCS = 0, + + INTCS, + + /* interrupt sources INTCS */ + VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3, + RTDMAC1_1_DEI0, RTDMAC1_1_DEI1, RTDMAC1_1_DEI2, RTDMAC1_1_DEI3, + CEU, + BEU_BEU0, BEU_BEU1, BEU_BEU2, + __IGNORE(MFI) + __IGNORE(BBIF2) + VPU, + TSIF1, + __IGNORE(SGX540) + _2DDMAC, + IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, + IPMMU_IPMMUR, IPMMU_IPMMUR2, + RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR, + __IGNORE(KEYSC) + __IGNORE(TTI20) + __IGNORE(MSIOF) + IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, + TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, + CMT0, + TSIF0, + __IGNORE(CMT2) + LMB, + __IGNORE(MSUG) + __IGNORE(MSU_MSU, MSU_MSU2) + __IGNORE(CTI) + MVI3, + __IGNORE(RWDT0) + __IGNORE(RWDT1) + ICB, + PEP, + ASA, + __IGNORE(_2DG) + HQE, + JPU, + LCDC0, + __IGNORE(LCRC) + RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3, + RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, + FRC, + LCDC1, + CSIRX, + DSITX_DSITX0, DSITX_DSITX1, + __IGNORE(SPU2_SPU0, SPU2_SPU1) + __IGNORE(FSI) + __IGNORE(FMSI) + __IGNORE(SCUV) + TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, + TSIF2, + CMT4, + __IGNORE(MFIS2) + CPORTS2R, + + /* interrupt groups INTCS */ + RTDMAC1_1, RTDMAC1_2, VEU, BEU, IIC0, __IGNORE(MSU) IPMMU, + IIC2, RTDMAC2_1, RTDMAC2_2, DSITX, __IGNORE(SPU2) TMU1, +}; + +#define INTCS_INTVECT 0x0F80 +static struct intc_vect intcs_vectors[] __initdata = { + INTCS_VECT(VEU_VEU0, 0x0700), INTCS_VECT(VEU_VEU1, 0x0720), + INTCS_VECT(VEU_VEU2, 0x0740), INTCS_VECT(VEU_VEU3, 0x0760), + INTCS_VECT(RTDMAC1_1_DEI0, 0x0800), INTCS_VECT(RTDMAC1_1_DEI1, 0x0820), + INTCS_VECT(RTDMAC1_1_DEI2, 0x0840), INTCS_VECT(RTDMAC1_1_DEI3, 0x0860), + INTCS_VECT(CEU, 0x0880), + INTCS_VECT(BEU_BEU0, 0x08A0), + INTCS_VECT(BEU_BEU1, 0x08C0), + INTCS_VECT(BEU_BEU2, 0x08E0), + __IGNORE(INTCS_VECT(MFI, 0x0900)) + __IGNORE(INTCS_VECT(BBIF2, 0x0960)) + INTCS_VECT(VPU, 0x0980), + INTCS_VECT(TSIF1, 0x09A0), + __IGNORE(INTCS_VECT(SGX540, 0x09E0)) + INTCS_VECT(_2DDMAC, 0x0A00), + INTCS_VECT(IIC2_ALI2, 0x0A80), INTCS_VECT(IIC2_TACKI2, 0x0AA0), + INTCS_VECT(IIC2_WAITI2, 0x0AC0), INTCS_VECT(IIC2_DTEI2, 0x0AE0), + INTCS_VECT(IPMMU_IPMMUR, 0x0B00), INTCS_VECT(IPMMU_IPMMUR2, 0x0B20), + INTCS_VECT(RTDMAC1_2_DEI4, 0x0B80), + INTCS_VECT(RTDMAC1_2_DEI5, 0x0BA0), + INTCS_VECT(RTDMAC1_2_DADERR, 0x0BC0), + __IGNORE(INTCS_VECT(KEYSC 0x0BE0)) + __IGNORE(INTCS_VECT(TTI20, 0x0C80)) + __IGNORE(INTCS_VECT(MSIOF, 0x0D20)) + INTCS_VECT(IIC0_ALI0, 0x0E00), INTCS_VECT(IIC0_TACKI0, 0x0E20), + INTCS_VECT(IIC0_WAITI0, 0x0E40), INTCS_VECT(IIC0_DTEI0, 0x0E60), + INTCS_VECT(TMU_TUNI0, 0x0E80), + INTCS_VECT(TMU_TUNI1, 0x0EA0), + INTCS_VECT(TMU_TUNI2, 0x0EC0), + INTCS_VECT(CMT0, 0x0F00), + INTCS_VECT(TSIF0, 0x0F20), + __IGNORE(INTCS_VECT(CMT2, 0x0F40)) + INTCS_VECT(LMB, 0x0F60), + __IGNORE(INTCS_VECT(MSUG, 0x0F80)) + __IGNORE(INTCS_VECT(MSU_MSU, 0x0FA0)) + __IGNORE(INTCS_VECT(MSU_MSU2, 0x0FC0)) + __IGNORE(INTCS_VECT(CTI, 0x0400)) + INTCS_VECT(MVI3, 0x0420), + __IGNORE(INTCS_VECT(RWDT0, 0x0440)) + __IGNORE(INTCS_VECT(RWDT1, 0x0460)) + INTCS_VECT(ICB, 0x0480), + INTCS_VECT(PEP, 0x04A0), + INTCS_VECT(ASA, 0x04C0), + __IGNORE(INTCS_VECT(_2DG, 0x04E0)) + INTCS_VECT(HQE, 0x0540), + INTCS_VECT(JPU, 0x0560), + INTCS_VECT(LCDC0, 0x0580), + __IGNORE(INTCS_VECT(LCRC, 0x05A0)) + INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320), + INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360), + INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13A0), + INTCS_VECT(RTDMAC2_2_DADERR, 0x13C0), + INTCS_VECT(FRC, 0x1700), + INTCS_VECT(LCDC1, 0x1780), + INTCS_VECT(CSIRX, 0x17A0), + INTCS_VECT(DSITX_DSITX0, 0x17C0), INTCS_VECT(DSITX_DSITX1, 0x17E0), + __IGNORE(INTCS_VECT(SPU2_SPU0, 0x1800)) + __IGNORE(INTCS_VECT(SPU2_SPU1, 0x1820)) + __IGNORE(INTCS_VECT(FSI, 0x1840)) + __IGNORE(INTCS_VECT(FMSI, 0x1860)) + __IGNORE(INTCS_VECT(SCUV, 0x1880)) + INTCS_VECT(TMU1_TUNI10, 0x1900), INTCS_VECT(TMU1_TUNI11, 0x1920), + INTCS_VECT(TMU1_TUNI12, 0x1940), + INTCS_VECT(TSIF2, 0x1960), + INTCS_VECT(CMT4, 0x1980), + __IGNORE(INTCS_VECT(MFIS2, 0x1A00)) + INTCS_VECT(CPORTS2R, 0x1A20), + + INTC_VECT(INTCS, INTCS_INTVECT), +}; + +static struct intc_group intcs_groups[] __initdata = { + INTC_GROUP(RTDMAC1_1, + RTDMAC1_1_DEI0, RTDMAC1_1_DEI1, + RTDMAC1_1_DEI2, RTDMAC1_1_DEI3), + INTC_GROUP(RTDMAC1_2, + RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR), + INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3), + INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2), + INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0), + __IGNORE(INTC_GROUP(MSU, MSU_MSU, MSU_MSU2)) + INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2), + INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2), + INTC_GROUP(RTDMAC2_1, + RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, + RTDMAC2_1_DEI2, RTDMAC2_1_DEI3), + INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR), + INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1), + __IGNORE(INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1)) + INTC_GROUP(TMU1, TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12), +}; + +static struct intc_mask_reg intcs_mask_registers[] __initdata = { + { 0xE6940184, 0xE69401C4, 8, /* IMR1AS / IMCR1AS */ + { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU, + VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } }, + { 0xE6940188, 0xE69401C8, 8, /* IMR2AS / IMCR2AS */ + { 0, 0, 0, VPU, + __IGNORE0(BBIF2), 0, 0, __IGNORE0(MFI) } }, + { 0xE694018C, 0xE69401CC, 8, /* IMR3AS / IMCR3AS */ + { 0, 0, 0, _2DDMAC, + __IGNORE0(_2DG), ASA, PEP, ICB } }, + { 0xE6940190, 0xE69401D0, 8, /* IMR4AS / IMCR4AS */ + { 0, 0, MVI3, __IGNORE0(CTI), + JPU, HQE, __IGNORE0(LCRC), LCDC0 } }, + { 0xE6940194, 0xE69401D4, 8, /* IMR5AS / IMCR5AS */ + { __IGNORE0(KEYSC), RTDMAC1_2_DADERR, RTDMAC1_2_DEI5, RTDMAC1_2_DEI4, + RTDMAC1_1_DEI3, RTDMAC1_1_DEI2, RTDMAC1_1_DEI1, RTDMAC1_1_DEI0 } }, + __IGNORE({ 0xE6940198, 0xE69401D8, 8, /* IMR6AS / IMCR6AS */ + { 0, 0, MSIOF, 0, + SGX540, 0, TTI20, 0 } }) + { 0xE694019C, 0xE69401DC, 8, /* IMR7AS / IMCR7AS */ + { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, + 0, 0, 0, 0 } }, + __IGNORE({ 0xE69401A0, 0xE69401E0, 8, /* IMR8AS / IMCR8AS */ + { 0, 0, 0, 0, + 0, MSU_MSU, MSU_MSU2, MSUG } }) + { 0xE69401A4, 0xE69401E4, 8, /* IMR9AS / IMCR9AS */ + { __IGNORE0(RWDT1), __IGNORE0(RWDT0), __IGNORE0(CMT2), CMT0, + IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } }, + { 0xE69401A8, 0xE69401E8, 8, /* IMR10AS / IMCR10AS */ + { 0, 0, IPMMU_IPMMUR, IPMMU_IPMMUR2, + 0, 0, 0, 0 } }, + { 0xE69401AC, 0xE69401EC, 8, /* IMR11AS / IMCR11AS */ + { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0, + 0, TSIF1, LMB, TSIF0 } }, + { 0xE6950180, 0xE69501C0, 8, /* IMR0AS3 / IMCR0AS3 */ + { RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3, + RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, 0 } }, + { 0xE6950190, 0xE69501D0, 8, /* IMR4AS3 / IMCR4AS3 */ + { FRC, 0, 0, 0, + LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } }, + __IGNORE({ 0xE6950194, 0xE69501D4, 8, /* IMR5AS3 / IMCR5AS3 */ + {SPU2_SPU0, SPU2_SPU1, FSI, FMSI, + SCUV, 0, 0, 0 } }) + { 0xE6950198, 0xE69501D8, 8, /* IMR6AS3 / IMCR6AS3 */ + { TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, TSIF2, + CMT4, 0, 0, 0 } }, + { 0xE695019C, 0xE69501DC, 8, /* IMR7AS3 / IMCR7AS3 */ + { __IGNORE0(MFIS2), CPORTS2R, 0, 0, + 0, 0, 0, 0 } }, + { 0xFFD20104, 0, 16, /* INTAMASK */ + { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, INTCS } } +}; + +static struct intc_prio_reg intcs_prio_registers[] __initdata = { + /* IPRAS */ + { 0xFFD20000, 0, 16, 4, { __IGNORE0(CTI), MVI3, _2DDMAC, ICB } }, + /* IPRBS */ + { 0xFFD20004, 0, 16, 4, { JPU, LCDC0, 0, __IGNORE0(LCRC) } }, + /* IPRCS */ + __IGNORE({ 0xFFD20008, 0, 16, 4, { BBIF2, 0, 0, 0 } }) + /* IPRES */ + { 0xFFD20010, 0, 16, 4, { RTDMAC1_1, CEU, __IGNORE0(MFI), VPU } }, + /* IPRFS */ + { 0xFFD20014, 0, 16, 4, + { __IGNORE0(KEYSC), RTDMAC1_2, __IGNORE0(CMT2), CMT0 } }, + /* IPRGS */ + { 0xFFD20018, 0, 16, 4, { TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, TSIF1 } }, + /* IPRHS */ + { 0xFFD2001C, 0, 16, 4, { __IGNORE0(TTI20), 0, VEU, BEU } }, + /* IPRIS */ + { 0xFFD20020, 0, 16, 4, { 0, __IGNORE0(MSIOF), TSIF0, IIC0 } }, + /* IPRJS */ + __IGNORE({ 0xFFD20024, 0, 16, 4, { 0, SGX540, MSUG, MSU } }) + /* IPRKS */ + { 0xFFD20028, 0, 16, 4, { __IGNORE0(_2DG), ASA, LMB, PEP } }, + /* IPRLS */ + { 0xFFD2002C, 0, 16, 4, { IPMMU, 0, 0, HQE } }, + /* IPRMS */ + { 0xFFD20030, 0, 16, 4, + { IIC2, 0, __IGNORE0(RWDT1), __IGNORE0(RWDT0) } }, + /* IPRAS3 */ + { 0xFFD50000, 0, 16, 4, { RTDMAC2_1, 0, 0, 0 } }, + /* IPRBS3 */ + { 0xFFD50004, 0, 16, 4, { RTDMAC2_2, 0, 0, 0 } }, + /* IPRIS3 */ + { 0xFFD50020, 0, 16, 4, { FRC, 0, 0, 0 } }, + /* IPRJS3 */ + { 0xFFD50024, 0, 16, 4, { LCDC1, CSIRX, DSITX, 0 } }, + /* IPRKS3 */ + __IGNORE({ 0xFFD50028, 0, 16, 4, { SPU2, 0, FSI, FMSI } }) + /* IPRLS3 */ + __IGNORE({ 0xFFD5002C, 0, 16, 4, { SCUV, 0, 0, 0 } }) + /* IPRMS3 */ + { 0xFFD50030, 0, 16, 4, { TMU1, 0, 0, TSIF2 } }, + /* IPRNS3 */ + { 0xFFD50034, 0, 16, 4, { CMT4, 0, 0, 0 } }, + /* IPROS3 */ + { 0xFFD50038, 0, 16, 4, { __IGNORE0(MFIS2), CPORTS2R, 0, 0 } }, +}; + +static struct resource intcs_resources[] __initdata = { + [0] = { + .start = 0xffd20000, + .end = 0xffd500ff, + .flags = IORESOURCE_MEM, + } +}; + +static struct intc_desc intcs_desc __initdata = { + .name = "sh7377-intcs", + .resource = intcs_resources, + .num_resources = ARRAY_SIZE(intcs_resources), + .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, + intcs_mask_registers, intcs_prio_registers, + NULL, NULL), +}; + +static void intcs_demux(unsigned int irq, struct irq_desc *desc) +{ + void __iomem *reg = (void *)get_irq_data(irq); + unsigned int evtcodeas = ioread32(reg); + + generic_handle_irq(intcs_evt2irq(evtcodeas)); +} + +#define INTEVTSA 0xFFD20100 void __init sh7377_init_irq(void) { + void __iomem *intevtsa = ioremap_nocache(INTEVTSA, PAGE_SIZE); + register_intc_controller(&intca_desc); + register_intc_controller(&intcs_desc); + + /* demux using INTEVTSA */ + set_irq_data(evt2irq(INTCS_INTVECT), (void *)intevtsa); + set_irq_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux); } diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c index eca90716140e..3148c11a550e 100644 --- a/arch/arm/mach-shmobile/setup-sh7367.c +++ b/arch/arm/mach-shmobile/setup-sh7367.c @@ -31,11 +31,13 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +/* SCIFA0 */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xe6c40000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, + .irqs = { evt2irq(0xc00), evt2irq(0xc00), + evt2irq(0xc00), evt2irq(0xc00) }, }; static struct platform_device scif0_device = { @@ -46,11 +48,13 @@ static struct platform_device scif0_device = { }, }; +/* SCIFA1 */ static struct plat_sci_port scif1_platform_data = { .mapbase = 0xe6c50000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, + .irqs = { evt2irq(0xc20), evt2irq(0xc20), + evt2irq(0xc20), evt2irq(0xc20) }, }; static struct platform_device scif1_device = { @@ -61,11 +65,13 @@ static struct platform_device scif1_device = { }, }; +/* SCIFA2 */ static struct plat_sci_port scif2_platform_data = { .mapbase = 0xe6c60000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, + .irqs = { evt2irq(0xc40), evt2irq(0xc40), + evt2irq(0xc40), evt2irq(0xc40) }, }; static struct platform_device scif2_device = { @@ -76,11 +82,13 @@ static struct platform_device scif2_device = { }, }; +/* SCIFA3 */ static struct plat_sci_port scif3_platform_data = { .mapbase = 0xe6c70000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 83, 83, 83, 83 }, + .irqs = { evt2irq(0xc60), evt2irq(0xc60), + evt2irq(0xc60), evt2irq(0xc60) }, }; static struct platform_device scif3_device = { @@ -91,11 +99,13 @@ static struct platform_device scif3_device = { }, }; +/* SCIFA4 */ static struct plat_sci_port scif4_platform_data = { .mapbase = 0xe6c80000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 89, 89, 89, 89 }, + .irqs = { evt2irq(0xd20), evt2irq(0xd20), + evt2irq(0xd20), evt2irq(0xd20) }, }; static struct platform_device scif4_device = { @@ -106,11 +116,13 @@ static struct platform_device scif4_device = { }, }; +/* SCIFA5 */ static struct plat_sci_port scif5_platform_data = { .mapbase = 0xe6cb0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 90, 90, 90, 90 }, + .irqs = { evt2irq(0xd40), evt2irq(0xd40), + evt2irq(0xd40), evt2irq(0xd40) }, }; static struct platform_device scif5_device = { @@ -121,11 +133,13 @@ static struct platform_device scif5_device = { }, }; +/* SCIFB */ static struct plat_sci_port scif6_platform_data = { .mapbase = 0xe6c30000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 91, 91, 91, 91 }, + .irqs = { evt2irq(0xd60), evt2irq(0xd60), + evt2irq(0xd60), evt2irq(0xd60) }, }; static struct platform_device scif6_device = { @@ -153,7 +167,7 @@ static struct resource cmt10_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 72, + .start = evt2irq(0xb00), /* CMT1_CMT10 */ .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 1d1153290f59..d1a8095a19eb 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -32,11 +32,13 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +/* SCIFA0 */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xe6c40000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0c00), evt2irq(0x0c00), + evt2irq(0x0c00), evt2irq(0x0c00) }, }; static struct platform_device scif0_device = { @@ -47,11 +49,13 @@ static struct platform_device scif0_device = { }, }; +/* SCIFA1 */ static struct plat_sci_port scif1_platform_data = { .mapbase = 0xe6c50000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0c20), evt2irq(0x0c20), + evt2irq(0x0c20), evt2irq(0x0c20) }, }; static struct platform_device scif1_device = { @@ -62,11 +66,13 @@ static struct platform_device scif1_device = { }, }; +/* SCIFA2 */ static struct plat_sci_port scif2_platform_data = { .mapbase = 0xe6c60000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0c40), evt2irq(0x0c40), + evt2irq(0x0c40), evt2irq(0x0c40) }, }; static struct platform_device scif2_device = { @@ -77,11 +83,13 @@ static struct platform_device scif2_device = { }, }; +/* SCIFA3 */ static struct plat_sci_port scif3_platform_data = { .mapbase = 0xe6c70000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 83, 83, 83, 83 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0c60), evt2irq(0x0c60), + evt2irq(0x0c60), evt2irq(0x0c60) }, }; static struct platform_device scif3_device = { @@ -92,11 +100,13 @@ static struct platform_device scif3_device = { }, }; +/* SCIFA4 */ static struct plat_sci_port scif4_platform_data = { .mapbase = 0xe6c80000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 89, 89, 89, 89 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0d20), evt2irq(0x0d20), + evt2irq(0x0d20), evt2irq(0x0d20) }, }; static struct platform_device scif4_device = { @@ -107,11 +117,13 @@ static struct platform_device scif4_device = { }, }; +/* SCIFA5 */ static struct plat_sci_port scif5_platform_data = { .mapbase = 0xe6cb0000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 90, 90, 90, 90 }, + .type = PORT_SCIFA, + .irqs = { evt2irq(0x0d40), evt2irq(0x0d40), + evt2irq(0x0d40), evt2irq(0x0d40) }, }; static struct platform_device scif5_device = { @@ -122,11 +134,13 @@ static struct platform_device scif5_device = { }, }; +/* SCIFB */ static struct plat_sci_port scif6_platform_data = { .mapbase = 0xe6c30000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 91, 91, 91, 91 }, + .type = PORT_SCIFB, + .irqs = { evt2irq(0x0d60), evt2irq(0x0d60), + evt2irq(0x0d60), evt2irq(0x0d60) }, }; static struct platform_device scif6_device = { @@ -137,11 +151,12 @@ static struct platform_device scif6_device = { }, }; +/* CMT */ static struct sh_timer_config cmt10_platform_data = { .name = "CMT10", .channel_offset = 0x10, .timer_bit = 0, - .clk = "r_clk", + .clk = "cmt1", .clockevent_rating = 125, .clocksource_rating = 125, }; @@ -154,7 +169,7 @@ static struct resource cmt10_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 72, + .start = evt2irq(0x0b00), /* CMT1_CMT10 */ .flags = IORESOURCE_IRQ, }, }; @@ -169,6 +184,49 @@ static struct platform_device cmt10_device = { .num_resources = ARRAY_SIZE(cmt10_resources), }; +/* I2C */ +static struct resource iic0_resources[] = { + [0] = { + .name = "IIC0", + .start = 0xFFF20000, + .end = 0xFFF20425 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = intcs_evt2irq(0xe00), /* IIC0_ALI0 */ + .end = intcs_evt2irq(0xe60), /* IIC0_DTEI0 */ + .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 = 0xE6C20000, + .end = 0xE6C20425 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = evt2irq(0x780), /* IIC1_ALI1 */ + .end = evt2irq(0x7e0), /* IIC1_DTEI1 */ + .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 platform_device *sh7372_early_devices[] __initdata = { &scif0_device, &scif1_device, @@ -178,6 +236,8 @@ static struct platform_device *sh7372_early_devices[] __initdata = { &scif5_device, &scif6_device, &cmt10_device, + &iic0_device, + &iic1_device, }; void __init sh7372_add_standard_devices(void) @@ -186,14 +246,8 @@ void __init sh7372_add_standard_devices(void) ARRAY_SIZE(sh7372_early_devices)); } -#define SMSTPCR3 0xe615013c -#define SMSTPCR3_CMT1 (1 << 29) - void __init sh7372_add_early_devices(void) { - /* enable clock to CMT1 */ - __raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3); - early_platform_add_devices(sh7372_early_devices, ARRAY_SIZE(sh7372_early_devices)); } diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c index 60e37774c35c..bb4adf17dbf4 100644 --- a/arch/arm/mach-shmobile/setup-sh7377.c +++ b/arch/arm/mach-shmobile/setup-sh7377.c @@ -32,11 +32,13 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +/* SCIFA0 */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xe6c40000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, + .irqs = { evt2irq(0xc00), evt2irq(0xc00), + evt2irq(0xc00), evt2irq(0xc00) }, }; static struct platform_device scif0_device = { @@ -47,11 +49,13 @@ static struct platform_device scif0_device = { }, }; +/* SCIFA1 */ static struct plat_sci_port scif1_platform_data = { .mapbase = 0xe6c50000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, + .irqs = { evt2irq(0xc20), evt2irq(0xc20), + evt2irq(0xc20), evt2irq(0xc20) }, }; static struct platform_device scif1_device = { @@ -62,11 +66,13 @@ static struct platform_device scif1_device = { }, }; +/* SCIFA2 */ static struct plat_sci_port scif2_platform_data = { .mapbase = 0xe6c60000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, + .irqs = { evt2irq(0xc40), evt2irq(0xc40), + evt2irq(0xc40), evt2irq(0xc40) }, }; static struct platform_device scif2_device = { @@ -77,11 +83,13 @@ static struct platform_device scif2_device = { }, }; +/* SCIFA3 */ static struct plat_sci_port scif3_platform_data = { .mapbase = 0xe6c70000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 83, 83, 83, 83 }, + .irqs = { evt2irq(0xc60), evt2irq(0xc60), + evt2irq(0xc60), evt2irq(0xc60) }, }; static struct platform_device scif3_device = { @@ -92,11 +100,13 @@ static struct platform_device scif3_device = { }, }; +/* SCIFA4 */ static struct plat_sci_port scif4_platform_data = { .mapbase = 0xe6c80000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 89, 89, 89, 89 }, + .irqs = { evt2irq(0xd20), evt2irq(0xd20), + evt2irq(0xd20), evt2irq(0xd20) }, }; static struct platform_device scif4_device = { @@ -107,11 +117,13 @@ static struct platform_device scif4_device = { }, }; +/* SCIFA5 */ static struct plat_sci_port scif5_platform_data = { .mapbase = 0xe6cb0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 90, 90, 90, 90 }, + .irqs = { evt2irq(0xd40), evt2irq(0xd40), + evt2irq(0xd40), evt2irq(0xd40) }, }; static struct platform_device scif5_device = { @@ -122,11 +134,13 @@ static struct platform_device scif5_device = { }, }; +/* SCIFA6 */ static struct plat_sci_port scif6_platform_data = { .mapbase = 0xe6cc0000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 196, 196, 196, 196 }, + .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80), + intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) }, }; static struct platform_device scif6_device = { @@ -137,11 +151,13 @@ static struct platform_device scif6_device = { }, }; +/* SCIFB */ static struct plat_sci_port scif7_platform_data = { .mapbase = 0xe6c30000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 91, 91, 91, 91 }, + .irqs = { evt2irq(0xd60), evt2irq(0xd60), + evt2irq(0xd60), evt2irq(0xd60) }, }; static struct platform_device scif7_device = { @@ -169,7 +185,7 @@ static struct resource cmt10_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 72, + .start = evt2irq(0xb00), /* CMT1_CMT10 */ .flags = IORESOURCE_IRQ, }, }; |