summaryrefslogtreecommitdiffstats
path: root/arch/arm/boards/pcm038/pcm970.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/boards/pcm038/pcm970.c')
-rw-r--r--arch/arm/boards/pcm038/pcm970.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/arch/arm/boards/pcm038/pcm970.c b/arch/arm/boards/pcm038/pcm970.c
index cd80677fc..ca10afb8c 100644
--- a/arch/arm/boards/pcm038/pcm970.c
+++ b/arch/arm/boards/pcm038/pcm970.c
@@ -18,11 +18,17 @@
#include <common.h>
#include <io.h>
#include <init.h>
+#include <sizes.h>
+#include <platform_ide.h>
#include <mach/imx-regs.h>
#include <mach/iomux-mx27.h>
#include <mach/gpio.h>
#include <usb/ulpi.h>
+#define GPIO_IDE_POWER (GPIO_PORTE + 18)
+#define GPIO_IDE_PCOE (GPIO_PORTF + 7)
+#define GPIO_IDE_RESET (GPIO_PORTF + 10)
+
#ifdef CONFIG_USB
static void pcm970_usbh2_init(void)
{
@@ -45,6 +51,103 @@ static void pcm970_usbh2_init(void)
}
#endif
+#ifdef CONFIG_DISK_INTF_PLATFORM_IDE
+static struct resource pcm970_ide_resources[] = {
+ {
+ .start = IMX_PCMCIA_MEM_BASE,
+ .size = SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static void pcm970_ide_reset(int state)
+{
+ /* Switch reset line to low/high state */
+ gpio_set_value(GPIO_IDE_RESET, !!state);
+}
+
+static struct ide_port_info pcm970_ide_pdata = {
+ .ioport_shift = 0,
+ .reset = &pcm970_ide_reset,
+};
+
+static struct device_d pcm970_ide_device = {
+ .id = -1,
+ .name = "ide_intf",
+ .num_resources = ARRAY_SIZE(pcm970_ide_resources),
+ .resource = pcm970_ide_resources,
+ .platform_data = &pcm970_ide_pdata,
+};
+
+static void pcm970_ide_init(void)
+{
+ uint32_t i;
+ unsigned int mode[] = {
+ /* PCMCIA */
+ PF20_PF_PC_CD1,
+ PF19_PF_PC_CD2,
+ PF18_PF_PC_WAIT,
+ PF17_PF_PC_READY,
+ PF16_PF_PC_PWRON,
+ PF14_PF_PC_VS1,
+ PF13_PF_PC_VS2,
+ PF12_PF_PC_BVD1,
+ PF11_PF_PC_BVD2,
+ PF9_PF_PC_IOIS16,
+ PF8_PF_PC_RW,
+ GPIO_IDE_PCOE | GPIO_GPIO | GPIO_OUT, /* PCOE */
+ GPIO_IDE_RESET | GPIO_GPIO | GPIO_OUT, /* Reset */
+ GPIO_IDE_POWER | GPIO_GPIO | GPIO_OUT, /* Power */
+ };
+
+ for (i = 0; i < ARRAY_SIZE(mode); i++)
+ imx_gpio_mode(mode[i] | GPIO_PUEN);
+
+ /* Always set PCOE signal to low */
+ gpio_set_value(GPIO_IDE_PCOE, 0);
+
+ /* Assert RESET line */
+ gpio_set_value(GPIO_IDE_RESET, 0);
+
+ /* Power up CF-card (Also switched on User-LED) */
+ gpio_set_value(GPIO_IDE_POWER, 1);
+ mdelay(10);
+
+ /* Reset PCMCIA Status Change Register */
+ writel(0x00000fff, PCMCIA_PSCR);
+ mdelay(10);
+
+ /* Check PCMCIA Input Pins Register for Card Detect & Power */
+ if ((readl(PCMCIA_PIPR) & ((1 << 8) | (3 << 3))) != (1 << 8)) {
+ printf("CompactFlash card not found. Driver not enabled.\n");
+ return;
+ }
+
+ /* Disable all interrupts */
+ writel(0, PCMCIA_PER);
+
+ /* Disable all PCMCIA banks */
+ for (i = 0; i < 5; i++)
+ writel(0, PCMCIA_POR(i));
+
+ /* Not use internal PCOE */
+ writel(0, PCMCIA_PGCR);
+
+ /* Setup PCMCIA bank0 for Common memory mode */
+ writel(0, PCMCIA_PBR(0));
+ writel(0, PCMCIA_POFR(0));
+ writel((0 << 25) | (17 << 17) | (4 << 11) | (3 << 5) | 0xf, PCMCIA_POR(0));
+
+ /* Clear PCMCIA General Status Register */
+ writel(0x0000001f, PCMCIA_PGSR);
+
+ /* Make PCMCIA bank0 valid */
+ writel(readl(PCMCIA_POR(0)) | (1 << 29), PCMCIA_POR(0));
+
+ register_device(&pcm970_ide_device);
+}
+#endif
+
static int pcm970_init(void)
{
int i;
@@ -74,6 +177,10 @@ static int pcm970_init(void)
pcm970_usbh2_init();
#endif
+#ifdef CONFIG_DISK_INTF_PLATFORM_IDE
+ pcm970_ide_init();
+#endif
+
return 0;
}