diff options
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r-- | arch/arm/mach-shmobile/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 460 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7367.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7372.c | 189 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7377.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/entry-macro.S | 30 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/gpio.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/sh7372.h | 12 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/vmalloc.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/intc-sh7372.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/pfc-sh7372.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-sh7367.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-sh7372.c | 94 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-sh7377.c | 1 |
14 files changed, 662 insertions, 175 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 54b479c35ee..51dcd59eda6 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -116,4 +116,6 @@ endmenu config SH_CLK_CPG bool +source "drivers/sh/Kconfig" + endif diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 14923989ea0..d440e5f456a 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -30,7 +30,6 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> -#include <linux/mmc/host.h> #include <linux/mmc/sh_mmcif.h> #include <linux/i2c.h> #include <linux/i2c/tsc2007.h> @@ -44,6 +43,10 @@ #include <linux/input/sh_keysc.h> #include <linux/usb/r8a66597.h> +#include <media/sh_mobile_ceu.h> +#include <media/sh_mobile_csi2.h> +#include <media/soc_camera.h> + #include <sound/sh_fsi.h> #include <video/sh_mobile_hdmi.h> @@ -160,11 +163,13 @@ static struct mtd_partition nor_flash_partitions[] = { .name = "loader", .offset = 0x00000000, .size = 512 * 1024, + .mask_flags = MTD_WRITEABLE, }, { .name = "bootenv", .offset = MTDPART_OFS_APPEND, .size = 512 * 1024, + .mask_flags = MTD_WRITEABLE, }, { .name = "kernel_ro", @@ -235,10 +240,22 @@ static struct platform_device smc911x_device = { }, }; +/* + * The card detect pin of the top SD/MMC slot (CN7) is active low and is + * connected to GPIO A22 of SH7372 (GPIO_PORT41). + */ +static int slot_cn7_get_cd(struct platform_device *pdev) +{ + if (gpio_is_valid(GPIO_PORT41)) + return !gpio_get_value(GPIO_PORT41); + else + return -ENXIO; +} + /* SH_MMCIF */ static struct resource sh_mmcif_resources[] = { [0] = { - .name = "SH_MMCIF", + .name = "MMCIF", .start = 0xE6BD0000, .end = 0xE6BD00FF, .flags = IORESOURCE_MEM, @@ -261,6 +278,7 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = { .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_NEEDS_POLL, + .get_cd = slot_cn7_get_cd, }; static struct platform_device sh_mmcif_device = { @@ -310,6 +328,8 @@ static struct sh_mobile_sdhi_info sdhi1_info = { .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, .tmio_ocr_mask = MMC_VDD_165_195, .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, + .tmio_caps = MMC_CAP_NEEDS_POLL, + .get_cd = slot_cn7_get_cd, }; static struct resource sdhi1_resources[] = { @@ -375,10 +395,40 @@ static struct platform_device usb1_host_device = { .resource = usb1_host_resources, }; +const static struct fb_videomode ap4evb_lcdc_modes[] = { + { +#ifdef CONFIG_AP4EVB_QHD + .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, +#else + .name = "WVGA Panel", + .xres = 800, + .yres = 480, + .left_margin = 220, + .right_margin = 110, + .hsync_len = 70, + .upper_margin = 20, + .lower_margin = 5, + .vsync_len = 5, + .sync = 0, +#endif + }, +}; + static struct sh_mobile_lcdc_info lcdc_info = { .ch[0] = { .chan = LCDC_CHAN_MAINLCD, .bpp = 16, + .lcd_cfg = ap4evb_lcdc_modes, + .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes), } }; @@ -517,26 +567,130 @@ static struct platform_device *qhd_devices[] __initdata = { /* FSI */ #define IRQ_FSI evt2irq(0x1840) -#define FSIACKCR 0xE6150018 -static void fsiackcr_init(struct clk *clk) +static int __fsi_set_rate(struct clk *clk, long rate, int enable) { - u32 status = __raw_readl(clk->enable_reg); + int ret = 0; + + if (rate <= 0) + return ret; + + if (enable) { + ret = clk_set_rate(clk, rate); + if (0 == ret) + ret = clk_enable(clk); + } else { + clk_disable(clk); + } - /* use external clock */ - status &= ~0x000000ff; - status |= 0x00000080; - __raw_writel(status, clk->enable_reg); + return ret; } -static struct clk_ops fsiackcr_clk_ops = { - .init = fsiackcr_init, -}; +static int __fsi_set_round_rate(struct clk *clk, long rate, int enable) +{ + return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable); +} -static struct clk fsiackcr_clk = { - .ops = &fsiackcr_clk_ops, - .enable_reg = (void __iomem *)FSIACKCR, - .rate = 0, /* unknown */ -}; +static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable) +{ + struct clk *fsia_ick; + struct clk *fsiack; + int ret = -EIO; + + fsia_ick = clk_get(dev, "icka"); + if (IS_ERR(fsia_ick)) + return PTR_ERR(fsia_ick); + + /* + * FSIACK is connected to AK4642, + * and use external clock pin from it. + * it is parent of fsia_ick now. + */ + fsiack = clk_get_parent(fsia_ick); + if (!fsiack) + goto fsia_ick_out; + + /* + * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick + * + ** FIXME ** + * Because the freq_table of external clk (fsiack) are all 0, + * the return value of clk_round_rate became 0. + * So, it use __fsi_set_rate here. + */ + ret = __fsi_set_rate(fsiack, rate, enable); + if (ret < 0) + goto fsiack_out; + + ret = __fsi_set_round_rate(fsia_ick, rate, enable); + if ((ret < 0) && enable) + __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */ + +fsiack_out: + clk_put(fsiack); + +fsia_ick_out: + clk_put(fsia_ick); + + return 0; +} + +static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable) +{ + struct clk *fsib_clk; + struct clk *fdiv_clk = &sh7372_fsidivb_clk; + long fsib_rate = 0; + long fdiv_rate = 0; + int ackmd_bpfmd; + int ret; + + switch (rate) { + case 44100: + fsib_rate = rate * 256; + ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; + break; + case 48000: + fsib_rate = 85428000; /* around 48kHz x 256 x 7 */ + fdiv_rate = rate * 256; + ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; + break; + default: + pr_err("unsupported rate in FSI2 port B\n"); + return -EINVAL; + } + + /* FSI B setting */ + fsib_clk = clk_get(dev, "ickb"); + if (IS_ERR(fsib_clk)) + return -EIO; + + ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable); + clk_put(fsib_clk); + if (ret < 0) + return ret; + + /* FSI DIV setting */ + ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable); + if (ret < 0) { + /* disable FSI B */ + if (enable) + __fsi_set_round_rate(fsib_clk, fsib_rate, 0); + return ret; + } + + return ackmd_bpfmd; +} + +static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable) +{ + int ret; + + if (is_porta) + ret = fsi_ak4642_set_rate(dev, rate, enable); + else + ret = fsi_hdmi_set_rate(dev, rate, enable); + + return ret; +} static struct sh_fsi_platform_info fsi_info = { .porta_flags = SH_FSI_BRS_INV | @@ -544,6 +698,12 @@ static struct sh_fsi_platform_info fsi_info = { SH_FSI_IN_SLAVE_MODE | SH_FSI_OFMT(PCM) | SH_FSI_IFMT(PCM), + + .portb_flags = SH_FSI_BRS_INV | + SH_FSI_BRM_INV | + SH_FSI_LRS_INV | + SH_FSI_OFMT(SPDIF), + .set_rate = fsi_set_rate, }; static struct resource fsi_resources[] = { @@ -577,26 +737,6 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = { .interface_type = RGB24, .clock_divider = 1, .flags = LCDC_FLAGS_DWPOL, - .lcd_cfg = { - .name = "HDMI", - /* So far only 720p is supported */ - .xres = 1280, - .yres = 720, - /* - * If left and right margins are not multiples of 8, - * LDHAJR will be adjusted accordingly by the LCDC - * driver. Until we start using EDID, these values - * might have to be adjusted for different monitors. - */ - .left_margin = 200, - .right_margin = 88, - .hsync_len = 48, - .upper_margin = 20, - .lower_margin = 5, - .vsync_len = 5, - .pixclock = 13468, - .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, - }, } }; @@ -608,7 +748,7 @@ static struct resource lcdc1_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = intcs_evt2irq(0x17a0), + .start = intcs_evt2irq(0x1780), .flags = IORESOURCE_IRQ, }, }; @@ -627,6 +767,7 @@ static struct platform_device lcdc1_device = { static struct sh_mobile_hdmi_info hdmi_info = { .lcd_chan = &sh_mobile_lcdc1_info.ch[0], .lcd_dev = &lcdc1_device.dev, + .flags = HDMI_SND_SRC_SPDIF, }; static struct resource hdmi_resources[] = { @@ -689,6 +830,95 @@ static struct platform_device leds_device = { }, }; +static struct i2c_board_info imx074_info = { + I2C_BOARD_INFO("imx074", 0x1a), +}; + +struct soc_camera_link imx074_link = { + .bus_id = 0, + .board_info = &imx074_info, + .i2c_adapter_id = 0, + .module_name = "imx074", +}; + +static struct platform_device ap4evb_camera = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &imx074_link, + }, +}; + +static struct sh_csi2_client_config csi2_clients[] = { + { + .phy = SH_CSI2_PHY_MAIN, + .lanes = 3, + .channel = 0, + .pdev = &ap4evb_camera, + }, +}; + +static struct sh_csi2_pdata csi2_info = { + .type = SH_CSI2C, + .clients = csi2_clients, + .num_clients = ARRAY_SIZE(csi2_clients), + .flags = SH_CSI2_ECC | SH_CSI2_CRC, +}; + +static struct resource csi2_resources[] = { + [0] = { + .name = "CSI2", + .start = 0xffc90000, + .end = 0xffc90fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = intcs_evt2irq(0x17a0), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device csi2_device = { + .name = "sh-mobile-csi2", + .id = 0, + .num_resources = ARRAY_SIZE(csi2_resources), + .resource = csi2_resources, + .dev = { + .platform_data = &csi2_info, + }, +}; + +static struct sh_mobile_ceu_info sh_mobile_ceu_info = { + .flags = SH_CEU_FLAG_USE_8BIT_BUS, + .csi2_dev = &csi2_device.dev, +}; + +static struct resource ceu_resources[] = { + [0] = { + .name = "CEU", + .start = 0xfe910000, + .end = 0xfe91009f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = intcs_evt2irq(0x880), + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* place holder for contiguous memory */ + }, +}; + +static struct platform_device ceu_device = { + .name = "sh_mobile_ceu", + .id = 0, /* "ceu0" clock */ + .num_resources = ARRAY_SIZE(ceu_resources), + .resource = ceu_resources, + .dev = { + .platform_data = &sh_mobile_ceu_info, + }, +}; + static struct platform_device *ap4evb_devices[] __initdata = { &leds_device, &nor_flash_device, @@ -701,6 +931,9 @@ static struct platform_device *ap4evb_devices[] __initdata = { &lcdc1_device, &lcdc_device, &hdmi_device, + &csi2_device, + &ceu_device, + &ap4evb_camera, }; static int __init hdmi_init_pm_clock(void) @@ -715,30 +948,35 @@ static int __init hdmi_init_pm_clock(void) goto out; } - ret = clk_set_parent(&pllc2_clk, &dv_clki_div2_clk); + ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk); if (ret < 0) { - pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, pllc2_clk.usecount); + pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, sh7372_pllc2_clk.usecount); goto out; } - pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&pllc2_clk)); + pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&sh7372_pllc2_clk)); - rate = clk_round_rate(&pllc2_clk, 594000000); + rate = clk_round_rate(&sh7372_pllc2_clk, 594000000); if (rate < 0) { pr_err("Cannot get suitable rate: %ld\n", rate); ret = rate; goto out; } - ret = clk_set_rate(&pllc2_clk, rate); + ret = clk_set_rate(&sh7372_pllc2_clk, rate); if (ret < 0) { pr_err("Cannot set rate %ld: %d\n", rate, ret); goto out; } + ret = clk_enable(&sh7372_pllc2_clk); + if (ret < 0) { + pr_err("Cannot enable pllc2 clock\n"); + goto out; + } pr_debug("PLLC2 set frequency %lu\n", rate); - ret = clk_set_parent(hdmi_ick, &pllc2_clk); + ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); if (ret < 0) { pr_err("Cannot set HDMI parent: %d\n", ret); goto out; @@ -752,11 +990,32 @@ out: device_initcall(hdmi_init_pm_clock); +static int __init fsi_init_pm_clock(void) +{ + struct clk *fsia_ick; + int ret; + + fsia_ick = clk_get(&fsi_device.dev, "icka"); + if (IS_ERR(fsia_ick)) { + ret = PTR_ERR(fsia_ick); + pr_err("Cannot get FSI ICK: %d\n", ret); + return ret; + } + + ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); + if (ret < 0) + pr_err("Cannot set FSI-A parent: %d\n", ret); + + clk_put(fsia_ick); + + return ret; +} +device_initcall(fsi_init_pm_clock); + /* * FIXME !! * * gpio_no_direction - * gpio_pull_up * are quick_hack. * * current gpio frame work doesn't have @@ -768,49 +1027,37 @@ static void __init gpio_no_direction(u32 addr) __raw_writeb(0x00, addr); } -static void __init gpio_pull_up(u32 addr) -{ - u8 data = __raw_readb(addr); - - data &= 0x0F; - data |= 0xC0; - __raw_writeb(data, addr); -} - /* TouchScreen */ +#ifdef CONFIG_AP4EVB_QHD +# define GPIO_TSC_IRQ GPIO_FN_IRQ28_123 +# define GPIO_TSC_PORT GPIO_PORT123 +#else /* WVGA */ +# define GPIO_TSC_IRQ GPIO_FN_IRQ7_40 +# define GPIO_TSC_PORT GPIO_PORT40 +#endif + #define IRQ28 evt2irq(0x3380) /* IRQ28A */ #define IRQ7 evt2irq(0x02e0) /* IRQ7A */ static int ts_get_pendown_state(void) { - int val1, val2; + int val; - gpio_free(GPIO_FN_IRQ28_123); - gpio_free(GPIO_FN_IRQ7_40); + gpio_free(GPIO_TSC_IRQ); - gpio_request(GPIO_PORT123, NULL); - gpio_request(GPIO_PORT40, NULL); + gpio_request(GPIO_TSC_PORT, NULL); - gpio_direction_input(GPIO_PORT123); - gpio_direction_input(GPIO_PORT40); + gpio_direction_input(GPIO_TSC_PORT); - val1 = gpio_get_value(GPIO_PORT123); - val2 = gpio_get_value(GPIO_PORT40); + val = gpio_get_value(GPIO_TSC_PORT); - gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ - gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */ + gpio_request(GPIO_TSC_IRQ, NULL); - return val1 ^ val2; + return !val; } -#define PORT40CR 0xE6051028 -#define PORT123CR 0xE605007B static int ts_init(void) { - gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ - gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */ - - gpio_pull_up(PORT40CR); - gpio_pull_up(PORT123CR); + gpio_request(GPIO_TSC_IRQ, NULL); return 0; } @@ -865,6 +1112,7 @@ static void __init ap4evb_map_io(void) #define GPIO_PORT9CR 0xE6051009 #define GPIO_PORT10CR 0xE605100A +#define USCCR1 0xE6058144 static void __init ap4evb_init(void) { u32 srcr4; @@ -935,7 +1183,7 @@ static void __init ap4evb_init(void) /* setup USB phy */ __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */ - /* enable FSI2 */ + /* enable FSI2 port A (ak4643) */ gpio_request(GPIO_FN_FSIAIBT, NULL); gpio_request(GPIO_FN_FSIAILR, NULL); gpio_request(GPIO_FN_FSIAISLD, NULL); @@ -948,6 +1196,14 @@ static void __init ap4evb_init(void) gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */ gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */ + /* card detect pin for MMC slot (CN7) */ + gpio_request(GPIO_PORT41, NULL); + gpio_direction_input(GPIO_PORT41); + + /* setup FSI2 port B (HDMI) */ + gpio_request(GPIO_FN_FSIBCK, NULL); + __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */ + /* set SPU2 clock to 119.6 MHz */ clk = clk_get(NULL, "spu_clk"); if (!IS_ERR(clk)) { @@ -955,14 +1211,6 @@ static void __init ap4evb_init(void) clk_put(clk); } - /* change parent of FSI A */ - clk = clk_get(NULL, "fsia_clk"); - if (!IS_ERR(clk)) { - clk_register(&fsiackcr_clk); - clk_set_parent(clk, &fsiackcr_clk); - clk_put(clk); - } - /* * set irq priority, to avoid sound chopping * when NFS rootfs is used @@ -977,8 +1225,10 @@ static void __init ap4evb_init(void) ARRAY_SIZE(i2c1_devices)); #ifdef CONFIG_AP4EVB_QHD + /* - * QHD + * For QHD Panel (MIPI-DSI, CONFIG_AP4EVB_QHD=y) and + * IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON. */ /* enable KEYSC */ @@ -1004,17 +1254,6 @@ static void __init ap4evb_init(void) lcdc_info.ch[0].interface_type = RGB24; lcdc_info.ch[0].clock_divider = 1; lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL; - lcdc_info.ch[0].lcd_cfg.name = "R63302(QHD)"; - lcdc_info.ch[0].lcd_cfg.xres = 544; - lcdc_info.ch[0].lcd_cfg.yres = 961; - lcdc_info.ch[0].lcd_cfg.left_margin = 72; - lcdc_info.ch[0].lcd_cfg.right_margin = 600; - lcdc_info.ch[0].lcd_cfg.hsync_len = 16; - lcdc_info.ch[0].lcd_cfg.upper_margin = 8; - lcdc_info.ch[0].lcd_cfg.lower_margin = 8; - lcdc_info.ch[0].lcd_cfg.vsync_len = 2; - lcdc_info.ch[0].lcd_cfg.sync = FB_SYNC_VERT_HIGH_ACT | - FB_SYNC_HOR_HIGH_ACT; lcdc_info.ch[0].lcd_size_cfg.width = 44; lcdc_info.ch[0].lcd_size_cfg.height = 79; @@ -1022,8 +1261,10 @@ static void __init ap4evb_init(void) #else /* - * WVGA + * For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and + * IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF. */ + gpio_request(GPIO_FN_LCDD17, NULL); gpio_request(GPIO_FN_LCDD16, NULL); gpio_request(GPIO_FN_LCDD15, NULL); @@ -1055,16 +1296,6 @@ static void __init ap4evb_init(void) lcdc_info.ch[0].interface_type = RGB18; lcdc_info.ch[0].clock_divider = 2; lcdc_info.ch[0].flags = 0; - lcdc_info.ch[0].lcd_cfg.name = "WVGA Panel"; - lcdc_info.ch[0].lcd_cfg.xres = 800; - lcdc_info.ch[0].lcd_cfg.yres = 480; - lcdc_info.ch[0].lcd_cfg.left_margin = 220; - lcdc_info.ch[0].lcd_cfg.right_margin = 110; - lcdc_info.ch[0].lcd_cfg.hsync_len = 70; - lcdc_info.ch[0].lcd_cfg.upper_margin = 20; - lcdc_info.ch[0].lcd_cfg.lower_margin = 5; - lcdc_info.ch[0].lcd_cfg.vsync_len = 5; - lcdc_info.ch[0].lcd_cfg.sync = 0; lcdc_info.ch[0].lcd_size_cfg.width = 152; lcdc_info.ch[0].lcd_size_cfg.height = 91; @@ -1075,6 +1306,23 @@ static void __init ap4evb_init(void) i2c_register_board_info(0, &tsc_device, 1); #endif /* CONFIG_AP4EVB_QHD */ + /* CEU */ + + /* + * TODO: reserve memory for V4L2 DMA buffers, when a suitable API + * becomes available + */ + + /* MIPI-CSI stuff */ + gpio_request(GPIO_FN_VIO_CKO, NULL); + + clk = clk_get(NULL, "vck1_clk"); + if (!IS_ERR(clk)) { + clk_set_rate(clk, clk_round_rate(clk, 13000000)); + clk_enable(clk); + clk_put(clk); + } + sh7372_add_standard_devices(); /* HDMI */ @@ -1097,7 +1345,7 @@ static void __init ap4evb_timer_init(void) shmobile_timer.init(); /* External clock source */ - clk_set_rate(&dv_clki_clk, 27000000); + clk_set_rate(&sh7372_dv_clki_clk, 27000000); } static struct sys_timer ap4evb_timer = { diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c index b6454c9f2ab..9f78729098f 100644 --- a/arch/arm/mach-shmobile/clock-sh7367.c +++ b/arch/arm/mach-shmobile/clock-sh7367.c @@ -321,7 +321,7 @@ static struct clk_lookup lookups[] = { 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_cmt.10", &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 */ diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 759468992ad..3aa02606943 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -50,8 +50,11 @@ #define SMSTPCR3 0xe615013c #define SMSTPCR4 0xe6150140 +#define FSIDIVA 0xFE1F8000 +#define FSIDIVB 0xFE1F8008 + /* Platforms must set frequency on their DV_CLKI pin */ -struct clk dv_clki_clk = { +struct clk sh7372_dv_clki_clk = { }; /* Fixed 32 KHz root clock from EXTALR pin */ @@ -86,9 +89,9 @@ static struct clk_ops div2_clk_ops = { }; /* Divide dv_clki by two */ -struct clk dv_clki_div2_clk = { +struct clk sh7372_dv_clki_div2_clk = { .ops = &div2_clk_ops, - .parent = &dv_clki_clk, + .parent = &sh7372_dv_clki_clk, }; /* Divide extal1 by two */ @@ -150,7 +153,7 @@ static struct clk pllc1_div2_clk = { static struct clk *pllc2_parent[] = { [0] = &extal1_div2_clk, [1] = &extal2_div2_clk, - [2] = &dv_clki_div2_clk, + [2] = &sh7372_dv_clki_div2_clk, }; /* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */ @@ -217,8 +220,7 @@ static void pllc2_disable(struct clk *clk) __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR); } -static int pllc2_set_rate(struct clk *clk, - unsigned long rate, int algo_id) +static int pllc2_set_rate(struct clk *clk, unsigned long rate) { unsigned long value; int idx; @@ -227,21 +229,13 @@ static int pllc2_set_rate(struct clk *clk, if (idx < 0) return idx; - if (rate == clk->parent->rate) { - pllc2_disable(clk); - return 0; - } + if (rate == clk->parent->rate) + return -EINVAL; value = __raw_readl(PLLC2CR) & ~(0x3f << 24); - if (value & 0x80000000) - pllc2_disable(clk); - __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR); - if (value & 0x80000000) - return pllc2_enable(clk); - return 0; } @@ -284,27 +278,37 @@ static struct clk_ops pllc2_clk_ops = { .set_parent = pllc2_set_parent, }; -struct clk pllc2_clk = { +struct clk sh7372_pllc2_clk = { .ops = &pllc2_clk_ops, .parent = &extal1_div2_clk, .freq_table = pllc2_freq_table, + .nr_freqs = ARRAY_SIZE(pllc2_freq_table) - 1, .parent_table = pllc2_parent, .parent_num = ARRAY_SIZE(pllc2_parent), }; +/* External input clock (pin name: FSIACK/FSIBCK ) */ +struct clk sh7372_fsiack_clk = { +}; + +struct clk sh7372_fsibck_clk = { +}; + static struct clk *main_clks[] = { - &dv_clki_clk, + &sh7372_dv_clki_clk, &r_clk, &sh7372_extal1_clk, &sh7372_extal2_clk, - &dv_clki_div2_clk, + &sh7372_dv_clki_div2_clk, &extal1_div2_clk, &extal2_div2_clk, &extal2_div4_clk, &pllc0_clk, &pllc1_clk, &pllc1_div2_clk, - &pllc2_clk, + &sh7372_pllc2_clk, + &sh7372_fsiack_clk, + &sh7372_fsibck_clk, }; static void div4_kick(struct clk *clk) @@ -357,7 +361,7 @@ static struct clk div4_clks[DIV4_NR] = { }; enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, - DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU, + DIV6_SUB, DIV6_SPU, DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P, DIV6_NR }; @@ -367,8 +371,6 @@ static struct clk div6_clks[DIV6_NR] = { [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), @@ -377,24 +379,129 @@ static struct clk div6_clks[DIV6_NR] = { [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0), }; -enum { DIV6_HDMI, DIV6_REPARENT_NR }; +enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR }; /* Indices are important - they are the actual src selecting values */ static struct clk *hdmi_parent[] = { [0] = &pllc1_div2_clk, - [1] = &pllc2_clk, - [2] = &dv_clki_clk, + [1] = &sh7372_pllc2_clk, + [2] = &sh7372_dv_clki_clk, [3] = NULL, /* pllc2_div4 not implemented yet */ }; +static struct clk *fsiackcr_parent[] = { + [0] = &pllc1_div2_clk, + [1] = &sh7372_pllc2_clk, + [2] = &sh7372_fsiack_clk, /* external input for FSI A */ + [3] = NULL, /* setting prohibited */ +}; + +static struct clk *fsibckcr_parent[] = { + [0] = &pllc1_div2_clk, + [1] = &sh7372_pllc2_clk, + [2] = &sh7372_fsibck_clk, /* external input for FSI B */ + [3] = NULL, /* setting prohibited */ +}; + static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0, hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2), + [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0, + fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2), + [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0, + fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2), +}; + +/* FSI DIV */ +static unsigned long fsidiv_recalc(struct clk *clk) +{ + unsigned long value; + + value = __raw_readl(clk->mapping->base); + + if ((value & 0x3) != 0x3) + return 0; + + value >>= 16; + if (value < 2) + return 0; + + return clk->parent->rate / value; +} + +static long fsidiv_round_rate(struct clk *clk, unsigned long rate) +{ + return clk_rate_div_range_round(clk, 2, 0xffff, rate); +} + +static void fsidiv_disable(struct clk *clk) +{ + __raw_writel(0, clk->mapping->base); +} + +static int fsidiv_enable(struct clk *clk) +{ + unsigned long value; + + value = __raw_readl(clk->mapping->base) >> 16; + if (value < 2) + return -EIO; + + __raw_writel((value << 16) | 0x3, clk->mapping->base); + + return 0; +} + +static int fsidiv_set_rate(struct clk *clk, unsigned long rate) +{ + int idx; + + idx = (clk->parent->rate / rate) & 0xffff; + if (idx < 2) + return -EINVAL; + + __raw_writel(idx << 16, clk->mapping->base); + return 0; +} + +static struct clk_ops fsidiv_clk_ops = { + .recalc = fsidiv_recalc, + .round_rate = fsidiv_round_rate, + .set_rate = fsidiv_set_rate, + .enable = fsidiv_enable, + .disable = fsidiv_disable, +}; + +static struct clk_mapping sh7372_fsidiva_clk_mapping = { + .phys = FSIDIVA, + .len = 8, +}; + +struct clk sh7372_fsidiva_clk = { + .ops = &fsidiv_clk_ops, + .parent = &div6_reparent_clks[DIV6_FSIA], /* late install */ + .mapping = &sh7372_fsidiva_clk_mapping, +}; + +static struct clk_mapping sh7372_fsidivb_clk_mapping = { + .phys = FSIDIVB, + .len = 8, +}; + +struct clk sh7372_fsidivb_clk = { + .ops = &fsidiv_clk_ops, + .parent = &div6_reparent_clks[DIV6_FSIB], /* late install */ + .mapping = &sh7372_fsidivb_clk_mapping, +}; + +static struct clk *late_main_clks[] = { + &sh7372_fsidiva_clk, + &sh7372_fsidivb_clk, }; enum { MSTP001, MSTP131, MSTP130, - MSTP129, MSTP128, MSTP127, MSTP126, + MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP117, MSTP116, MSTP106, MSTP101, MSTP100, MSTP223, @@ -414,6 +521,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */ [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */ + [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */ [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */ [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ @@ -429,7 +537,7 @@ static struct clk mstp_clks[MSTP_NR] = { [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 */ - [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */ + [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */ [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 */ @@ -445,10 +553,11 @@ static struct clk mstp_clks[MSTP_NR] = { #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } +#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk } static struct clk_lookup lookups[] = { /* main clocks */ - CLKDEV_CON_ID("dv_clki_div2_clk", &dv_clki_div2_clk), + CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk), CLKDEV_CON_ID("r_clk", &r_clk), CLKDEV_CON_ID("extal1", &sh7372_extal1_clk), CLKDEV_CON_ID("extal2", &sh7372_extal2_clk), @@ -458,7 +567,7 @@ static struct clk_lookup lookups[] = { 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), + CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk), /* DIV4 clocks */ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), @@ -483,8 +592,6 @@ static struct clk_lookup lookups[] = { 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]), @@ -501,6 +608,8 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */ CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */ + CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */ + CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */ 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 */ @@ -516,11 +625,11 @@ static struct clk_lookup lookups[] = { 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("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ 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("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ + CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* 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_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ @@ -531,7 +640,10 @@ static struct clk_lookup lookups[] = { 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 */ - {.con_id = "ick", .dev_id = "sh-mobile-hdmi", .clk = &div6_reparent_clks[DIV6_HDMI]}, + + CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), + CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), + CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), }; void __init sh7372_clock_init(void) @@ -548,11 +660,14 @@ void __init sh7372_clock_init(void) ret = sh_clk_div6_register(div6_clks, DIV6_NR); if (!ret) - ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_NR); + ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR); if (!ret) ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); + for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) + ret = clk_register(late_main_clks[k]); + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c index e007c28cf0a..f91395aeb9a 100644 --- a/arch/arm/mach-shmobile/clock-sh7377.c +++ b/arch/arm/mach-shmobile/clock-sh7377.c @@ -333,7 +333,7 @@ static struct clk_lookup lookups[] = { 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_cmt.10", &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 */ diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S index a285d13c741..f428c4db2b6 100644 --- a/arch/arm/mach-shmobile/include/mach/entry-macro.S +++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S @@ -1,4 +1,5 @@ /* + * Copyright (C) 2010 Magnus Damm * Copyright (C) 2008 Renesas Solutions Corp. * * This program is free software; you can redistribute it and/or modify @@ -14,24 +15,45 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <mach/hardware.h> #include <mach/irqs.h> +#define INTCA_BASE 0xe6980000 +#define INTFLGA_OFFS 0x00000018 /* accept pending interrupt */ +#define INTEVTA_OFFS 0x00000020 /* vector number of accepted interrupt */ +#define INTLVLA_OFFS 0x00000030 /* priority level of accepted interrupt */ +#define INTLVLB_OFFS 0x00000034 /* previous priority level */ + .macro disable_fiq .endm .macro get_irqnr_preamble, base, tmp - ldr \base, =INTFLGA + ldr \base, =INTCA_BASE .endm .macro arch_ret_to_user, tmp1, tmp2 .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - ldr \irqnr, [\base] + /* The single INTFLGA read access below results in the following: + * + * 1. INTLVLB is updated with old priority value from INTLVLA + * 2. Highest priority interrupt is accepted + * 3. INTLVLA is updated to contain priority of accepted interrupt + * 4. Accepted interrupt vector is stored in INTFLGA and INTEVTA + */ + ldr \irqnr, [\base, #INTFLGA_OFFS] + + /* Restore INTLVLA with the value saved in INTLVLB. + * This is required to support interrupt priorities properly. + */ + ldrb \tmp, [\base, #INTLVLB_OFFS] + strb \tmp, [\base, #INTLVLA_OFFS] + + /* Handle invalid vector number case */ cmp \irqnr, #0 beq 1000f - /* intevt to irq number */ + + /* Convert vector to irq number, same as the evt2irq() macro */ lsr \irqnr, \irqnr, #0x5 subs \irqnr, \irqnr, #16 diff --git a/arch/arm/mach-shmobile/include/mach/gpio.h b/arch/arm/mach-shmobile/include/mach/gpio.h index 5bc6bd444d7..2b1bb9e43dd 100644 --- a/arch/arm/mach-shmobile/include/mach/gpio.h +++ b/arch/arm/mach-shmobile/include/mach/gpio.h @@ -35,12 +35,12 @@ static inline int gpio_cansleep(unsigned gpio) static inline int gpio_to_irq(unsigned gpio) { - return -ENOSYS; + return __gpio_to_irq(gpio); } static inline int irq_to_gpio(unsigned int irq) { - return -EINVAL; + return -ENOSYS; } #endif /* CONFIG_GPIOLIB */ diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index 33e9700ded7..e4f9004e710 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -457,8 +457,14 @@ enum { SHDMA_SLAVE_SDHI2_TX, }; -extern struct clk dv_clki_clk; -extern struct clk dv_clki_div2_clk; -extern struct clk pllc2_clk; +extern struct clk sh7372_extal1_clk; +extern struct clk sh7372_extal2_clk; +extern struct clk sh7372_dv_clki_clk; +extern struct clk sh7372_dv_clki_div2_clk; +extern struct clk sh7372_pllc2_clk; +extern struct clk sh7372_fsiack_clk; +extern struct clk sh7372_fsibck_clk; +extern struct clk sh7372_fsidiva_clk; +extern struct clk sh7372_fsidivb_clk; #endif /* __ASM_SH7372_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h index 4aecf6e3a85..2b8fd8b942f 100644 --- a/arch/arm/mach-shmobile/include/mach/vmalloc.h +++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h @@ -2,6 +2,6 @@ #define __ASM_MACH_VMALLOC_H /* Vmalloc at ... - 0xe5ffffff */ -#define VMALLOC_END 0xe6000000 +#define VMALLOC_END 0xe6000000UL #endif /* __ASM_MACH_VMALLOC_H */ diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index e3551b56cd0..30b2f400666 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c @@ -98,7 +98,7 @@ static struct intc_vect intca_vectors[] __initdata = { INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0), INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220), INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260), - INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ31A, 0x32a0), + INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ21A, 0x32a0), INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0), INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320), INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360), @@ -369,9 +369,13 @@ enum { INTCS, /* interrupt sources INTCS */ + + /* IRQ0S - IRQ31S */ 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, + /* MFI */ + /* BBIF2 */ VPU, TSIF1, _3DG_SGX530, @@ -379,13 +383,17 @@ enum { IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, IPMMU_IPMMUR, IPMMU_IPMMUR2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR, + /* KEYSC */ + /* TTI20 */ MSIOF, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, CMT0, TSIF0, + /* CMT2 */ LMB, CTI, + /* RWDT0 */ ICB, JPU_JPEG, LCDC, @@ -397,11 +405,17 @@ enum { CSIRX, DSITX_DSITX0, DSITX_DSITX1, + /* SPU2 */ + /* FSI */ + /* FMSI */ + /* HDMI */ TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2, CMT4, DSITX1_DSITX1_0, DSITX1_DSITX1_1, + /* MFIS2 */ CPORTS2R, + /* CEC */ JPU6E, /* interrupt groups INTCS */ @@ -410,12 +424,15 @@ enum { }; static struct intc_vect intcs_vectors[] = { + /* IRQ0S - IRQ31S */ 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), + /* MFI */ + /* BBIF2 */ INTCS_VECT(VPU, 0x980), INTCS_VECT(TSIF1, 0x9a0), INTCS_VECT(_3DG_SGX530, 0x9e0), @@ -425,14 +442,19 @@ static struct intc_vect intcs_vectors[] = { 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), + /* KEYSC */ + /* TTI20 */ + INTCS_VECT(MSIOF, 0x0d20), 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), + /* CMT2 */ INTCS_VECT(LMB, 0xf60), INTCS_VECT(CTI, 0x400), + /* RWDT0 */ INTCS_VECT(ICB, 0x480), INTCS_VECT(JPU_JPEG, 0x560), INTCS_VECT(LCDC, 0x580), @@ -446,12 +468,18 @@ static struct intc_vect intcs_vectors[] = { INTCS_VECT(CSIRX, 0x17a0), INTCS_VECT(DSITX_DSITX0, 0x17c0), INTCS_VECT(DSITX_DSITX1, 0x17e0), + /* SPU2 */ + /* FSI */ + /* FMSI */ + /* HDMI */ 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), + /* MFIS2 */ INTCS_VECT(CPORTS2R, 0x1a20), + /* CEC */ INTCS_VECT(JPU6E, 0x1a80), INTC_VECT(INTCS, 0xf80), diff --git a/arch/arm/mach-shmobile/pfc-sh7372.c b/arch/arm/mach-shmobile/pfc-sh7372.c index ec420353f8e..9c265dae138 100644 --- a/arch/arm/mach-shmobile/pfc-sh7372.c +++ b/arch/arm/mach-shmobile/pfc-sh7372.c @@ -166,12 +166,12 @@ enum { MSIOF2_TSYNC_MARK, MSIOF2_TSCK_MARK, MSIOF2_RXD_MARK, MSIOF2_TXD_MARK, - /* MSIOF3 */ + /* BBIF1 */ BBIF1_RXD_MARK, BBIF1_TSYNC_MARK, BBIF1_TSCK_MARK, BBIF1_TXD_MARK, BBIF1_RSCK_MARK, BBIF1_RSYNC_MARK, BBIF1_FLOW_MARK, BB_RX_FLOW_N_MARK, - /* MSIOF4 */ + /* BBIF2 */ BBIF2_TSCK1_MARK, BBIF2_TSYNC1_MARK, BBIF2_TXD1_MARK, BBIF2_RXD_MARK, @@ -976,12 +976,12 @@ static struct pinmux_gpio pinmux_gpios[] = { GPIO_FN(MSIOF2_TSYNC), GPIO_FN(MSIOF2_TSCK), GPIO_FN(MSIOF2_RXD), GPIO_FN(MSIOF2_TXD), - /* MSIOF3 */ + /* BBIF1 */ GPIO_FN(BBIF1_RXD), GPIO_FN(BBIF1_TSYNC), GPIO_FN(BBIF1_TSCK), GPIO_FN(BBIF1_TXD), GPIO_FN(BBIF1_RSCK), GPIO_FN(BBIF1_RSYNC), GPIO_FN(BBIF1_FLOW), GPIO_FN(BB_RX_FLOW_N), - /* MSIOF4 */ + /* BBIF2 */ GPIO_FN(BBIF2_TSCK1), GPIO_FN(BBIF2_TSYNC1), GPIO_FN(BBIF2_TXD1), GPIO_FN(BBIF2_RXD), diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c index 3148c11a550..003008c1836 100644 --- a/arch/arm/mach-shmobile/setup-sh7367.c +++ b/arch/arm/mach-shmobile/setup-sh7367.c @@ -154,7 +154,6 @@ static struct sh_timer_config cmt10_platform_data = { .name = "CMT10", .channel_offset = 0x10, .timer_bit = 0, - .clk = "r_clk", .clockevent_rating = 125, .clocksource_rating = 125, }; diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index e26686c9d0b..564a6d0be47 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -158,7 +158,6 @@ static struct sh_timer_config cmt10_platform_data = { .name = "CMT10", .channel_offset = 0x10, .timer_bit = 0, - .clk = "cmt1", .clockevent_rating = 125, .clocksource_rating = 125, }; @@ -186,6 +185,67 @@ static struct platform_device cmt10_device = { .num_resources = ARRAY_SIZE(cmt10_resources), }; +/* TMU */ +static struct sh_timer_config tmu00_platform_data = { + .name = "TMU00", + .channel_offset = 0x4, + .timer_bit = 0, + .clockevent_rating = 200, +}; + +static struct resource tmu00_resources[] = { + [0] = { + .name = "TMU00", + .start = 0xfff60008, + .end = 0xfff60013, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = intcs_evt2irq(0xe80), /* TMU_TUNI0 */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device tmu00_device = { + .name = "sh_tmu", + .id = 0, + .dev = { + .platform_data = &tmu00_platform_data, + }, + .resource = tmu00_resources, + .num_resources = ARRAY_SIZE(tmu00_resources), +}; + +static struct sh_timer_config tmu01_platform_data = { + .name = "TMU01", + .channel_offset = 0x10, + .timer_bit = 1, + .clocksource_rating = 200, +}; + +static struct resource tmu01_resources[] = { + [0] = { + .name = "TMU01", + .start = 0xfff60014, + .end = 0xfff6001f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = intcs_evt2irq(0xea0), /* TMU_TUNI1 */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device tmu01_device = { + .name = "sh_tmu", + .id = 1, + .dev = { + .platform_data = &tmu01_platform_data, + }, + .resource = tmu01_resources, + .num_resources = ARRAY_SIZE(tmu01_resources), +}; + /* I2C */ static struct resource iic0_resources[] = { [0] = { @@ -419,14 +479,14 @@ static struct resource sh7372_dmae0_resources[] = { }, { /* DMA error IRQ */ - .start = 246, - .end = 246, + .start = evt2irq(0x20c0), + .end = evt2irq(0x20c0), .flags = IORESOURCE_IRQ, }, { /* IRQ for channels 0-5 */ - .start = 240, - .end = 245, + .start = evt2irq(0x2000), + .end = evt2irq(0x20a0), .flags = IORESOURCE_IRQ, }, }; @@ -447,14 +507,14 @@ static struct resource sh7372_dmae1_resources[] = { }, { /* DMA error IRQ */ - .start = 254, - .end = 254, + .start = evt2irq(0x21c0), + .end = evt2irq(0x21c0), .flags = IORESOURCE_IRQ, }, { /* IRQ for channels 0-5 */ - .start = 248, - .end = 253, + .start = evt2irq(0x2100), + .end = evt2irq(0x21a0), .flags = IORESOURCE_IRQ, }, }; @@ -475,14 +535,14 @@ static struct resource sh7372_dmae2_resources[] = { }, { /* DMA error IRQ */ - .start = 262, - .end = 262, + .start = evt2irq(0x22c0), + .end = evt2irq(0x22c0), .flags = IORESOURCE_IRQ, }, { /* IRQ for channels 0-5 */ - .start = 256, - .end = 261, + .start = evt2irq(0x2200), + .end = evt2irq(0x22a0), .flags = IORESOURCE_IRQ, }, }; @@ -526,6 +586,11 @@ static struct platform_device *sh7372_early_devices[] __initdata = { &scif5_device, &scif6_device, &cmt10_device, + &tmu00_device, + &tmu01_device, +}; + +static struct platform_device *sh7372_late_devices[] __initdata = { &iic0_device, &iic1_device, &dma0_device, @@ -537,6 +602,9 @@ void __init sh7372_add_standard_devices(void) { platform_add_devices(sh7372_early_devices, ARRAY_SIZE(sh7372_early_devices)); + + platform_add_devices(sh7372_late_devices, + ARRAY_SIZE(sh7372_late_devices)); } void __init sh7372_add_early_devices(void) diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c index bb4adf17dbf..575dbd6c2f1 100644 --- a/arch/arm/mach-shmobile/setup-sh7377.c +++ b/arch/arm/mach-shmobile/setup-sh7377.c @@ -172,7 +172,6 @@ static struct sh_timer_config cmt10_platform_data = { .name = "CMT10", .channel_offset = 0x10, .timer_bit = 0, - .clk = "r_clk", .clockevent_rating = 125, .clocksource_rating = 125, }; |