alistair23-linux/arch/arm/mach-davinci/board-omapl138-hawk.c
Linus Torvalds 53575aa99d ARM: driver updates for 3.13
Updates of SoC-near drivers and other driver updates that makes more sense to
 take through our tree. In this case it's involved:
 
 - Some Davinci driver updates that has required corresponding platform code
   changes (gpio mostly)
 - CCI bindings and a few driver updates
 - Marvell mvebu patches for PCI MSI support (could have gone through the PCI
   tree for this release, but they were acked by Bjorn for 3.12 so we kept them
   through arm-soc).
 - Marvell dove switch-over to DT-based PCIe configuration
 - Misc updates for Samsung platform dmaengine drivers
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJSgBr3AAoJEIwa5zzehBx3QkEP/i0bm4V+AkNV/EXPxqXDf0Re
 WIKao/0UjqEfTLSx38F+GlsCdpiPkicPZls0tzAiuqWycx+gMiUlJ7XB+tFmQRk1
 RS4KzPQeALFVapjVLtid/Bls9OVI8NcNL1Dx7FISTURzrSzB+kXg7KIsq92SootW
 AHUMZbPQNqZoTYcRo9EFEBCm+7QwH1GmWIo5tID6sRhPIsj0xXrw/zOQDK4WDbkv
 ZmlR2PNdVTYNuKsWtBcINU5GGNcTCEpnLlHZ9QzVOGyP2M/S93FQdjjm+vDxBRC6
 0WsCCFzWc2boSyKrah8xcb7kox7+8HMXUFFAARfOJxvqnMpDCSQnQv0Hb2SiwbkF
 7AW90lj+E9KqleSVy1fjGOvx2MV8vhqFMoCYg2TXW2546JADGnCw2JOILfRcqMox
 JqIpc84Yhmnv2qFCDxdj9hLYqvhH3RjdLzaLhSfMPc8pjP1StMJzcNi7tN46KVqg
 60wU7DvJ0uWfacUGj7VBn88XiZvvJjO/laxj5UcZlS+kQzsysw4Tbriz9UeJK1yl
 N0LBl4iA9xn5aUEI/1kL8xzX+h01VodMCe6jIz3JBdE66vCX6d2Tf+zYpNHiGCsH
 kBfOpuYc1jVW6qTYqDWgO3IVdDdSGa096AF5vR3MOmtDidblq9QVVxxhDwscqO6J
 O0RIcxwZAzQGcO4F50PL
 =yCsK
 -----END PGP SIGNATURE-----

Merge tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM driver updates from Olof Johansson:
 "Updates of SoC-near drivers and other driver updates that makes more
  sense to take through our tree.  In this case it's involved:

   - Some Davinci driver updates that has required corresponding
     platform code changes (gpio mostly)
   - CCI bindings and a few driver updates
   - Marvell mvebu patches for PCI MSI support (could have gone through
     the PCI tree for this release, but they were acked by Bjorn for
     3.12 so we kept them through arm-soc).
   - Marvell dove switch-over to DT-based PCIe configuration
   - Misc updates for Samsung platform dmaengine drivers"

* tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (32 commits)
  ARM: S3C24XX: add dma pdata for s3c2410, s3c2440 and s3c2442
  dmaengine: s3c24xx-dma: add support for the s3c2410 type of controller
  ARM: S3C24XX: Fix possible dma selection warning
  PCI: mvebu: make local functions static
  PCI: mvebu: add I/O access wrappers
  PCI: mvebu: Dynamically detect if the PEX link is up to enable hot plug
  ARM: mvebu: fix gated clock documentation
  ARM: dove: remove legacy pcie and clock init
  ARM: dove: switch to DT probed mbus address windows
  ARM: SAMSUNG: set s3c24xx_dma_filter for s3c64xx-spi0 device
  ARM: S3C24XX: add platform-devices for new dma driver for s3c2412 and s3c2443
  dmaengine: add driver for Samsung s3c24xx SoCs
  ARM: S3C24XX: number the dma clocks
  PCI: mvebu: add support for Marvell Dove SoCs
  PCI: mvebu: add support for reset on GPIO
  PCI: mvebu: remove subsys_initcall
  PCI: mvebu: increment nports only for registered ports
  PCI: mvebu: move clock enable before register access
  PCI: mvebu: add support for MSI
  irqchip: armada-370-xp: implement MSI support
  ...
2013-11-11 17:05:37 +09:00

349 lines
8.2 KiB
C

/*
* Hawkboard.org based on TI's OMAP-L138 Platform
*
* Initial code: Syed Mohammed Khasim
*
* Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of
* any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/gpio.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <mach/cp_intc.h>
#include <mach/da8xx.h>
#include <mach/mux.h>
#define HAWKBOARD_PHY_ID "davinci_mdio-0:07"
#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12)
#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13)
#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4)
#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13)
static short omapl138_hawk_mii_pins[] __initdata = {
DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
DA850_MDIO_D,
-1
};
static __init void omapl138_hawk_config_emac(void)
{
void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
int ret;
u32 val;
struct davinci_soc_info *soc_info = &davinci_soc_info;
val = __raw_readl(cfgchip3);
val &= ~BIT(8);
ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins);
if (ret) {
pr_warn("%s: CPGMAC/MII mux setup failed: %d\n", __func__, ret);
return;
}
/* configure the CFGCHIP3 register for MII */
__raw_writel(val, cfgchip3);
pr_info("EMAC: MII PHY configured\n");
soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID;
ret = da8xx_register_emac();
if (ret)
pr_warn("%s: EMAC registration failed: %d\n", __func__, ret);
}
/*
* The following EDMA channels/slots are not being used by drivers (for
* example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard,
* hence they are being reserved for codecs on the DSP side.
*/
static const s16 da850_dma0_rsv_chans[][2] = {
/* (offset, number) */
{ 8, 6},
{24, 4},
{30, 2},
{-1, -1}
};
static const s16 da850_dma0_rsv_slots[][2] = {
/* (offset, number) */
{ 8, 6},
{24, 4},
{30, 50},
{-1, -1}
};
static const s16 da850_dma1_rsv_chans[][2] = {
/* (offset, number) */
{ 0, 28},
{30, 2},
{-1, -1}
};
static const s16 da850_dma1_rsv_slots[][2] = {
/* (offset, number) */
{ 0, 28},
{30, 90},
{-1, -1}
};
static struct edma_rsv_info da850_edma_cc0_rsv = {
.rsv_chans = da850_dma0_rsv_chans,
.rsv_slots = da850_dma0_rsv_slots,
};
static struct edma_rsv_info da850_edma_cc1_rsv = {
.rsv_chans = da850_dma1_rsv_chans,
.rsv_slots = da850_dma1_rsv_slots,
};
static struct edma_rsv_info *da850_edma_rsv[2] = {
&da850_edma_cc0_rsv,
&da850_edma_cc1_rsv,
};
static const short hawk_mmcsd0_pins[] = {
DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
DA850_GPIO3_12, DA850_GPIO3_13,
-1
};
static int da850_hawk_mmc_get_ro(int index)
{
return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN);
}
static int da850_hawk_mmc_get_cd(int index)
{
return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN);
}
static struct davinci_mmc_config da850_mmc_config = {
.get_ro = da850_hawk_mmc_get_ro,
.get_cd = da850_hawk_mmc_get_cd,
.wires = 4,
.max_freq = 50000000,
.caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
};
static __init void omapl138_hawk_mmc_init(void)
{
int ret;
ret = davinci_cfg_reg_list(hawk_mmcsd0_pins);
if (ret) {
pr_warn("%s: MMC/SD0 mux setup failed: %d\n", __func__, ret);
return;
}
ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN,
GPIOF_DIR_IN, "MMC CD");
if (ret < 0) {
pr_warn("%s: can not open GPIO %d\n",
__func__, DA850_HAWK_MMCSD_CD_PIN);
return;
}
ret = gpio_request_one(DA850_HAWK_MMCSD_WP_PIN,
GPIOF_DIR_IN, "MMC WP");
if (ret < 0) {
pr_warn("%s: can not open GPIO %d\n",
__func__, DA850_HAWK_MMCSD_WP_PIN);
goto mmc_setup_wp_fail;
}
ret = da8xx_register_mmcsd0(&da850_mmc_config);
if (ret) {
pr_warn("%s: MMC/SD0 registration failed: %d\n", __func__, ret);
goto mmc_setup_mmcsd_fail;
}
return;
mmc_setup_mmcsd_fail:
gpio_free(DA850_HAWK_MMCSD_WP_PIN);
mmc_setup_wp_fail:
gpio_free(DA850_HAWK_MMCSD_CD_PIN);
}
static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id);
static da8xx_ocic_handler_t hawk_usb_ocic_handler;
static const short da850_hawk_usb11_pins[] = {
DA850_GPIO2_4, DA850_GPIO6_13,
-1
};
static int hawk_usb_set_power(unsigned port, int on)
{
gpio_set_value(DA850_USB1_VBUS_PIN, on);
return 0;
}
static int hawk_usb_get_power(unsigned port)
{
return gpio_get_value(DA850_USB1_VBUS_PIN);
}
static int hawk_usb_get_oci(unsigned port)
{
return !gpio_get_value(DA850_USB1_OC_PIN);
}
static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler)
{
int irq = gpio_to_irq(DA850_USB1_OC_PIN);
int error = 0;
if (handler != NULL) {
hawk_usb_ocic_handler = handler;
error = request_irq(irq, omapl138_hawk_usb_ocic_irq,
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING,
"OHCI over-current indicator", NULL);
if (error)
pr_err("%s: could not request IRQ to watch "
"over-current indicator changes\n", __func__);
} else {
free_irq(irq, NULL);
}
return error;
}
static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = {
.set_power = hawk_usb_set_power,
.get_power = hawk_usb_get_power,
.get_oci = hawk_usb_get_oci,
.ocic_notify = hawk_usb_ocic_notify,
/* TPS2087 switch @ 5V */
.potpgt = (3 + 1) / 2, /* 3 ms max */
};
static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id)
{
hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1);
return IRQ_HANDLED;
}
static __init void omapl138_hawk_usb_init(void)
{
int ret;
u32 cfgchip2;
ret = davinci_cfg_reg_list(da850_hawk_usb11_pins);
if (ret) {
pr_warn("%s: USB 1.1 PinMux setup failed: %d\n", __func__, ret);
return;
}
/* Setup the Ref. clock frequency for the HAWK at 24 MHz. */
cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
cfgchip2 &= ~CFGCHIP2_REFFREQ;
cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
__raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
ret = gpio_request_one(DA850_USB1_VBUS_PIN,
GPIOF_DIR_OUT, "USB1 VBUS");
if (ret < 0) {
pr_err("%s: failed to request GPIO for USB 1.1 port "
"power control: %d\n", __func__, ret);
return;
}
ret = gpio_request_one(DA850_USB1_OC_PIN,
GPIOF_DIR_IN, "USB1 OC");
if (ret < 0) {
pr_err("%s: failed to request GPIO for USB 1.1 port "
"over-current indicator: %d\n", __func__, ret);
goto usb11_setup_oc_fail;
}
ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata);
if (ret) {
pr_warn("%s: USB 1.1 registration failed: %d\n", __func__, ret);
goto usb11_setup_fail;
}
return;
usb11_setup_fail:
gpio_free(DA850_USB1_OC_PIN);
usb11_setup_oc_fail:
gpio_free(DA850_USB1_VBUS_PIN);
}
static __init void omapl138_hawk_init(void)
{
int ret;
ret = da850_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
davinci_serial_init(da8xx_serial_device);
omapl138_hawk_config_emac();
ret = da850_register_edma(da850_edma_rsv);
if (ret)
pr_warn("%s: EDMA registration failed: %d\n", __func__, ret);
omapl138_hawk_mmc_init();
omapl138_hawk_usb_init();
ret = da8xx_register_watchdog();
if (ret)
pr_warn("%s: watchdog registration failed: %d\n",
__func__, ret);
ret = da8xx_register_rproc();
if (ret)
pr_warn("%s: dsp/rproc registration failed: %d\n",
__func__, ret);
}
#ifdef CONFIG_SERIAL_8250_CONSOLE
static int __init omapl138_hawk_console_init(void)
{
if (!machine_is_omapl138_hawkboard())
return 0;
return add_preferred_console("ttyS", 2, "115200");
}
console_initcall(omapl138_hawk_console_init);
#endif
static void __init omapl138_hawk_map_io(void)
{
da850_init();
}
MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
.atag_offset = 0x100,
.map_io = omapl138_hawk_map_io,
.init_irq = cp_intc_init,
.init_time = davinci_timer_init,
.init_machine = omapl138_hawk_init,
.init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = da8xx_restart,
.reserve = da8xx_rproc_reserve_cma,
MACHINE_END