diff options
Diffstat (limited to 'arch/arm/boards/pcm038')
-rw-r--r-- | arch/arm/boards/pcm038/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/boards/pcm038/config.h | 26 | ||||
-rw-r--r-- | arch/arm/boards/pcm038/env/config | 56 | ||||
-rw-r--r-- | arch/arm/boards/pcm038/lowlevel.c | 117 | ||||
-rw-r--r-- | arch/arm/boards/pcm038/pcm038.c | 423 | ||||
-rw-r--r-- | arch/arm/boards/pcm038/pcm038.dox | 8 | ||||
-rw-r--r-- | arch/arm/boards/pcm038/pll_init.S | 48 |
7 files changed, 681 insertions, 0 deletions
diff --git a/arch/arm/boards/pcm038/Makefile b/arch/arm/boards/pcm038/Makefile new file mode 100644 index 0000000000..a681ddafb9 --- /dev/null +++ b/arch/arm/boards/pcm038/Makefile @@ -0,0 +1,3 @@ + +obj-y += lowlevel.o pll_init.o +obj-y += pcm038.o diff --git a/arch/arm/boards/pcm038/config.h b/arch/arm/boards/pcm038/config.h new file mode 100644 index 0000000000..c2f5e7cc58 --- /dev/null +++ b/arch/arm/boards/pcm038/config.h @@ -0,0 +1,26 @@ +/* + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/** + * @file + * @brief Global defintions for the ARM i.MX27 based pcm038 + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#endif /* __CONFIG_H */ diff --git a/arch/arm/boards/pcm038/env/config b/arch/arm/boards/pcm038/env/config new file mode 100644 index 0000000000..a8be5c924d --- /dev/null +++ b/arch/arm/boards/pcm038/env/config @@ -0,0 +1,56 @@ +#!/bin/sh + +machine=pcm038 +eth0.serverip= +user= + +# use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration +ip=dhcp + +# or set your networking parameters here +#eth0.ipaddr=a.b.c.d +#eth0.netmask=a.b.c.d +#eth0.gateway=a.b.c.d +#eth0.serverip=a.b.c.d + +# can be either 'net', 'nor' or 'nand' +kernel_loc=net +# can be either 'net', 'nor', 'nand' or 'initrd' +rootfs_loc=net + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root-$machine.$rootfs_type + +# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo +kernelimage_type=zimage +kernelimage=zImage-$machine +#kernelimage_type=uimage +#kernelimage=uImage-$machine +#kernelimage_type=raw +#kernelimage=Image-$machine +#kernelimage_type=raw_lzo +#kernelimage=Image-$machine.lzo + +if [ -n $user ]; then + kernelimage="$user"-"$kernelimage" + nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine" + rootfsimage="$user"-"$rootfsimage" +else + nfsroot="$eth0.serverip:/path/to/nfs/root" +fi + +autoboot_timeout=3 + +bootargs="console=ttymxc0,115200" + +nor_parts="256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root)" +rootfs_mtdblock_nor=3 + +nand_parts="256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root)" +rootfs_mtdblock_nand=7 + +# set a fancy prompt (if support is compiled in) +PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m " + diff --git a/arch/arm/boards/pcm038/lowlevel.c b/arch/arm/boards/pcm038/lowlevel.c new file mode 100644 index 0000000000..0c376f2fae --- /dev/null +++ b/arch/arm/boards/pcm038/lowlevel.c @@ -0,0 +1,117 @@ +/* + * + * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <init.h> +#include <mach/imx-regs.h> +#include <mach/imx-pll.h> +#include <mach/esdctl.h> +#include <asm/cache-l2x0.h> +#include <asm/io.h> +#include <mach/imx-nand.h> +#include <asm/barebox-arm.h> +#include <asm/system.h> +#include <asm-generic/memory_layout.h> + +static void __bare_init __naked insdram(void) +{ + uint32_t r; + + PCCR1 |= PCCR1_NFC_BAUDEN; + + /* setup a stack to be able to call imx_nand_load_image() */ + r = STACK_BASE + STACK_SIZE - 12; + __asm__ __volatile__("mov sp, %0" : : "r"(r)); + + imx_nand_load_image((void *)TEXT_BASE, 256 * 1024); + + board_init_lowlevel_return(); +} + +#define ESDCTL0_VAL (ESDCTL0_SDE | ESDCTL0_ROW13 | ESDCTL0_COL10) + +void __bare_init __naked board_init_lowlevel(void) +{ + uint32_t r; + int i; + unsigned int *trg, *src; + + /* ahb lite ip interface */ + AIPI1_PSR0 = 0x20040304; + AIPI1_PSR1 = 0xDFFBFCFB; + AIPI2_PSR0 = 0x00000000; + AIPI2_PSR1 = 0xFFFFFFFF; + + /* Skip SDRAM initialization if we run from RAM */ + r = get_pc(); + if (r > 0xa0000000 && r < 0xb0000000) + board_init_lowlevel_return(); + + /* + * DDR on CSD0 + */ + writel(0x00000008, ESDMISC); /* Enable DDR SDRAM operation */ + + DSCR(3) = 0x55555555; /* Set the driving strength */ + DSCR(5) = 0x55555555; + DSCR(6) = 0x55555555; + DSCR(7) = 0x00005005; + DSCR(8) = 0x15555555; + + writel(0x00000004, ESDMISC); /* Initial reset */ + writel(0x006ac73a, ESDCFG0); + + writel(ESDCTL0_VAL | ESDCTL0_SMODE_PRECHARGE, ESDCTL0); /* precharge CSD0 all banks */ + writel(0x00000000, 0xA0000F00); /* CSD0 precharge address (A10 = 1) */ + writel(ESDCTL0_VAL | ESDCTL0_SMODE_AUTO_REFRESH, ESDCTL0); + + for (i = 0; i < 8; i++) + writel(0, 0xa0000f00); + + writel(ESDCTL0_VAL | ESDCTL0_SMODE_LOAD_MODE, ESDCTL0); + + writeb(0xda, 0xa0000033); + writeb(0xff, 0xa1000000); + writel(ESDCTL0_VAL | ESDCTL0_DSIZ_31_0 | ESDCTL0_REF4 | + ESDCTL0_BL | ESDCTL0_SMODE_NORMAL, ESDCTL0); + +#ifdef CONFIG_NAND_IMX_BOOT + /* skip NAND boot if not running from NFC space */ + r = get_pc(); + if (r < IMX_NFC_BASE || r > IMX_NFC_BASE + 0x800) + board_init_lowlevel_return(); + + src = (unsigned int *)IMX_NFC_BASE; + trg = (unsigned int *)TEXT_BASE; + + /* Move ourselves out of NFC SRAM */ + for (i = 0; i < 0x800 / sizeof(int); i++) + *trg++ = *src++; + + /* Jump to SDRAM */ + r = (unsigned int)&insdram; + __asm__ __volatile__("mov pc, %0" : : "r"(r)); +#else + board_init_lowlevel_return(); +#endif +} + diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c new file mode 100644 index 0000000000..03794fc13d --- /dev/null +++ b/arch/arm/boards/pcm038/pcm038.c @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2007 Sascha Hauer, Pengutronix + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include <common.h> +#include <net.h> +#include <init.h> +#include <environment.h> +#include <mach/imx-regs.h> +#include <fec.h> +#include <notifier.h> +#include <mach/gpio.h> +#include <asm/armlinux.h> +#include <asm/mach-types.h> +#include <mach/pmic.h> +#include <partition.h> +#include <fs.h> +#include <fcntl.h> +#include <nand.h> +#include <command.h> +#include <spi/spi.h> +#include <asm/io.h> +#include <mach/imx-nand.h> +#include <mach/imx-pll.h> +#include <mach/imxfb.h> +#include <asm/mmu.h> +#include <usb/isp1504.h> +#include <mach/spi.h> +#include <mach/iomux-mx27.h> + +static struct device_d cfi_dev = { + .name = "cfi_flash", + .map_base = 0xC0000000, + .size = 32 * 1024 * 1024, +}; + +static struct memory_platform_data ram_pdata = { + .name = "ram0", + .flags = DEVFS_RDWR, +}; + +static struct device_d sdram_dev = { + .name = "mem", + .map_base = 0xa0000000, + .size = 128 * 1024 * 1024, + .platform_data = &ram_pdata, +}; + +static struct memory_platform_data sram_pdata = { + .name = "sram0", + .flags = DEVFS_RDWR, +}; + +static struct device_d sram_dev = { + .name = "mem", + .map_base = 0xc8000000, + .size = 512 * 1024, /* Can be up to 2MiB */ + .platform_data = &sram_pdata, +}; + +static struct fec_platform_data fec_info = { + .xcv_type = MII100, + .phy_addr = 1, +}; + +static struct device_d fec_dev = { + .name = "fec_imx", + .map_base = 0x1002b000, + .platform_data = &fec_info, +}; + +static int pcm038_spi_cs[] = {GPIO_PORTD + 28}; + +static struct spi_imx_master pcm038_spi_0_data = { + .chipselect = pcm038_spi_cs, + .num_chipselect = ARRAY_SIZE(pcm038_spi_cs), +}; + +static struct device_d spi_dev = { + .name = "imx_spi", + .map_base = 0x1000e000, + .platform_data = &pcm038_spi_0_data, +}; + +static struct spi_board_info pcm038_spi_board_info[] = { + { + .name = "mc13783", + .max_speed_hz = 3000000, + .bus_num = 0, + .chip_select = 0, + } +}; + +static struct imx_nand_platform_data nand_info = { + .width = 1, + .hw_ecc = 1, + .flash_bbt = 1, +}; + +static struct device_d nand_dev = { + .name = "imx_nand", + .map_base = 0xd8000000, + .platform_data = &nand_info, +}; + +static struct imx_fb_videomode imxfb_mode = { + .mode = { + .name = "Sharp-LQ035Q7", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 188679, /* in ps (5.3MHz) */ + .hsync_len = 7, + .left_margin = 5, + .right_margin = 16, + .vsync_len = 1, + .upper_margin = 7, + .lower_margin = 9, + }, + /* + * - HSYNC active high + * - VSYNC active high + * - clk notenabled while idle + * - clock not inverted + * - data not inverted + * - data enable low active + * - enable sharp mode + */ + .pcr = 0xF00080C0, + .bpp = 16, +}; + +static struct imx_fb_platform_data pcm038_fb_data = { + .mode = &imxfb_mode, + .pwmr = 0x00A903FF, + .lscr1 = 0x00120300, + .dmacr = 0x00020010, +}; + +static struct device_d imxfb_dev = { + .name = "imxfb", + .map_base = 0x10021000, + .size = 0x1000, + .platform_data = &pcm038_fb_data, +}; + +#ifdef CONFIG_USB +static struct device_d usbh2_dev = { + .name = "ehci", + .map_base = IMX_OTG_BASE + 0x400, + .size = 0x200, +}; + +static void pcm038_usbh_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); + + isp1504_set_vbus_power((void *)(IMX_OTG_BASE + 0x570), 1); +} +#endif + +#ifdef CONFIG_MMU +static void pcm038_mmu_init(void) +{ + mmu_init(); + + arm_create_section(0xa0000000, 0xa0000000, 128, PMD_SECT_DEF_CACHED); + arm_create_section(0xb0000000, 0xa0000000, 128, PMD_SECT_DEF_UNCACHED); + + setup_dma_coherent(0x10000000); + +#if TEXT_BASE & (0x100000 - 1) +#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary +#else + arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED); +#endif + mmu_enable(); +} +#else +static void pcm038_mmu_init(void) +{ +} +#endif + +static int pcm038_devices_init(void) +{ + int i; + char *envdev; + + unsigned int mode[] = { + PD0_AIN_FEC_TXD0, + PD1_AIN_FEC_TXD1, + PD2_AIN_FEC_TXD2, + PD3_AIN_FEC_TXD3, + PD4_AOUT_FEC_RX_ER, + PD5_AOUT_FEC_RXD1, + PD6_AOUT_FEC_RXD2, + PD7_AOUT_FEC_RXD3, + PD8_AF_FEC_MDIO, + PD9_AIN_FEC_MDC | GPIO_PUEN, + PD10_AOUT_FEC_CRS, + PD11_AOUT_FEC_TX_CLK, + PD12_AOUT_FEC_RXD0, + PD13_AOUT_FEC_RX_DV, + PD14_AOUT_FEC_RX_CLK, + PD15_AOUT_FEC_COL, + PD16_AIN_FEC_TX_ER, + PF23_AIN_FEC_TX_EN, + PE12_PF_UART1_TXD, + PE13_PF_UART1_RXD, + PE14_PF_UART1_CTS, + PE15_PF_UART1_RTS, + PD25_PF_CSPI1_RDY, + GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT, + PD29_PF_CSPI1_SCLK, + PD30_PF_CSPI1_MISO, + PD31_PF_CSPI1_MOSI, + /* display */ + PA5_PF_LSCLK, + PA6_PF_LD0, + PA7_PF_LD1, + PA8_PF_LD2, + PA9_PF_LD3, + PA10_PF_LD4, + PA11_PF_LD5, + PA12_PF_LD6, + PA13_PF_LD7, + PA14_PF_LD8, + PA15_PF_LD9, + PA16_PF_LD10, + PA17_PF_LD11, + PA18_PF_LD12, + PA19_PF_LD13, + PA20_PF_LD14, + PA21_PF_LD15, + PA22_PF_LD16, + PA23_PF_LD17, + PA24_PF_REV, + PA25_PF_CLS, + PA26_PF_PS, + PA27_PF_SPL_SPR, + PA28_PF_HSYNC, + PA29_PF_VSYNC, + PA30_PF_CONTRAST, + PA31_PF_OE_ACD, + /* 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, + }; + + pcm038_mmu_init(); + + /* configure 16 bit nor flash on cs0 */ + CS0U = 0x0000CC03; + CS0L = 0xa0330D01; + CS0A = 0x00220800; + + /* configure SRAM on cs1 */ + CS1U = 0x0000d843; + CS1L = 0x22252521; + CS1A = 0x22220a00; + + /* configure SJA1000 on cs4 */ + CS4U = 0x0000DCF6; + CS4L = 0x444A0301; + CS4A = 0x44443302; + + /* initizalize gpios */ + for (i = 0; i < ARRAY_SIZE(mode); i++) + imx_gpio_mode(mode[i]); + + PCCR0 |= PCCR0_CSPI1_EN; + PCCR1 |= PCCR1_PERCLK2_EN; + + gpio_direction_output(GPIO_PORTD | 28, 0); + gpio_set_value(GPIO_PORTD | 28, 0); + spi_register_board_info(pcm038_spi_board_info, ARRAY_SIZE(pcm038_spi_board_info)); + register_device(&spi_dev); + + register_device(&cfi_dev); + register_device(&nand_dev); + register_device(&sdram_dev); + register_device(&sram_dev); + register_device(&imxfb_dev); + +#ifdef CONFIG_USB + pcm038_usbh_init(); + register_device(&usbh2_dev); +#endif + + /* Register the fec device after the PLL re-initialisation + * as the fec depends on the (now higher) ipg clock + */ + register_device(&fec_dev); + + switch ((GPCR & GPCR_BOOT_MASK) >> GPCR_BOOT_SHIFT) { + case GPCR_BOOT_8BIT_NAND_2k: + case GPCR_BOOT_16BIT_NAND_2k: + case GPCR_BOOT_16BIT_NAND_512: + case GPCR_BOOT_8BIT_NAND_512: + devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw"); + dev_add_bb_dev("self_raw", "self0"); + + devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED, "env_raw"); + dev_add_bb_dev("env_raw", "env0"); + envdev = "NAND"; + break; + default: + devfs_add_partition("nor0", 0x00000, 0x40000, PARTITION_FIXED, "self0"); + devfs_add_partition("nor0", 0x40000, 0x20000, PARTITION_FIXED, "env0"); + protect_file("/dev/env0", 1); + + envdev = "NOR"; + } + + printf("Using environment in %s Flash\n", envdev); + + armlinux_add_dram(&sdram_dev); + armlinux_set_bootparams((void *)0xa0000100); + armlinux_set_architecture(MACH_TYPE_PCM038); + + return 0; +} + +device_initcall(pcm038_devices_init); + +static struct device_d pcm038_serial_device = { + .name = "imx_serial", + .map_base = IMX_UART1_BASE, + .size = 4096, +}; + +static int pcm038_console_init(void) +{ + /* bring PLLs to reset default */ + MPCTL0 = 0x00211803; + SPCTL0 = 0x1002700c; + CSCR = 0x33fc1307; + + register_device(&pcm038_serial_device); + + return 0; +} + +console_initcall(pcm038_console_init); + +extern void *pcm038_pll_init, *pcm038_pll_init_end; + +static int pcm038_power_init(void) +{ + int ret; + void *vram = 0xffff4c00; + void (*pllfunc)(void) = vram; + + printf("initialising PLLs: 0x%p 0x%p\n", &pcm038_pll_init); + + memcpy(vram, &pcm038_pll_init, 0x100); + + console_flush(); + + ret = pmic_power(); + if (ret) { + printf("Failed to initialize PMIC. Will continue with low CPU speed\n"); + return 0; + } + + /* wait for good power level */ + udelay(100000); + + pllfunc(); + + /* clock gating enable */ + GPCR = 0x00050f08; + + PCDR0 = 0x130410c3; + PCDR1 = 0x09030911; + + /* Clocks have changed. Notify clients */ + clock_notifier_call_chain(); + + return 0; +} + +late_initcall(pcm038_power_init); + diff --git a/arch/arm/boards/pcm038/pcm038.dox b/arch/arm/boards/pcm038/pcm038.dox new file mode 100644 index 0000000000..9b17674a21 --- /dev/null +++ b/arch/arm/boards/pcm038/pcm038.dox @@ -0,0 +1,8 @@ +/** @page pcm038 Phytec's phyCORE-i.MX27 + +This CPU card is based on a Freescale i.MX27 CPU. The card is shipped with: + +- up to 32MiB NOR type Flash Memory +- 32MiB synchronous dynamic RAM + +*/ diff --git a/arch/arm/boards/pcm038/pll_init.S b/arch/arm/boards/pcm038/pll_init.S new file mode 100644 index 0000000000..0c1ff13415 --- /dev/null +++ b/arch/arm/boards/pcm038/pll_init.S @@ -0,0 +1,48 @@ +#include <config.h> +#include <mach/imx-regs.h> +#include <mach/imx-pll.h> +#include <linux/linkage.h> + +#define writel(val, reg) \ + ldr r0, =reg; \ + ldr r1, =val; \ + str r1, [r0]; + +#define CSCR_VAL CSCR_USB_DIV(3) | \ + CSCR_SD_CNT(3) | \ + CSCR_MSHC_SEL | \ + CSCR_H264_SEL | \ + CSCR_SSI1_SEL | \ + CSCR_SSI2_SEL | \ + CSCR_MCU_SEL | \ + CSCR_ARM_SRC_MPLL | \ + CSCR_SP_SEL | \ + CSCR_ARM_DIV(0) | \ + CSCR_FPM_EN | \ + CSCR_SPEN | \ + CSCR_MPEN | \ + CSCR_AHB_DIV(1) + +ENTRY(pcm038_pll_init) + + writel(IMX_PLL_PD(0) | + IMX_PLL_MFD(51) | + IMX_PLL_MFI(7) | + IMX_PLL_MFN(35), MPCTL0) /* 399 MHz */ + + writel(IMX_PLL_PD(1) | + IMX_PLL_MFD(12) | + IMX_PLL_MFI(9) | + IMX_PLL_MFN(3), SPCTL0) /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */ + + writel(CSCR_VAL | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART, CSCR) + + ldr r2, =16000 +1: + subs r2, r2, #1 + nop + bcs 1b + + mov pc, lr +ENDPROC(pcm038_pll_init) + |