linux/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
<<
>>
Prefs
   1/*
   2 * SH7763 Setup
   3 *
   4 *  Copyright (C) 2006  Paul Mundt
   5 *  Copyright (C) 2007  Yoshihiro Shimoda
   6 *  Copyright (C) 2008, 2009  Nobuhiro Iwamatsu
   7 *
   8 * This file is subject to the terms and conditions of the GNU General Public
   9 * License.  See the file "COPYING" in the main directory of this archive
  10 * for more details.
  11 */
  12#include <linux/platform_device.h>
  13#include <linux/init.h>
  14#include <linux/serial.h>
  15#include <linux/sh_timer.h>
  16#include <linux/sh_intc.h>
  17#include <linux/io.h>
  18#include <linux/serial_sci.h>
  19#include <linux/usb/ohci_pdriver.h>
  20
  21static struct plat_sci_port scif0_platform_data = {
  22        .scscr          = SCSCR_REIE,
  23        .type           = PORT_SCIF,
  24        .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
  25};
  26
  27static struct resource scif0_resources[] = {
  28        DEFINE_RES_MEM(0xffe00000, 0x100),
  29        DEFINE_RES_IRQ(evt2irq(0x700)),
  30};
  31
  32static struct platform_device scif0_device = {
  33        .name           = "sh-sci",
  34        .id             = 0,
  35        .resource       = scif0_resources,
  36        .num_resources  = ARRAY_SIZE(scif0_resources),
  37        .dev            = {
  38                .platform_data  = &scif0_platform_data,
  39        },
  40};
  41
  42static struct plat_sci_port scif1_platform_data = {
  43        .scscr          = SCSCR_REIE,
  44        .type           = PORT_SCIF,
  45        .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
  46};
  47
  48static struct resource scif1_resources[] = {
  49        DEFINE_RES_MEM(0xffe08000, 0x100),
  50        DEFINE_RES_IRQ(evt2irq(0xb80)),
  51};
  52
  53static struct platform_device scif1_device = {
  54        .name           = "sh-sci",
  55        .id             = 1,
  56        .resource       = scif1_resources,
  57        .num_resources  = ARRAY_SIZE(scif1_resources),
  58        .dev            = {
  59                .platform_data  = &scif1_platform_data,
  60        },
  61};
  62
  63static struct plat_sci_port scif2_platform_data = {
  64        .scscr          = SCSCR_REIE,
  65        .type           = PORT_SCIF,
  66        .regtype        = SCIx_SH4_SCIF_FIFODATA_REGTYPE,
  67};
  68
  69static struct resource scif2_resources[] = {
  70        DEFINE_RES_MEM(0xffe10000, 0x100),
  71        DEFINE_RES_IRQ(evt2irq(0xf00)),
  72};
  73
  74static struct platform_device scif2_device = {
  75        .name           = "sh-sci",
  76        .id             = 2,
  77        .resource       = scif2_resources,
  78        .num_resources  = ARRAY_SIZE(scif2_resources),
  79        .dev            = {
  80                .platform_data  = &scif2_platform_data,
  81        },
  82};
  83
  84static struct resource rtc_resources[] = {
  85        [0] = {
  86                .start  = 0xffe80000,
  87                .end    = 0xffe80000 + 0x58 - 1,
  88                .flags  = IORESOURCE_IO,
  89        },
  90        [1] = {
  91                /* Shared Period/Carry/Alarm IRQ */
  92                .start  = evt2irq(0x480),
  93                .flags  = IORESOURCE_IRQ,
  94        },
  95};
  96
  97static struct platform_device rtc_device = {
  98        .name           = "sh-rtc",
  99        .id             = -1,
 100        .num_resources  = ARRAY_SIZE(rtc_resources),
 101        .resource       = rtc_resources,
 102};
 103
 104static struct resource usb_ohci_resources[] = {
 105        [0] = {
 106                .start  = 0xffec8000,
 107                .end    = 0xffec80ff,
 108                .flags  = IORESOURCE_MEM,
 109        },
 110        [1] = {
 111                .start  = evt2irq(0xc60),
 112                .end    = evt2irq(0xc60),
 113                .flags  = IORESOURCE_IRQ,
 114        },
 115};
 116
 117static u64 usb_ohci_dma_mask = 0xffffffffUL;
 118
 119static struct usb_ohci_pdata usb_ohci_pdata;
 120
 121static struct platform_device usb_ohci_device = {
 122        .name           = "ohci-platform",
 123        .id             = -1,
 124        .dev = {
 125                .dma_mask               = &usb_ohci_dma_mask,
 126                .coherent_dma_mask      = 0xffffffff,
 127                .platform_data          = &usb_ohci_pdata,
 128        },
 129        .num_resources  = ARRAY_SIZE(usb_ohci_resources),
 130        .resource       = usb_ohci_resources,
 131};
 132
 133static struct resource usbf_resources[] = {
 134        [0] = {
 135                .start  = 0xffec0000,
 136                .end    = 0xffec00ff,
 137                .flags  = IORESOURCE_MEM,
 138        },
 139        [1] = {
 140                .start  = evt2irq(0xc80),
 141                .end    = evt2irq(0xc80),
 142                .flags  = IORESOURCE_IRQ,
 143        },
 144};
 145
 146static struct platform_device usbf_device = {
 147        .name           = "sh_udc",
 148        .id             = -1,
 149        .dev = {
 150                .dma_mask               = NULL,
 151                .coherent_dma_mask      = 0xffffffff,
 152        },
 153        .num_resources  = ARRAY_SIZE(usbf_resources),
 154        .resource       = usbf_resources,
 155};
 156
 157static struct sh_timer_config tmu0_platform_data = {
 158        .channels_mask = 7,
 159};
 160
 161static struct resource tmu0_resources[] = {
 162        DEFINE_RES_MEM(0xffd80000, 0x30),
 163        DEFINE_RES_IRQ(evt2irq(0x580)),
 164        DEFINE_RES_IRQ(evt2irq(0x5a0)),
 165        DEFINE_RES_IRQ(evt2irq(0x5c0)),
 166};
 167
 168static struct platform_device tmu0_device = {
 169        .name           = "sh-tmu",
 170        .id             = 0,
 171        .dev = {
 172                .platform_data  = &tmu0_platform_data,
 173        },
 174        .resource       = tmu0_resources,
 175        .num_resources  = ARRAY_SIZE(tmu0_resources),
 176};
 177
 178static struct sh_timer_config tmu1_platform_data = {
 179        .channels_mask = 7,
 180};
 181
 182static struct resource tmu1_resources[] = {
 183        DEFINE_RES_MEM(0xffd88000, 0x2c),
 184        DEFINE_RES_IRQ(evt2irq(0xe00)),
 185        DEFINE_RES_IRQ(evt2irq(0xe20)),
 186        DEFINE_RES_IRQ(evt2irq(0xe40)),
 187};
 188
 189static struct platform_device tmu1_device = {
 190        .name           = "sh-tmu",
 191        .id             = 1,
 192        .dev = {
 193                .platform_data  = &tmu1_platform_data,
 194        },
 195        .resource       = tmu1_resources,
 196        .num_resources  = ARRAY_SIZE(tmu1_resources),
 197};
 198
 199static struct platform_device *sh7763_devices[] __initdata = {
 200        &scif0_device,
 201        &scif1_device,
 202        &scif2_device,
 203        &tmu0_device,
 204        &tmu1_device,
 205        &rtc_device,
 206        &usb_ohci_device,
 207        &usbf_device,
 208};
 209
 210static int __init sh7763_devices_setup(void)
 211{
 212        return platform_add_devices(sh7763_devices,
 213                                    ARRAY_SIZE(sh7763_devices));
 214}
 215arch_initcall(sh7763_devices_setup);
 216
 217static struct platform_device *sh7763_early_devices[] __initdata = {
 218        &scif0_device,
 219        &scif1_device,
 220        &scif2_device,
 221        &tmu0_device,
 222        &tmu1_device,
 223};
 224
 225void __init plat_early_device_setup(void)
 226{
 227        early_platform_add_devices(sh7763_early_devices,
 228                                   ARRAY_SIZE(sh7763_early_devices));
 229}
 230
 231enum {
 232        UNUSED = 0,
 233
 234        /* interrupt sources */
 235
 236        IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
 237        IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
 238        IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
 239        IRL_HHLL, IRL_HHLH, IRL_HHHL,
 240
 241        IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
 242        RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
 243        HUDI, LCDC, DMAC, SCIF0, IIC0, IIC1, CMT, GETHER, HAC,
 244        PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
 245        STIF0, STIF1, SCIF1, SIOF0, SIOF1, SIOF2,
 246        USBH, USBF, TPU, PCC, MMCIF, SIM,
 247        TMU3, TMU4, TMU5, ADC, SSI0, SSI1, SSI2, SSI3,
 248        SCIF2, GPIO,
 249
 250        /* interrupt groups */
 251
 252        TMU012, TMU345,
 253};
 254
 255static struct intc_vect vectors[] __initdata = {
 256        INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
 257        INTC_VECT(RTC, 0x4c0),
 258        INTC_VECT(WDT, 0x560), INTC_VECT(TMU0, 0x580),
 259        INTC_VECT(TMU1, 0x5a0), INTC_VECT(TMU2, 0x5c0),
 260        INTC_VECT(TMU2_TICPI, 0x5e0), INTC_VECT(HUDI, 0x600),
 261        INTC_VECT(LCDC, 0x620),
 262        INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
 263        INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
 264        INTC_VECT(DMAC, 0x6c0),
 265        INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
 266        INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
 267        INTC_VECT(DMAC, 0x780), INTC_VECT(DMAC, 0x7a0),
 268        INTC_VECT(IIC0, 0x8A0), INTC_VECT(IIC1, 0x8C0),
 269        INTC_VECT(CMT, 0x900), INTC_VECT(GETHER, 0x920),
 270        INTC_VECT(GETHER, 0x940), INTC_VECT(GETHER, 0x960),
 271        INTC_VECT(HAC, 0x980),
 272        INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
 273        INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
 274        INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
 275        INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
 276        INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
 277        INTC_VECT(STIF0, 0xb40), INTC_VECT(STIF1, 0xb60),
 278        INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),
 279        INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),
 280        INTC_VECT(SIOF0, 0xc00), INTC_VECT(SIOF1, 0xc20),
 281        INTC_VECT(USBH, 0xc60), INTC_VECT(USBF, 0xc80),
 282        INTC_VECT(USBF, 0xca0),
 283        INTC_VECT(TPU, 0xcc0), INTC_VECT(PCC, 0xce0),
 284        INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
 285        INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
 286        INTC_VECT(SIM, 0xd80), INTC_VECT(SIM, 0xda0),
 287        INTC_VECT(SIM, 0xdc0), INTC_VECT(SIM, 0xde0),
 288        INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
 289        INTC_VECT(TMU5, 0xe40), INTC_VECT(ADC, 0xe60),
 290        INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
 291        INTC_VECT(SSI2, 0xec0), INTC_VECT(SSI3, 0xee0),
 292        INTC_VECT(SCIF2, 0xf00), INTC_VECT(SCIF2, 0xf20),
 293        INTC_VECT(SCIF2, 0xf40), INTC_VECT(SCIF2, 0xf60),
 294        INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
 295        INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
 296};
 297
 298static struct intc_group groups[] __initdata = {
 299        INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
 300        INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
 301};
 302
 303static struct intc_mask_reg mask_registers[] __initdata = {
 304        { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
 305          { 0, 0, 0, 0, 0, 0, GPIO, 0,
 306            SSI0, MMCIF, 0, SIOF0, PCIC5, PCIINTD, PCIINTC, PCIINTB,
 307            PCIINTA, PCISERR, HAC, CMT, 0, 0, 0, DMAC,
 308            HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },
 309        { 0xffd400d0, 0xffd400d4, 32, /* INT2MSKR1 / INT2MSKCR1 */
 310          { 0, 0, 0, 0, 0, 0, SCIF2, USBF,
 311            0, 0, STIF1, STIF0, 0, 0, USBH, GETHER,
 312            PCC, 0, 0, ADC, TPU, SIM, SIOF2, SIOF1,
 313            LCDC, 0, IIC1, IIC0, SSI3, SSI2, SSI1, 0 } },
 314};
 315
 316static struct intc_prio_reg prio_registers[] __initdata = {
 317        { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
 318                                                 TMU2, TMU2_TICPI } },
 319        { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },
 320        { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },
 321        { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC, ADC } },
 322        { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC,
 323                                                 PCISERR, PCIINTA } },
 324        { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,
 325                                                 PCIINTD, PCIC5 } },
 326        { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF0, USBF, MMCIF, SSI0 } },
 327        { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { SCIF2, GPIO } },
 328        { 0xffd400a0, 0, 32, 8, /* INT2PRI8 */ { SSI3, SSI2, SSI1, 0 } },
 329        { 0xffd400a4, 0, 32, 8, /* INT2PRI9 */ { LCDC, 0, IIC1, IIC0 } },
 330        { 0xffd400a8, 0, 32, 8, /* INT2PRI10 */ { TPU, SIM, SIOF2, SIOF1 } },
 331        { 0xffd400ac, 0, 32, 8, /* INT2PRI11 */ { PCC } },
 332        { 0xffd400b0, 0, 32, 8, /* INT2PRI12 */ { 0, 0, USBH, GETHER } },
 333        { 0xffd400b4, 0, 32, 8, /* INT2PRI13 */ { 0, 0, STIF1, STIF0 } },
 334};
 335
 336static DECLARE_INTC_DESC(intc_desc, "sh7763", vectors, groups,
 337                         mask_registers, prio_registers, NULL);
 338
 339/* Support for external interrupt pins in IRQ mode */
 340static struct intc_vect irq_vectors[] __initdata = {
 341        INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
 342        INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
 343        INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
 344        INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
 345};
 346
 347static struct intc_mask_reg irq_mask_registers[] __initdata = {
 348        { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
 349          { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
 350};
 351
 352static struct intc_prio_reg irq_prio_registers[] __initdata = {
 353        { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
 354                                               IRQ4, IRQ5, IRQ6, IRQ7 } },
 355};
 356
 357static struct intc_sense_reg irq_sense_registers[] __initdata = {
 358        { 0xffd0001c, 32, 2, /* ICR1 */   { IRQ0, IRQ1, IRQ2, IRQ3,
 359                                            IRQ4, IRQ5, IRQ6, IRQ7 } },
 360};
 361
 362static struct intc_mask_reg irq_ack_registers[] __initdata = {
 363        { 0xffd00024, 0, 32, /* INTREQ */
 364          { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
 365};
 366
 367static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7763-irq", irq_vectors,
 368                             NULL, irq_mask_registers, irq_prio_registers,
 369                             irq_sense_registers, irq_ack_registers);
 370
 371
 372/* External interrupt pins in IRL mode */
 373static struct intc_vect irl_vectors[] __initdata = {
 374        INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
 375        INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
 376        INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
 377        INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
 378        INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
 379        INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
 380        INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
 381        INTC_VECT(IRL_HHHL, 0x3c0),
 382};
 383
 384static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
 385        { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
 386          { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
 387            IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
 388            IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
 389            IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
 390};
 391
 392static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
 393        { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
 394          { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 395            IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
 396            IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
 397            IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
 398            IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
 399};
 400
 401static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7763-irl7654", irl_vectors,
 402                        NULL, irl7654_mask_registers, NULL, NULL);
 403
 404static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors,
 405                        NULL, irl3210_mask_registers, NULL, NULL);
 406
 407#define INTC_ICR0       0xffd00000
 408#define INTC_INTMSK0    0xffd00044
 409#define INTC_INTMSK1    0xffd00048
 410#define INTC_INTMSK2    0xffd40080
 411#define INTC_INTMSKCLR1 0xffd00068
 412#define INTC_INTMSKCLR2 0xffd40084
 413
 414void __init plat_irq_setup(void)
 415{
 416        /* disable IRQ7-0 */
 417        __raw_writel(0xff000000, INTC_INTMSK0);
 418
 419        /* disable IRL3-0 + IRL7-4 */
 420        __raw_writel(0xc0000000, INTC_INTMSK1);
 421        __raw_writel(0xfffefffe, INTC_INTMSK2);
 422
 423        register_intc_controller(&intc_desc);
 424}
 425
 426void __init plat_irq_setup_pins(int mode)
 427{
 428        switch (mode) {
 429        case IRQ_MODE_IRQ:
 430                /* select IRQ mode for IRL3-0 + IRL7-4 */
 431                __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
 432                register_intc_controller(&intc_irq_desc);
 433                break;
 434        case IRQ_MODE_IRL7654:
 435                /* enable IRL7-4 but don't provide any masking */
 436                __raw_writel(0x40000000, INTC_INTMSKCLR1);
 437                __raw_writel(0x0000fffe, INTC_INTMSKCLR2);
 438                break;
 439        case IRQ_MODE_IRL3210:
 440                /* enable IRL0-3 but don't provide any masking */
 441                __raw_writel(0x80000000, INTC_INTMSKCLR1);
 442                __raw_writel(0xfffe0000, INTC_INTMSKCLR2);
 443                break;
 444        case IRQ_MODE_IRL7654_MASK:
 445                /* enable IRL7-4 and mask using cpu intc controller */
 446                __raw_writel(0x40000000, INTC_INTMSKCLR1);
 447                register_intc_controller(&intc_irl7654_desc);
 448                break;
 449        case IRQ_MODE_IRL3210_MASK:
 450                /* enable IRL0-3 and mask using cpu intc controller */
 451                __raw_writel(0x80000000, INTC_INTMSKCLR1);
 452                register_intc_controller(&intc_irl3210_desc);
 453                break;
 454        default:
 455                BUG();
 456        }
 457}
 458