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