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