Path: blob/master/arch/arm/mach-mx5/board-cpuimx51.c
10817 views
/*1*2* Copyright (C) 2010 Eric Bénard <[email protected]>3*4* based on board-mx51_babbage.c which is5* Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.6* Copyright (C) 2009-2010 Amit Kucheria <[email protected]>7*8* The code contained herein is licensed under the GNU General Public9* License. You may obtain a copy of the GNU General Public License10* Version 2 or later at the following locations:11*12* http://www.opensource.org/licenses/gpl-license.html13* http://www.gnu.org/copyleft/gpl.html14*/1516#include <linux/init.h>17#include <linux/platform_device.h>18#include <linux/serial_8250.h>19#include <linux/i2c.h>20#include <linux/gpio.h>21#include <linux/delay.h>22#include <linux/io.h>23#include <linux/interrupt.h>24#include <linux/irq.h>2526#include <mach/eukrea-baseboards.h>27#include <mach/common.h>28#include <mach/hardware.h>29#include <mach/iomux-mx51.h>3031#include <asm/irq.h>32#include <asm/setup.h>33#include <asm/mach-types.h>34#include <asm/mach/arch.h>35#include <asm/mach/time.h>3637#include "devices-imx51.h"38#include "devices.h"3940#define CPUIMX51_USBH1_STP IMX_GPIO_NR(1, 27)41#define CPUIMX51_QUARTA_GPIO IMX_GPIO_NR(3, 28)42#define CPUIMX51_QUARTB_GPIO IMX_GPIO_NR(3, 25)43#define CPUIMX51_QUARTC_GPIO IMX_GPIO_NR(3, 26)44#define CPUIMX51_QUARTD_GPIO IMX_GPIO_NR(3, 27)45#define CPUIMX51_QUARTA_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTA_GPIO)46#define CPUIMX51_QUARTB_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTB_GPIO)47#define CPUIMX51_QUARTC_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTC_GPIO)48#define CPUIMX51_QUARTD_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTD_GPIO)49#define CPUIMX51_QUART_XTAL 1474560050#define CPUIMX51_QUART_REGSHIFT 175152/* USB_CTRL_1 */53#define MX51_USB_CTRL_1_OFFSET 0x1054#define MX51_USB_CTRL_UH1_EXT_CLK_EN (1 << 25)5556#define MX51_USB_PLLDIV_12_MHZ 0x0057#define MX51_USB_PLL_DIV_19_2_MHZ 0x0158#define MX51_USB_PLL_DIV_24_MHZ 0x025960static struct plat_serial8250_port serial_platform_data[] = {61{62.mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x400000),63.irq = CPUIMX51_QUARTA_IRQ,64.irqflags = IRQF_TRIGGER_HIGH,65.uartclk = CPUIMX51_QUART_XTAL,66.regshift = CPUIMX51_QUART_REGSHIFT,67.iotype = UPIO_MEM,68.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,69}, {70.mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x800000),71.irq = CPUIMX51_QUARTB_IRQ,72.irqflags = IRQF_TRIGGER_HIGH,73.uartclk = CPUIMX51_QUART_XTAL,74.regshift = CPUIMX51_QUART_REGSHIFT,75.iotype = UPIO_MEM,76.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,77}, {78.mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x1000000),79.irq = CPUIMX51_QUARTC_IRQ,80.irqflags = IRQF_TRIGGER_HIGH,81.uartclk = CPUIMX51_QUART_XTAL,82.regshift = CPUIMX51_QUART_REGSHIFT,83.iotype = UPIO_MEM,84.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,85}, {86.mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x2000000),87.irq = CPUIMX51_QUARTD_IRQ,88.irqflags = IRQF_TRIGGER_HIGH,89.uartclk = CPUIMX51_QUART_XTAL,90.regshift = CPUIMX51_QUART_REGSHIFT,91.iotype = UPIO_MEM,92.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,93}, {94}95};9697static struct platform_device serial_device = {98.name = "serial8250",99.id = 0,100.dev = {101.platform_data = serial_platform_data,102},103};104105static struct platform_device *devices[] __initdata = {106&serial_device,107};108109static iomux_v3_cfg_t eukrea_cpuimx51_pads[] = {110/* UART1 */111MX51_PAD_UART1_RXD__UART1_RXD,112MX51_PAD_UART1_TXD__UART1_TXD,113MX51_PAD_UART1_RTS__UART1_RTS,114MX51_PAD_UART1_CTS__UART1_CTS,115116/* I2C2 */117MX51_PAD_GPIO1_2__I2C2_SCL,118MX51_PAD_GPIO1_3__I2C2_SDA,119MX51_PAD_NANDF_D10__GPIO3_30,120121/* QUART IRQ */122MX51_PAD_NANDF_D15__GPIO3_25,123MX51_PAD_NANDF_D14__GPIO3_26,124MX51_PAD_NANDF_D13__GPIO3_27,125MX51_PAD_NANDF_D12__GPIO3_28,126127/* USB HOST1 */128MX51_PAD_USBH1_CLK__USBH1_CLK,129MX51_PAD_USBH1_DIR__USBH1_DIR,130MX51_PAD_USBH1_NXT__USBH1_NXT,131MX51_PAD_USBH1_DATA0__USBH1_DATA0,132MX51_PAD_USBH1_DATA1__USBH1_DATA1,133MX51_PAD_USBH1_DATA2__USBH1_DATA2,134MX51_PAD_USBH1_DATA3__USBH1_DATA3,135MX51_PAD_USBH1_DATA4__USBH1_DATA4,136MX51_PAD_USBH1_DATA5__USBH1_DATA5,137MX51_PAD_USBH1_DATA6__USBH1_DATA6,138MX51_PAD_USBH1_DATA7__USBH1_DATA7,139MX51_PAD_USBH1_STP__USBH1_STP,140};141142static const struct mxc_nand_platform_data143eukrea_cpuimx51_nand_board_info __initconst = {144.width = 1,145.hw_ecc = 1,146.flash_bbt = 1,147};148149static const struct imxuart_platform_data uart_pdata __initconst = {150.flags = IMXUART_HAVE_RTSCTS,151};152153static const154struct imxi2c_platform_data eukrea_cpuimx51_i2c_data __initconst = {155.bitrate = 100000,156};157158static struct i2c_board_info eukrea_cpuimx51_i2c_devices[] = {159{160I2C_BOARD_INFO("pcf8563", 0x51),161},162};163164/* This function is board specific as the bit mask for the plldiv will also165be different for other Freescale SoCs, thus a common bitmask is not166possible and cannot get place in /plat-mxc/ehci.c.*/167static int initialize_otg_port(struct platform_device *pdev)168{169u32 v;170void __iomem *usb_base;171void __iomem *usbother_base;172173usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);174if (!usb_base)175return -ENOMEM;176usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;177178/* Set the PHY clock to 19.2MHz */179v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);180v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;181v |= MX51_USB_PLL_DIV_19_2_MHZ;182__raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);183iounmap(usb_base);184185mdelay(10);186187return mx51_initialize_usb_hw(0, MXC_EHCI_INTERNAL_PHY);188}189190static int initialize_usbh1_port(struct platform_device *pdev)191{192u32 v;193void __iomem *usb_base;194void __iomem *usbother_base;195196usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);197if (!usb_base)198return -ENOMEM;199usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;200201/* The clock for the USBH1 ULPI port will come externally from the PHY. */202v = __raw_readl(usbother_base + MX51_USB_CTRL_1_OFFSET);203__raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN, usbother_base + MX51_USB_CTRL_1_OFFSET);204iounmap(usb_base);205206mdelay(10);207208return mx51_initialize_usb_hw(1, MXC_EHCI_POWER_PINS_ENABLED |209MXC_EHCI_ITC_NO_THRESHOLD);210}211212static struct mxc_usbh_platform_data dr_utmi_config = {213.init = initialize_otg_port,214.portsc = MXC_EHCI_UTMI_16BIT,215};216217static struct fsl_usb2_platform_data usb_pdata = {218.operating_mode = FSL_USB2_DR_DEVICE,219.phy_mode = FSL_USB2_PHY_UTMI_WIDE,220};221222static struct mxc_usbh_platform_data usbh1_config = {223.init = initialize_usbh1_port,224.portsc = MXC_EHCI_MODE_ULPI,225};226227static int otg_mode_host;228229static int __init eukrea_cpuimx51_otg_mode(char *options)230{231if (!strcmp(options, "host"))232otg_mode_host = 1;233else if (!strcmp(options, "device"))234otg_mode_host = 0;235else236pr_info("otg_mode neither \"host\" nor \"device\". "237"Defaulting to device\n");238return 0;239}240__setup("otg_mode=", eukrea_cpuimx51_otg_mode);241242/*243* Board specific initialization.244*/245static void __init eukrea_cpuimx51_init(void)246{247mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads,248ARRAY_SIZE(eukrea_cpuimx51_pads));249250imx51_add_imx_uart(0, &uart_pdata);251imx51_add_mxc_nand(&eukrea_cpuimx51_nand_board_info);252253gpio_request(CPUIMX51_QUARTA_GPIO, "quarta_irq");254gpio_direction_input(CPUIMX51_QUARTA_GPIO);255gpio_free(CPUIMX51_QUARTA_GPIO);256gpio_request(CPUIMX51_QUARTB_GPIO, "quartb_irq");257gpio_direction_input(CPUIMX51_QUARTB_GPIO);258gpio_free(CPUIMX51_QUARTB_GPIO);259gpio_request(CPUIMX51_QUARTC_GPIO, "quartc_irq");260gpio_direction_input(CPUIMX51_QUARTC_GPIO);261gpio_free(CPUIMX51_QUARTC_GPIO);262gpio_request(CPUIMX51_QUARTD_GPIO, "quartd_irq");263gpio_direction_input(CPUIMX51_QUARTD_GPIO);264gpio_free(CPUIMX51_QUARTD_GPIO);265266imx51_add_fec(NULL);267platform_add_devices(devices, ARRAY_SIZE(devices));268269imx51_add_imx_i2c(1, &eukrea_cpuimx51_i2c_data);270i2c_register_board_info(1, eukrea_cpuimx51_i2c_devices,271ARRAY_SIZE(eukrea_cpuimx51_i2c_devices));272273if (otg_mode_host)274mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);275else {276initialize_otg_port(NULL);277mxc_register_device(&mxc_usbdr_udc_device, &usb_pdata);278}279mxc_register_device(&mxc_usbh1_device, &usbh1_config);280281#ifdef CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD282eukrea_mbimx51_baseboard_init();283#endif284}285286static void __init eukrea_cpuimx51_timer_init(void)287{288mx51_clocks_init(32768, 24000000, 22579200, 0);289}290291static struct sys_timer mxc_timer = {292.init = eukrea_cpuimx51_timer_init,293};294295MACHINE_START(EUKREA_CPUIMX51, "Eukrea CPUIMX51 Module")296/* Maintainer: Eric Bénard <[email protected]> */297.boot_params = MX51_PHYS_OFFSET + 0x100,298.map_io = mx51_map_io,299.init_early = imx51_init_early,300.init_irq = mx51_init_irq,301.timer = &mxc_timer,302.init_machine = eukrea_cpuimx51_init,303MACHINE_END304305306