Logo Search packages:      
Sourcecode: linux version File versions  Download package

setup.c

/*
 * arch/sh/boards/renesas/r7780rp/setup.c
 *
 * Renesas Solutions Highlander Support.
 *
 * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
 * Copyright (C) 2005 - 2008 Paul Mundt
 *
 * This contains support for the R7780RP-1, R7780MP, and R7785RP
 * Highlander modules.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <net/ax88796.h>
#include <asm/machvec.h>
#include <asm/r7780rp.h>
#include <asm/clock.h>
#include <asm/heartbeat.h>
#include <asm/io.h>
#include <asm/io_trapped.h>

static struct resource r8a66597_usb_host_resources[] = {
      [0] = {
            .name = "r8a66597_hcd",
            .start      = 0xA4200000,
            .end  = 0xA42000FF,
            .flags      = IORESOURCE_MEM,
      },
      [1] = {
            .name = "r8a66597_hcd",
            .start      = IRQ_EXT1,       /* irq number */
            .end  = IRQ_EXT1,
            .flags      = IORESOURCE_IRQ,
      },
};

static struct platform_device r8a66597_usb_host_device = {
      .name       = "r8a66597_hcd",
      .id         = -1,
      .dev = {
            .dma_mask         = NULL,           /* don't use dma */
            .coherent_dma_mask      = 0xffffffff,
      },
      .num_resources    = ARRAY_SIZE(r8a66597_usb_host_resources),
      .resource   = r8a66597_usb_host_resources,
};

static struct resource m66592_usb_peripheral_resources[] = {
      [0] = {
            .name = "m66592_udc",
            .start      = 0xb0000000,
            .end  = 0xb00000FF,
            .flags      = IORESOURCE_MEM,
      },
      [1] = {
            .name = "m66592_udc",
            .start      = IRQ_EXT4,       /* irq number */
            .end  = IRQ_EXT4,
            .flags      = IORESOURCE_IRQ,
      },
};

static struct platform_device m66592_usb_peripheral_device = {
      .name       = "m66592_udc",
      .id         = -1,
      .dev = {
            .dma_mask         = NULL,           /* don't use dma */
            .coherent_dma_mask      = 0xffffffff,
      },
      .num_resources    = ARRAY_SIZE(m66592_usb_peripheral_resources),
      .resource   = m66592_usb_peripheral_resources,
};

static struct resource cf_ide_resources[] = {
      [0] = {
            .start      = PA_AREA5_IO + 0x1000,
            .end  = PA_AREA5_IO + 0x1000 + 0x08 - 1,
            .flags      = IORESOURCE_MEM,
      },
      [1] = {
            .start      = PA_AREA5_IO + 0x80c,
            .end  = PA_AREA5_IO + 0x80c + 0x16 - 1,
            .flags      = IORESOURCE_MEM,
      },
      [2] = {
            .start      = IRQ_CF,
            .flags      = IORESOURCE_IRQ,
      },
};

static struct pata_platform_info pata_info = {
      .ioport_shift     = 1,
};

static struct platform_device cf_ide_device  = {
      .name       = "pata_platform",
      .id         = -1,
      .num_resources    = ARRAY_SIZE(cf_ide_resources),
      .resource   = cf_ide_resources,
      .dev  = {
            .platform_data    = &pata_info,
      },
};

static struct resource heartbeat_resources[] = {
      [0] = {
            .start      = PA_OBLED,
            .end  = PA_OBLED,
            .flags      = IORESOURCE_MEM,
      },
};

#ifndef CONFIG_SH_R7785RP
static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 };

static struct heartbeat_data heartbeat_data = {
      .bit_pos    = heartbeat_bit_pos,
      .nr_bits    = ARRAY_SIZE(heartbeat_bit_pos),
};
#endif

static struct platform_device heartbeat_device = {
      .name       = "heartbeat",
      .id         = -1,

      /* R7785RP has a slightly more sensible FPGA.. */
#ifndef CONFIG_SH_R7785RP
      .dev  = {
            .platform_data    = &heartbeat_data,
      },
#endif
      .num_resources    = ARRAY_SIZE(heartbeat_resources),
      .resource   = heartbeat_resources,
};

static struct ax_plat_data ax88796_platdata = {
      .flags          = AXFLG_HAS_93CX6,
      .wordlength     = 2,
      .dcr_val        = 0x1,
      .rcr_val        = 0x40,
};

static struct resource ax88796_resources[] = {
      {
#ifdef CONFIG_SH_R7780RP
            .start  = 0xa5800400,
            .end    = 0xa5800400 + (0x20 * 0x2) - 1,
#else
            .start  = 0xa4100400,
            .end    = 0xa4100400 + (0x20 * 0x2) - 1,
#endif
            .flags  = IORESOURCE_MEM,
      },
      {
            .start  = IRQ_AX88796,
            .end    = IRQ_AX88796,
            .flags  = IORESOURCE_IRQ,
      },
};

static struct platform_device ax88796_device = {
      .name           = "ax88796",
      .id             = 0,

      .dev    = {
            .platform_data = &ax88796_platdata,
      },

      .num_resources  = ARRAY_SIZE(ax88796_resources),
      .resource       = ax88796_resources,
};

static struct resource smbus_resources[] = {
      [0] = {
            .start      = PA_SMCR,
            .end  = PA_SMCR + 0x100 - 1,
            .flags      = IORESOURCE_MEM,
      },
      [1] = {
            .start      = IRQ_SMBUS,
            .end  = IRQ_SMBUS,
            .flags      = IORESOURCE_IRQ,
      },
};

static struct platform_device smbus_device = {
      .name       = "i2c-highlander",
      .id         = 0,
      .num_resources    = ARRAY_SIZE(smbus_resources),
      .resource   = smbus_resources,
};

static struct i2c_board_info __initdata highlander_i2c_devices[] = {
      {
            I2C_BOARD_INFO("r2025sd", 0x32),
      },
};

static struct platform_device *r7780rp_devices[] __initdata = {
      &r8a66597_usb_host_device,
      &m66592_usb_peripheral_device,
      &heartbeat_device,
      &smbus_device,
#ifndef CONFIG_SH_R7780RP
      &ax88796_device,
#endif
};

/*
 * The CF is connected using a 16-bit bus where 8-bit operations are
 * unsupported. The linux ata driver is however using 8-bit operations, so
 * insert a trapped io filter to convert 8-bit operations into 16-bit.
 */
static struct trapped_io cf_trapped_io = {
      .resource         = cf_ide_resources,
      .num_resources          = 2,
      .minimum_bus_width      = 16,
};

static int __init r7780rp_devices_setup(void)
{
      int ret = 0;

#ifndef CONFIG_SH_R7780RP
      if (register_trapped_io(&cf_trapped_io) == 0)
            ret |= platform_device_register(&cf_ide_device);
#endif

      ret |= platform_add_devices(r7780rp_devices,
                            ARRAY_SIZE(r7780rp_devices));

      ret |= i2c_register_board_info(0, highlander_i2c_devices,
                               ARRAY_SIZE(highlander_i2c_devices));

      return ret;
}
device_initcall(r7780rp_devices_setup);

/*
 * Platform specific clocks
 */
static void ivdr_clk_enable(struct clk *clk)
{
      ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL);
}

static void ivdr_clk_disable(struct clk *clk)
{
      ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL);
}

static struct clk_ops ivdr_clk_ops = {
      .enable           = ivdr_clk_enable,
      .disable    = ivdr_clk_disable,
};

static struct clk ivdr_clk = {
      .name       = "ivdr_clk",
      .ops        = &ivdr_clk_ops,
};

static struct clk *r7780rp_clocks[] = {
      &ivdr_clk,
};

static void r7780rp_power_off(void)
{
      if (mach_is_r7780mp() || mach_is_r7785rp())
            ctrl_outw(0x0001, PA_POFF);
}

/*
 * Initialize the board
 */
static void __init highlander_setup(char **cmdline_p)
{
      u16 ver = ctrl_inw(PA_VERREG);
      int i;

      printk(KERN_INFO "Renesas Solutions Highlander %s support.\n",
                   mach_is_r7780rp() ? "R7780RP-1" :
                   mach_is_r7780mp() ? "R7780MP"       :
                                   "R7785RP");

      printk(KERN_INFO "Board version: %d (revision %d), "
                   "FPGA version: %d (revision %d)\n",
                   (ver >> 12) & 0xf, (ver >> 8) & 0xf,
                   (ver >>  4) & 0xf, ver & 0xf);

      /*
       * Enable the important clocks right away..
       */
      for (i = 0; i < ARRAY_SIZE(r7780rp_clocks); i++) {
            struct clk *clk = r7780rp_clocks[i];

            clk_register(clk);
            clk_enable(clk);
      }

      ctrl_outw(0x0000, PA_OBLED);  /* Clear LED. */

      if (mach_is_r7780rp())
            ctrl_outw(0x0001, PA_SDPOW);  /* SD Power ON */

      ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL);   /* Si13112 */

      pm_power_off = r7780rp_power_off;
}

static unsigned char irl2irq[HL_NR_IRL];

static int highlander_irq_demux(int irq)
{
      if (irq >= HL_NR_IRL || !irl2irq[irq])
            return irq;

      return irl2irq[irq];
}

static void __init highlander_init_irq(void)
{
      unsigned char *ucp = highlander_plat_irq_setup();

      if (ucp) {
            plat_irq_setup_pins(IRQ_MODE_IRL3210);
            memcpy(irl2irq, ucp, HL_NR_IRL);
      }
}

/*
 * The Machine Vector
 */
static struct sh_machine_vector mv_highlander __initmv = {
      .mv_name          = "Highlander",
      .mv_setup         = highlander_setup,
      .mv_init_irq            = highlander_init_irq,
      .mv_irq_demux           = highlander_irq_demux,
};

Generated by  Doxygen 1.6.0   Back to index