9
0
Fork 0
barebox/arch/arm/boards/pcm038/pcm970.c

208 lines
4.6 KiB
C

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#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 <mach/devices-imx27.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)
{
uint32_t temp;
temp = readl(IMX_OTG_BASE + 0x600);
temp &= ~((3 << 21) | 1);
temp |= (1 << 5) | (1 << 16) | (1 << 19) | (1 << 20);
writel(temp, IMX_OTG_BASE + 0x600);
temp = readl(IMX_OTG_BASE + 0x584);
temp &= ~(3 << 30);
temp |= 2 << 30;
writel(temp, IMX_OTG_BASE + 0x584);
mdelay(10);
if (!ulpi_setup((void *)(IMX_OTG_BASE + 0x570), 1))
add_generic_usb_ehci_device(DEVICE_ID_DYNAMIC, IMX_OTG_BASE + 0x400, NULL);
}
#endif
#ifdef CONFIG_DISK_INTF_PLATFORM_IDE
static struct resource pcm970_ide_resources[] = {
{
.start = IMX_PCMCIA_MEM_BASE,
.end = IMX_PCMCIA_MEM_BASE + SZ_1K - 1,
.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 = DEVICE_ID_DYNAMIC,
.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 void pcm970_mmc_init(void)
{
uint32_t i;
unsigned int mode[] = {
/* SD2 */
PB4_PF_SD2_D0,
PB5_PF_SD2_D1,
PB6_PF_SD2_D2,
PB7_PF_SD2_D3,
PB8_PF_SD2_CMD,
PB9_PF_SD2_CLK,
};
for (i = 0; i < ARRAY_SIZE(mode); i++)
imx_gpio_mode(mode[i]);
PCCR0 |= PCCR0_SDHC2_EN;
imx27_add_mmc1(NULL);
}
static int pcm970_init(void)
{
int i;
unsigned int mode[] = {
/* USB Host 2 */
PA0_PF_USBH2_CLK,
PA1_PF_USBH2_DIR,
PA2_PF_USBH2_DATA7,
PA3_PF_USBH2_NXT,
PA4_PF_USBH2_STP,
PD19_AF_USBH2_DATA4,
PD20_AF_USBH2_DATA3,
PD21_AF_USBH2_DATA6,
PD22_AF_USBH2_DATA0,
PD23_AF_USBH2_DATA2,
PD24_AF_USBH2_DATA1,
PD26_AF_USBH2_DATA5,
};
for (i = 0; i < ARRAY_SIZE(mode); i++)
imx_gpio_mode(mode[i]);
/* Configure SJA1000 on cs4 */
imx27_setup_weimcs(4, 0x0000DCF6, 0x444A0301, 0x44443302);
#ifdef CONFIG_USB
pcm970_usbh2_init();
#endif
#ifdef CONFIG_DISK_INTF_PLATFORM_IDE
pcm970_ide_init();
#endif
if (IS_ENABLED(CONFIG_MCI_IMX))
pcm970_mmc_init();
return 0;
}
late_initcall(pcm970_init);