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