linux/arch/sh/kernel/cpu/sh4a/setup-shx3.c
<<
>>
Prefs
   1/*
   2 * SH-X3 Prototype Setup
   3 *
   4 *  Copyright (C) 2007 - 2010  Paul Mundt
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file "COPYING" in the main directory of this archive
   8 * for more details.
   9 */
  10#include <linux/platform_device.h>
  11#include <linux/init.h>
  12#include <linux/serial.h>
  13#include <linux/serial_sci.h>
  14#include <linux/io.h>
  15#include <linux/gpio.h>
  16#include <linux/sh_timer.h>
  17#include <linux/sh_intc.h>
  18#include <cpu/shx3.h>
  19#include <asm/mmzone.h>
  20
  21/*
  22 * This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2
  23 * INTEVT values overlap with the FPU EXPEVT ones, requiring special
  24 * demuxing in the exception dispatch path.
  25 *
  26 * As this overlap is something that never should have made it in to
  27 * silicon in the first place, we just refuse to deal with the port at
  28 * all rather than adding infrastructure to hack around it.
  29 */
  30static struct plat_sci_port scif0_platform_data = {
  31        .scscr          = SCSCR_REIE,
  32        .type           = PORT_SCIF,
  33};
  34
  35static struct resource scif0_resources[] = {
  36        DEFINE_RES_MEM(0xffc30000, 0x100),
  37        DEFINE_RES_IRQ(evt2irq(0x700)),
  38        DEFINE_RES_IRQ(evt2irq(0x720)),
  39        DEFINE_RES_IRQ(evt2irq(0x760)),
  40        DEFINE_RES_IRQ(evt2irq(0x740)),
  41};
  42
  43static struct platform_device scif0_device = {
  44        .name           = "sh-sci",
  45        .id             = 0,
  46        .resource       = scif0_resources,
  47        .num_resources  = ARRAY_SIZE(scif0_resources),
  48        .dev            = {
  49                .platform_data  = &scif0_platform_data,
  50        },
  51};
  52
  53static struct plat_sci_port scif1_platform_data = {
  54        .scscr          = SCSCR_REIE,
  55        .type           = PORT_SCIF,
  56};
  57
  58static struct resource scif1_resources[] = {
  59        DEFINE_RES_MEM(0xffc40000, 0x100),
  60        DEFINE_RES_IRQ(evt2irq(0x780)),
  61        DEFINE_RES_IRQ(evt2irq(0x7a0)),
  62        DEFINE_RES_IRQ(evt2irq(0x7e0)),
  63        DEFINE_RES_IRQ(evt2irq(0x7c0)),
  64};
  65
  66static struct platform_device scif1_device = {
  67        .name           = "sh-sci",
  68        .id             = 1,
  69        .resource       = scif1_resources,
  70        .num_resources  = ARRAY_SIZE(scif1_resources),
  71        .dev            = {
  72                .platform_data  = &scif1_platform_data,
  73        },
  74};
  75
  76static struct plat_sci_port scif2_platform_data = {
  77        .scscr          = SCSCR_REIE,
  78        .type           = PORT_SCIF,
  79};
  80
  81static struct resource scif2_resources[] = {
  82        DEFINE_RES_MEM(0xffc60000, 0x100),
  83        DEFINE_RES_IRQ(evt2irq(0x880)),
  84        DEFINE_RES_IRQ(evt2irq(0x8a0)),
  85        DEFINE_RES_IRQ(evt2irq(0x8e0)),
  86        DEFINE_RES_IRQ(evt2irq(0x8c0)),
  87};
  88
  89static struct platform_device scif2_device = {
  90        .name           = "sh-sci",
  91        .id             = 2,
  92        .resource       = scif2_resources,
  93        .num_resources  = ARRAY_SIZE(scif2_resources),
  94        .dev            = {
  95                .platform_data  = &scif2_platform_data,
  96        },
  97};
  98
  99static struct sh_timer_config tmu0_platform_data = {
 100        .channels_mask = 7,
 101};
 102
 103static struct resource tmu0_resources[] = {
 104        DEFINE_RES_MEM(0xffc10000, 0x30),
 105        DEFINE_RES_IRQ(evt2irq(0x400)),
 106        DEFINE_RES_IRQ(evt2irq(0x420)),
 107        DEFINE_RES_IRQ(evt2irq(0x440)),
 108};
 109
 110static struct platform_device tmu0_device = {
 111        .name           = "sh-tmu",
 112        .id             = 0,
 113        .dev = {
 114                .platform_data  = &tmu0_platform_data,
 115        },
 116        .resource       = tmu0_resources,
 117        .num_resources  = ARRAY_SIZE(tmu0_resources),
 118};
 119
 120static struct sh_timer_config tmu1_platform_data = {
 121        .channels_mask = 7,
 122};
 123
 124static struct resource tmu1_resources[] = {
 125        DEFINE_RES_MEM(0xffc20000, 0x2c),
 126        DEFINE_RES_IRQ(evt2irq(0x460)),
 127        DEFINE_RES_IRQ(evt2irq(0x480)),
 128        DEFINE_RES_IRQ(evt2irq(0x4a0)),
 129};
 130
 131static struct platform_device tmu1_device = {
 132        .name           = "sh-tmu",
 133        .id             = 1,
 134        .dev = {
 135                .platform_data  = &tmu1_platform_data,
 136        },
 137        .resource       = tmu1_resources,
 138        .num_resources  = ARRAY_SIZE(tmu1_resources),
 139};
 140
 141static struct platform_device *shx3_early_devices[] __initdata = {
 142        &scif0_device,
 143        &scif1_device,
 144        &scif2_device,
 145        &tmu0_device,
 146        &tmu1_device,
 147};
 148
 149static int __init shx3_devices_setup(void)
 150{
 151        return platform_add_devices(shx3_early_devices,
 152                                   ARRAY_SIZE(shx3_early_devices));
 153}
 154arch_initcall(shx3_devices_setup);
 155
 156void __init plat_early_device_setup(void)
 157{
 158        early_platform_add_devices(shx3_early_devices,
 159                                   ARRAY_SIZE(shx3_early_devices));
 160}
 161
 162enum {
 163        UNUSED = 0,
 164
 165        /* interrupt sources */
 166        IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
 167        IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
 168        IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
 169        IRL_HHLL, IRL_HHLH, IRL_HHHL,
 170        IRQ0, IRQ1, IRQ2, IRQ3,
 171        HUDII,
 172        TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
 173        PCII0, PCII1, PCII2, PCII3, PCII4,
 174        PCII5, PCII6, PCII7, PCII8, PCII9,
 175        SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
 176        SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
 177        SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
 178        SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI,
 179        DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
 180        DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
 181        DU,
 182        DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
 183        DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
 184        IIC, VIN0, VIN1, VCORE0, ATAPI,
 185        DTU0, DTU1, DTU2, DTU3,
 186        FE0, FE1,
 187        GPIO0, GPIO1, GPIO2, GPIO3,
 188        PAM, IRM,
 189        INTICI0, INTICI1, INTICI2, INTICI3,
 190        INTICI4, INTICI5, INTICI6, INTICI7,
 191
 192        /* interrupt groups */
 193        IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
 194        DMAC0, DMAC1,
 195};
 196
 197static struct intc_vect vectors[] __initdata = {
 198        INTC_VECT(HUDII, 0x3e0),
 199        INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
 200        INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460),
 201        INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0),
 202        INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520),
 203        INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560),
 204        INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0),
 205        INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0),
 206        INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620),
 207        INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
 208        INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
 209        INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
 210        INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
 211        INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
 212        INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
 213        INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
 214        INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960),
 215        INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0),
 216        INTC_VECT(DMAC0_DMAE, 0x9c0),
 217        INTC_VECT(DU, 0x9e0),
 218        INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20),
 219        INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60),
 220        INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0),
 221        INTC_VECT(DMAC1_DMAE, 0xac0),
 222        INTC_VECT(IIC, 0xae0),
 223        INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
 224        INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
 225        INTC_VECT(DTU0, 0xc00), INTC_VECT(DTU0, 0xc20),
 226        INTC_VECT(DTU0, 0xc40),
 227        INTC_VECT(DTU1, 0xc60), INTC_VECT(DTU1, 0xc80),
 228        INTC_VECT(DTU1, 0xca0),
 229        INTC_VECT(DTU2, 0xcc0), INTC_VECT(DTU2, 0xce0),
 230        INTC_VECT(DTU2, 0xd00),
 231        INTC_VECT(DTU3, 0xd20), INTC_VECT(DTU3, 0xd40),
 232        INTC_VECT(DTU3, 0xd60),
 233        INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
 234        INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
 235        INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
 236        INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0),
 237        INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
 238        INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
 239        INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
 240        INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
 241};
 242
 243static struct intc_group groups[] __initdata = {
 244        INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
 245                   IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
 246                   IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
 247                   IRL_HHLL, IRL_HHLH, IRL_HHHL),
 248        INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
 249        INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
 250        INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
 251        INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
 252        INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
 253                   DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
 254        INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
 255                   DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
 256};
 257
 258#define INT2DISTCR0     0xfe4108a0
 259#define INT2DISTCR1     0xfe4108a4
 260#define INT2DISTCR2     0xfe4108a8
 261
 262static struct intc_mask_reg mask_registers[] __initdata = {
 263        { 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
 264          { IRQ0, IRQ1, IRQ2, IRQ3 } },
 265        { 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */
 266          { IRL } },
 267        { 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */
 268          { FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
 269            DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
 270            0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
 271            0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, },
 272            INTC_SMP_BALANCING(INT2DISTCR0) },
 273        { 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
 274          { 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
 275            PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
 276            PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
 277            DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
 278            DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
 279            DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 },
 280            INTC_SMP_BALANCING(INT2DISTCR1) },
 281        { 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
 282          { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 283            SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
 284            SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
 285            SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
 286            SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI },
 287            INTC_SMP_BALANCING(INT2DISTCR2) },
 288};
 289
 290static struct intc_prio_reg prio_registers[] __initdata = {
 291        { 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
 292
 293        { 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4,
 294                                                 TMU3, TMU2, TMU1, TMU0 } },
 295        { 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0,
 296                                                 SCIF3, SCIF2,
 297                                                 SCIF1, SCIF0 } },
 298        { 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0,
 299                                                 PCII56789, PCII4,
 300                                                 PCII3, PCII2,
 301                                                 PCII1, PCII0 } },
 302        { 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0,
 303                                                 VIN1, VIN0, IIC, DU} },
 304        { 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3,
 305                                                 GPIO2, GPIO1, GPIO0, IRM } },
 306        { 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
 307          { INTICI7, INTICI6, INTICI5, INTICI4,
 308            INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) },
 309};
 310
 311static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups,
 312                         mask_registers, prio_registers, NULL);
 313
 314/* Support for external interrupt pins in IRQ mode */
 315static struct intc_vect vectors_irq[] __initdata = {
 316        INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
 317        INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
 318};
 319
 320static struct intc_sense_reg sense_registers[] __initdata = {
 321        { 0xfe41001c, 32, 2, /* ICR1 */   { IRQ0, IRQ1, IRQ2, IRQ3 } },
 322};
 323
 324static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
 325                         mask_registers, prio_registers, sense_registers);
 326
 327/* External interrupt pins in IRL mode */
 328static struct intc_vect vectors_irl[] __initdata = {
 329        INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
 330        INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
 331        INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
 332        INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
 333        INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
 334        INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
 335        INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
 336        INTC_VECT(IRL_HHHL, 0x3c0),
 337};
 338
 339static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
 340                         mask_registers, prio_registers, NULL);
 341
 342void __init plat_irq_setup_pins(int mode)
 343{
 344        int ret = 0;
 345
 346        switch (mode) {
 347        case IRQ_MODE_IRQ:
 348                ret |= gpio_request(GPIO_FN_IRQ3, intc_desc_irq.name);
 349                ret |= gpio_request(GPIO_FN_IRQ2, intc_desc_irq.name);
 350                ret |= gpio_request(GPIO_FN_IRQ1, intc_desc_irq.name);
 351                ret |= gpio_request(GPIO_FN_IRQ0, intc_desc_irq.name);
 352
 353                if (unlikely(ret)) {
 354                        pr_err("Failed to set IRQ mode\n");
 355                        return;
 356                }
 357
 358                register_intc_controller(&intc_desc_irq);
 359                break;
 360        case IRQ_MODE_IRL3210:
 361                ret |= gpio_request(GPIO_FN_IRL3, intc_desc_irl.name);
 362                ret |= gpio_request(GPIO_FN_IRL2, intc_desc_irl.name);
 363                ret |= gpio_request(GPIO_FN_IRL1, intc_desc_irl.name);
 364                ret |= gpio_request(GPIO_FN_IRL0, intc_desc_irl.name);
 365
 366                if (unlikely(ret)) {
 367                        pr_err("Failed to set IRL mode\n");
 368                        return;
 369                }
 370
 371                register_intc_controller(&intc_desc_irl);
 372                break;
 373        default:
 374                BUG();
 375        }
 376}
 377
 378void __init plat_irq_setup(void)
 379{
 380        register_intc_controller(&intc_desc);
 381}
 382
 383void __init plat_mem_setup(void)
 384{
 385        unsigned int nid = 1;
 386
 387        /* Register CPU#0 URAM space as Node 1 */
 388        setup_bootmem_node(nid++, 0x145f0000, 0x14610000);      /* CPU0 */
 389
 390#if 0
 391        /* XXX: Not yet.. */
 392        setup_bootmem_node(nid++, 0x14df0000, 0x14e10000);      /* CPU1 */
 393        setup_bootmem_node(nid++, 0x155f0000, 0x15610000);      /* CPU2 */
 394        setup_bootmem_node(nid++, 0x15df0000, 0x15e10000);      /* CPU3 */
 395#endif
 396
 397        setup_bootmem_node(nid++, 0x16000000, 0x16020000);      /* CSM */
 398}
 399