summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r--arch/arm/mach-shmobile/Kconfig2
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c460
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c189
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c2
-rw-r--r--arch/arm/mach-shmobile/include/mach/entry-macro.S30
-rw-r--r--arch/arm/mach-shmobile/include/mach/gpio.h4
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h12
-rw-r--r--arch/arm/mach-shmobile/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c30
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7372.c8
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c1
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c94
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c1
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,
};