linux/arch/arm/mach-mv78xx0/common.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-mv78xx0/common.c
   3 *
   4 * Core functions for Marvell MV78xx0 SoCs
   5 *
   6 * This file is licensed under the terms of the GNU General Public
   7 * License version 2.  This program is licensed "as is" without any
   8 * warranty of any kind, whether express or implied.
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <linux/platform_device.h>
  14#include <linux/serial_8250.h>
  15#include <linux/mbus.h>
  16#include <linux/mv643xx_eth.h>
  17#include <linux/mv643xx_i2c.h>
  18#include <linux/ata_platform.h>
  19#include <linux/ethtool.h>
  20#include <asm/mach/map.h>
  21#include <asm/mach/time.h>
  22#include <mach/mv78xx0.h>
  23#include <mach/bridge-regs.h>
  24#include <plat/cache-feroceon-l2.h>
  25#include <plat/ehci-orion.h>
  26#include <plat/orion_nand.h>
  27#include <plat/time.h>
  28#include "common.h"
  29
  30
  31/*****************************************************************************
  32 * Common bits
  33 ****************************************************************************/
  34int mv78xx0_core_index(void)
  35{
  36        u32 extra;
  37
  38        /*
  39         * Read Extra Features register.
  40         */
  41        __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (extra));
  42
  43        return !!(extra & 0x00004000);
  44}
  45
  46static int get_hclk(void)
  47{
  48        int hclk;
  49
  50        /*
  51         * HCLK tick rate is configured by DEV_D[7:5] pins.
  52         */
  53        switch ((readl(SAMPLE_AT_RESET_LOW) >> 5) & 7) {
  54        case 0:
  55                hclk = 166666667;
  56                break;
  57        case 1:
  58                hclk = 200000000;
  59                break;
  60        case 2:
  61                hclk = 266666667;
  62                break;
  63        case 3:
  64                hclk = 333333333;
  65                break;
  66        case 4:
  67                hclk = 400000000;
  68                break;
  69        default:
  70                panic("unknown HCLK PLL setting: %.8x\n",
  71                        readl(SAMPLE_AT_RESET_LOW));
  72        }
  73
  74        return hclk;
  75}
  76
  77static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk)
  78{
  79        u32 cfg;
  80
  81        /*
  82         * Core #0 PCLK/L2CLK is configured by bits [13:8], core #1
  83         * PCLK/L2CLK by bits [19:14].
  84         */
  85        if (core_index == 0) {
  86                cfg = (readl(SAMPLE_AT_RESET_LOW) >> 8) & 0x3f;
  87        } else {
  88                cfg = (readl(SAMPLE_AT_RESET_LOW) >> 14) & 0x3f;
  89        }
  90
  91        /*
  92         * Bits [11:8] ([17:14] for core #1) configure the PCLK:HCLK
  93         * ratio (1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6).
  94         */
  95        *pclk = ((u64)hclk * (2 + (cfg & 0xf))) >> 1;
  96
  97        /*
  98         * Bits [13:12] ([19:18] for core #1) configure the PCLK:L2CLK
  99         * ratio (1, 2, 3).
 100         */
 101        *l2clk = *pclk / (((cfg >> 4) & 3) + 1);
 102}
 103
 104static int get_tclk(void)
 105{
 106        int tclk;
 107
 108        /*
 109         * TCLK tick rate is configured by DEV_A[2:0] strap pins.
 110         */
 111        switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
 112        case 1:
 113                tclk = 166666667;
 114                break;
 115        case 3:
 116                tclk = 200000000;
 117                break;
 118        default:
 119                panic("unknown TCLK PLL setting: %.8x\n",
 120                        readl(SAMPLE_AT_RESET_HIGH));
 121        }
 122
 123        return tclk;
 124}
 125
 126
 127/*****************************************************************************
 128 * I/O Address Mapping
 129 ****************************************************************************/
 130static struct map_desc mv78xx0_io_desc[] __initdata = {
 131        {
 132                .virtual        = MV78XX0_CORE_REGS_VIRT_BASE,
 133                .pfn            = 0,
 134                .length         = MV78XX0_CORE_REGS_SIZE,
 135                .type           = MT_DEVICE,
 136        }, {
 137                .virtual        = MV78XX0_PCIE_IO_VIRT_BASE(0),
 138                .pfn            = __phys_to_pfn(MV78XX0_PCIE_IO_PHYS_BASE(0)),
 139                .length         = MV78XX0_PCIE_IO_SIZE * 8,
 140                .type           = MT_DEVICE,
 141        }, {
 142                .virtual        = MV78XX0_REGS_VIRT_BASE,
 143                .pfn            = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),
 144                .length         = MV78XX0_REGS_SIZE,
 145                .type           = MT_DEVICE,
 146        },
 147};
 148
 149void __init mv78xx0_map_io(void)
 150{
 151        unsigned long phys;
 152
 153        /*
 154         * Map the right set of per-core registers depending on
 155         * which core we are running on.
 156         */
 157        if (mv78xx0_core_index() == 0) {
 158                phys = MV78XX0_CORE0_REGS_PHYS_BASE;
 159        } else {
 160                phys = MV78XX0_CORE1_REGS_PHYS_BASE;
 161        }
 162        mv78xx0_io_desc[0].pfn = __phys_to_pfn(phys);
 163
 164        iotable_init(mv78xx0_io_desc, ARRAY_SIZE(mv78xx0_io_desc));
 165}
 166
 167
 168/*****************************************************************************
 169 * EHCI
 170 ****************************************************************************/
 171static struct orion_ehci_data mv78xx0_ehci_data = {
 172        .dram           = &mv78xx0_mbus_dram_info,
 173        .phy_version    = EHCI_PHY_NA,
 174};
 175
 176static u64 ehci_dmamask = 0xffffffffUL;
 177
 178
 179/*****************************************************************************
 180 * EHCI0
 181 ****************************************************************************/
 182static struct resource mv78xx0_ehci0_resources[] = {
 183        {
 184                .start  = USB0_PHYS_BASE,
 185                .end    = USB0_PHYS_BASE + 0x0fff,
 186                .flags  = IORESOURCE_MEM,
 187        }, {
 188                .start  = IRQ_MV78XX0_USB_0,
 189                .end    = IRQ_MV78XX0_USB_0,
 190                .flags  = IORESOURCE_IRQ,
 191        },
 192};
 193
 194static struct platform_device mv78xx0_ehci0 = {
 195        .name           = "orion-ehci",
 196        .id             = 0,
 197        .dev            = {
 198                .dma_mask               = &ehci_dmamask,
 199                .coherent_dma_mask      = 0xffffffff,
 200                .platform_data          = &mv78xx0_ehci_data,
 201        },
 202        .resource       = mv78xx0_ehci0_resources,
 203        .num_resources  = ARRAY_SIZE(mv78xx0_ehci0_resources),
 204};
 205
 206void __init mv78xx0_ehci0_init(void)
 207{
 208        platform_device_register(&mv78xx0_ehci0);
 209}
 210
 211
 212/*****************************************************************************
 213 * EHCI1
 214 ****************************************************************************/
 215static struct resource mv78xx0_ehci1_resources[] = {
 216        {
 217                .start  = USB1_PHYS_BASE,
 218                .end    = USB1_PHYS_BASE + 0x0fff,
 219                .flags  = IORESOURCE_MEM,
 220        }, {
 221                .start  = IRQ_MV78XX0_USB_1,
 222                .end    = IRQ_MV78XX0_USB_1,
 223                .flags  = IORESOURCE_IRQ,
 224        },
 225};
 226
 227static struct platform_device mv78xx0_ehci1 = {
 228        .name           = "orion-ehci",
 229        .id             = 1,
 230        .dev            = {
 231                .dma_mask               = &ehci_dmamask,
 232                .coherent_dma_mask      = 0xffffffff,
 233                .platform_data          = &mv78xx0_ehci_data,
 234        },
 235        .resource       = mv78xx0_ehci1_resources,
 236        .num_resources  = ARRAY_SIZE(mv78xx0_ehci1_resources),
 237};
 238
 239void __init mv78xx0_ehci1_init(void)
 240{
 241        platform_device_register(&mv78xx0_ehci1);
 242}
 243
 244
 245/*****************************************************************************
 246 * EHCI2
 247 ****************************************************************************/
 248static struct resource mv78xx0_ehci2_resources[] = {
 249        {
 250                .start  = USB2_PHYS_BASE,
 251                .end    = USB2_PHYS_BASE + 0x0fff,
 252                .flags  = IORESOURCE_MEM,
 253        }, {
 254                .start  = IRQ_MV78XX0_USB_2,
 255                .end    = IRQ_MV78XX0_USB_2,
 256                .flags  = IORESOURCE_IRQ,
 257        },
 258};
 259
 260static struct platform_device mv78xx0_ehci2 = {
 261        .name           = "orion-ehci",
 262        .id             = 2,
 263        .dev            = {
 264                .dma_mask               = &ehci_dmamask,
 265                .coherent_dma_mask      = 0xffffffff,
 266                .platform_data          = &mv78xx0_ehci_data,
 267        },
 268        .resource       = mv78xx0_ehci2_resources,
 269        .num_resources  = ARRAY_SIZE(mv78xx0_ehci2_resources),
 270};
 271
 272void __init mv78xx0_ehci2_init(void)
 273{
 274        platform_device_register(&mv78xx0_ehci2);
 275}
 276
 277
 278/*****************************************************************************
 279 * GE00
 280 ****************************************************************************/
 281struct mv643xx_eth_shared_platform_data mv78xx0_ge00_shared_data = {
 282        .t_clk          = 0,
 283        .dram           = &mv78xx0_mbus_dram_info,
 284};
 285
 286static struct resource mv78xx0_ge00_shared_resources[] = {
 287        {
 288                .name   = "ge00 base",
 289                .start  = GE00_PHYS_BASE + 0x2000,
 290                .end    = GE00_PHYS_BASE + 0x3fff,
 291                .flags  = IORESOURCE_MEM,
 292        }, {
 293                .name   = "ge err irq",
 294                .start  = IRQ_MV78XX0_GE_ERR,
 295                .end    = IRQ_MV78XX0_GE_ERR,
 296                .flags  = IORESOURCE_IRQ,
 297        },
 298};
 299
 300static struct platform_device mv78xx0_ge00_shared = {
 301        .name           = MV643XX_ETH_SHARED_NAME,
 302        .id             = 0,
 303        .dev            = {
 304                .platform_data  = &mv78xx0_ge00_shared_data,
 305        },
 306        .num_resources  = ARRAY_SIZE(mv78xx0_ge00_shared_resources),
 307        .resource       = mv78xx0_ge00_shared_resources,
 308};
 309
 310static struct resource mv78xx0_ge00_resources[] = {
 311        {
 312                .name   = "ge00 irq",
 313                .start  = IRQ_MV78XX0_GE00_SUM,
 314                .end    = IRQ_MV78XX0_GE00_SUM,
 315                .flags  = IORESOURCE_IRQ,
 316        },
 317};
 318
 319static struct platform_device mv78xx0_ge00 = {
 320        .name           = MV643XX_ETH_NAME,
 321        .id             = 0,
 322        .num_resources  = 1,
 323        .resource       = mv78xx0_ge00_resources,
 324        .dev            = {
 325                .coherent_dma_mask      = 0xffffffff,
 326        },
 327};
 328
 329void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 330{
 331        eth_data->shared = &mv78xx0_ge00_shared;
 332        mv78xx0_ge00.dev.platform_data = eth_data;
 333
 334        platform_device_register(&mv78xx0_ge00_shared);
 335        platform_device_register(&mv78xx0_ge00);
 336}
 337
 338
 339/*****************************************************************************
 340 * GE01
 341 ****************************************************************************/
 342struct mv643xx_eth_shared_platform_data mv78xx0_ge01_shared_data = {
 343        .t_clk          = 0,
 344        .dram           = &mv78xx0_mbus_dram_info,
 345        .shared_smi     = &mv78xx0_ge00_shared,
 346};
 347
 348static struct resource mv78xx0_ge01_shared_resources[] = {
 349        {
 350                .name   = "ge01 base",
 351                .start  = GE01_PHYS_BASE + 0x2000,
 352                .end    = GE01_PHYS_BASE + 0x3fff,
 353                .flags  = IORESOURCE_MEM,
 354        },
 355};
 356
 357static struct platform_device mv78xx0_ge01_shared = {
 358        .name           = MV643XX_ETH_SHARED_NAME,
 359        .id             = 1,
 360        .dev            = {
 361                .platform_data  = &mv78xx0_ge01_shared_data,
 362        },
 363        .num_resources  = 1,
 364        .resource       = mv78xx0_ge01_shared_resources,
 365};
 366
 367static struct resource mv78xx0_ge01_resources[] = {
 368        {
 369                .name   = "ge01 irq",
 370                .start  = IRQ_MV78XX0_GE01_SUM,
 371                .end    = IRQ_MV78XX0_GE01_SUM,
 372                .flags  = IORESOURCE_IRQ,
 373        },
 374};
 375
 376static struct platform_device mv78xx0_ge01 = {
 377        .name           = MV643XX_ETH_NAME,
 378        .id             = 1,
 379        .num_resources  = 1,
 380        .resource       = mv78xx0_ge01_resources,
 381        .dev            = {
 382                .coherent_dma_mask      = 0xffffffff,
 383        },
 384};
 385
 386void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
 387{
 388        eth_data->shared = &mv78xx0_ge01_shared;
 389        mv78xx0_ge01.dev.platform_data = eth_data;
 390
 391        platform_device_register(&mv78xx0_ge01_shared);
 392        platform_device_register(&mv78xx0_ge01);
 393}
 394
 395
 396/*****************************************************************************
 397 * GE10
 398 ****************************************************************************/
 399struct mv643xx_eth_shared_platform_data mv78xx0_ge10_shared_data = {
 400        .t_clk          = 0,
 401        .dram           = &mv78xx0_mbus_dram_info,
 402        .shared_smi     = &mv78xx0_ge00_shared,
 403};
 404
 405static struct resource mv78xx0_ge10_shared_resources[] = {
 406        {
 407                .name   = "ge10 base",
 408                .start  = GE10_PHYS_BASE + 0x2000,
 409                .end    = GE10_PHYS_BASE + 0x3fff,
 410                .flags  = IORESOURCE_MEM,
 411        },
 412};
 413
 414static struct platform_device mv78xx0_ge10_shared = {
 415        .name           = MV643XX_ETH_SHARED_NAME,
 416        .id             = 2,
 417        .dev            = {
 418                .platform_data  = &mv78xx0_ge10_shared_data,
 419        },
 420        .num_resources  = 1,
 421        .resource       = mv78xx0_ge10_shared_resources,
 422};
 423
 424static struct resource mv78xx0_ge10_resources[] = {
 425        {
 426                .name   = "ge10 irq",
 427                .start  = IRQ_MV78XX0_GE10_SUM,
 428                .end    = IRQ_MV78XX0_GE10_SUM,
 429                .flags  = IORESOURCE_IRQ,
 430        },
 431};
 432
 433static struct platform_device mv78xx0_ge10 = {
 434        .name           = MV643XX_ETH_NAME,
 435        .id             = 2,
 436        .num_resources  = 1,
 437        .resource       = mv78xx0_ge10_resources,
 438        .dev            = {
 439                .coherent_dma_mask      = 0xffffffff,
 440        },
 441};
 442
 443void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
 444{
 445        u32 dev, rev;
 446
 447        eth_data->shared = &mv78xx0_ge10_shared;
 448        mv78xx0_ge10.dev.platform_data = eth_data;
 449
 450        /*
 451         * On the Z0, ge10 and ge11 are internally connected back
 452         * to back, and not brought out.
 453         */
 454        mv78xx0_pcie_id(&dev, &rev);
 455        if (dev == MV78X00_Z0_DEV_ID) {
 456                eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
 457                eth_data->speed = SPEED_1000;
 458                eth_data->duplex = DUPLEX_FULL;
 459        }
 460
 461        platform_device_register(&mv78xx0_ge10_shared);
 462        platform_device_register(&mv78xx0_ge10);
 463}
 464
 465
 466/*****************************************************************************
 467 * GE11
 468 ****************************************************************************/
 469struct mv643xx_eth_shared_platform_data mv78xx0_ge11_shared_data = {
 470        .t_clk          = 0,
 471        .dram           = &mv78xx0_mbus_dram_info,
 472        .shared_smi     = &mv78xx0_ge00_shared,
 473};
 474
 475static struct resource mv78xx0_ge11_shared_resources[] = {
 476        {
 477                .name   = "ge11 base",
 478                .start  = GE11_PHYS_BASE + 0x2000,
 479                .end    = GE11_PHYS_BASE + 0x3fff,
 480                .flags  = IORESOURCE_MEM,
 481        },
 482};
 483
 484static struct platform_device mv78xx0_ge11_shared = {
 485        .name           = MV643XX_ETH_SHARED_NAME,
 486        .id             = 3,
 487        .dev            = {
 488                .platform_data  = &mv78xx0_ge11_shared_data,
 489        },
 490        .num_resources  = 1,
 491        .resource       = mv78xx0_ge11_shared_resources,
 492};
 493
 494static struct resource mv78xx0_ge11_resources[] = {
 495        {
 496                .name   = "ge11 irq",
 497                .start  = IRQ_MV78XX0_GE11_SUM,
 498                .end    = IRQ_MV78XX0_GE11_SUM,
 499                .flags  = IORESOURCE_IRQ,
 500        },
 501};
 502
 503static struct platform_device mv78xx0_ge11 = {
 504        .name           = MV643XX_ETH_NAME,
 505        .id             = 3,
 506        .num_resources  = 1,
 507        .resource       = mv78xx0_ge11_resources,
 508        .dev            = {
 509                .coherent_dma_mask      = 0xffffffff,
 510        },
 511};
 512
 513void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
 514{
 515        u32 dev, rev;
 516
 517        eth_data->shared = &mv78xx0_ge11_shared;
 518        mv78xx0_ge11.dev.platform_data = eth_data;
 519
 520        /*
 521         * On the Z0, ge10 and ge11 are internally connected back
 522         * to back, and not brought out.
 523         */
 524        mv78xx0_pcie_id(&dev, &rev);
 525        if (dev == MV78X00_Z0_DEV_ID) {
 526                eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
 527                eth_data->speed = SPEED_1000;
 528                eth_data->duplex = DUPLEX_FULL;
 529        }
 530
 531        platform_device_register(&mv78xx0_ge11_shared);
 532        platform_device_register(&mv78xx0_ge11);
 533}
 534
 535/*****************************************************************************
 536 * I2C bus 0
 537 ****************************************************************************/
 538
 539static struct mv64xxx_i2c_pdata mv78xx0_i2c_0_pdata = {
 540        .freq_m         = 8, /* assumes 166 MHz TCLK */
 541        .freq_n         = 3,
 542        .timeout        = 1000, /* Default timeout of 1 second */
 543};
 544
 545static struct resource mv78xx0_i2c_0_resources[] = {
 546        {
 547                .start  = I2C_0_PHYS_BASE,
 548                .end    = I2C_0_PHYS_BASE + 0x1f,
 549                .flags  = IORESOURCE_MEM,
 550        }, {
 551                .start  = IRQ_MV78XX0_I2C_0,
 552                .end    = IRQ_MV78XX0_I2C_0,
 553                .flags  = IORESOURCE_IRQ,
 554        },
 555};
 556
 557
 558static struct platform_device mv78xx0_i2c_0 = {
 559        .name           = MV64XXX_I2C_CTLR_NAME,
 560        .id             = 0,
 561        .num_resources  = ARRAY_SIZE(mv78xx0_i2c_0_resources),
 562        .resource       = mv78xx0_i2c_0_resources,
 563        .dev            = {
 564                .platform_data  = &mv78xx0_i2c_0_pdata,
 565        },
 566};
 567
 568/*****************************************************************************
 569 * I2C bus 1
 570 ****************************************************************************/
 571
 572static struct mv64xxx_i2c_pdata mv78xx0_i2c_1_pdata = {
 573        .freq_m         = 8, /* assumes 166 MHz TCLK */
 574        .freq_n         = 3,
 575        .timeout        = 1000, /* Default timeout of 1 second */
 576};
 577
 578static struct resource mv78xx0_i2c_1_resources[] = {
 579        {
 580                .start  = I2C_1_PHYS_BASE,
 581                .end    = I2C_1_PHYS_BASE + 0x1f,
 582                .flags  = IORESOURCE_MEM,
 583        }, {
 584                .start  = IRQ_MV78XX0_I2C_1,
 585                .end    = IRQ_MV78XX0_I2C_1,
 586                .flags  = IORESOURCE_IRQ,
 587        },
 588};
 589
 590
 591static struct platform_device mv78xx0_i2c_1 = {
 592        .name           = MV64XXX_I2C_CTLR_NAME,
 593        .id             = 1,
 594        .num_resources  = ARRAY_SIZE(mv78xx0_i2c_1_resources),
 595        .resource       = mv78xx0_i2c_1_resources,
 596        .dev            = {
 597                .platform_data  = &mv78xx0_i2c_1_pdata,
 598        },
 599};
 600
 601void __init mv78xx0_i2c_init(void)
 602{
 603        platform_device_register(&mv78xx0_i2c_0);
 604        platform_device_register(&mv78xx0_i2c_1);
 605}
 606
 607/*****************************************************************************
 608 * SATA
 609 ****************************************************************************/
 610static struct resource mv78xx0_sata_resources[] = {
 611        {
 612                .name   = "sata base",
 613                .start  = SATA_PHYS_BASE,
 614                .end    = SATA_PHYS_BASE + 0x5000 - 1,
 615                .flags  = IORESOURCE_MEM,
 616        }, {
 617                .name   = "sata irq",
 618                .start  = IRQ_MV78XX0_SATA,
 619                .end    = IRQ_MV78XX0_SATA,
 620                .flags  = IORESOURCE_IRQ,
 621        },
 622};
 623
 624static struct platform_device mv78xx0_sata = {
 625        .name           = "sata_mv",
 626        .id             = 0,
 627        .dev            = {
 628                .coherent_dma_mask      = 0xffffffff,
 629        },
 630        .num_resources  = ARRAY_SIZE(mv78xx0_sata_resources),
 631        .resource       = mv78xx0_sata_resources,
 632};
 633
 634void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
 635{
 636        sata_data->dram = &mv78xx0_mbus_dram_info;
 637        mv78xx0_sata.dev.platform_data = sata_data;
 638        platform_device_register(&mv78xx0_sata);
 639}
 640
 641
 642/*****************************************************************************
 643 * UART0
 644 ****************************************************************************/
 645static struct plat_serial8250_port mv78xx0_uart0_data[] = {
 646        {
 647                .mapbase        = UART0_PHYS_BASE,
 648                .membase        = (char *)UART0_VIRT_BASE,
 649                .irq            = IRQ_MV78XX0_UART_0,
 650                .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
 651                .iotype         = UPIO_MEM,
 652                .regshift       = 2,
 653                .uartclk        = 0,
 654        }, {
 655        },
 656};
 657
 658static struct resource mv78xx0_uart0_resources[] = {
 659        {
 660                .start          = UART0_PHYS_BASE,
 661                .end            = UART0_PHYS_BASE + 0xff,
 662                .flags          = IORESOURCE_MEM,
 663        }, {
 664                .start          = IRQ_MV78XX0_UART_0,
 665                .end            = IRQ_MV78XX0_UART_0,
 666                .flags          = IORESOURCE_IRQ,
 667        },
 668};
 669
 670static struct platform_device mv78xx0_uart0 = {
 671        .name                   = "serial8250",
 672        .id                     = 0,
 673        .dev                    = {
 674                .platform_data  = mv78xx0_uart0_data,
 675        },
 676        .resource               = mv78xx0_uart0_resources,
 677        .num_resources          = ARRAY_SIZE(mv78xx0_uart0_resources),
 678};
 679
 680void __init mv78xx0_uart0_init(void)
 681{
 682        platform_device_register(&mv78xx0_uart0);
 683}
 684
 685
 686/*****************************************************************************
 687 * UART1
 688 ****************************************************************************/
 689static struct plat_serial8250_port mv78xx0_uart1_data[] = {
 690        {
 691                .mapbase        = UART1_PHYS_BASE,
 692                .membase        = (char *)UART1_VIRT_BASE,
 693                .irq            = IRQ_MV78XX0_UART_1,
 694                .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
 695                .iotype         = UPIO_MEM,
 696                .regshift       = 2,
 697                .uartclk        = 0,
 698        }, {
 699        },
 700};
 701
 702static struct resource mv78xx0_uart1_resources[] = {
 703        {
 704                .start          = UART1_PHYS_BASE,
 705                .end            = UART1_PHYS_BASE + 0xff,
 706                .flags          = IORESOURCE_MEM,
 707        }, {
 708                .start          = IRQ_MV78XX0_UART_1,
 709                .end            = IRQ_MV78XX0_UART_1,
 710                .flags          = IORESOURCE_IRQ,
 711        },
 712};
 713
 714static struct platform_device mv78xx0_uart1 = {
 715        .name                   = "serial8250",
 716        .id                     = 1,
 717        .dev                    = {
 718                .platform_data  = mv78xx0_uart1_data,
 719        },
 720        .resource               = mv78xx0_uart1_resources,
 721        .num_resources          = ARRAY_SIZE(mv78xx0_uart1_resources),
 722};
 723
 724void __init mv78xx0_uart1_init(void)
 725{
 726        platform_device_register(&mv78xx0_uart1);
 727}
 728
 729
 730/*****************************************************************************
 731 * UART2
 732 ****************************************************************************/
 733static struct plat_serial8250_port mv78xx0_uart2_data[] = {
 734        {
 735                .mapbase        = UART2_PHYS_BASE,
 736                .membase        = (char *)UART2_VIRT_BASE,
 737                .irq            = IRQ_MV78XX0_UART_2,
 738                .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
 739                .iotype         = UPIO_MEM,
 740                .regshift       = 2,
 741                .uartclk        = 0,
 742        }, {
 743        },
 744};
 745
 746static struct resource mv78xx0_uart2_resources[] = {
 747        {
 748                .start          = UART2_PHYS_BASE,
 749                .end            = UART2_PHYS_BASE + 0xff,
 750                .flags          = IORESOURCE_MEM,
 751        }, {
 752                .start          = IRQ_MV78XX0_UART_2,
 753                .end            = IRQ_MV78XX0_UART_2,
 754                .flags          = IORESOURCE_IRQ,
 755        },
 756};
 757
 758static struct platform_device mv78xx0_uart2 = {
 759        .name                   = "serial8250",
 760        .id                     = 2,
 761        .dev                    = {
 762                .platform_data  = mv78xx0_uart2_data,
 763        },
 764        .resource               = mv78xx0_uart2_resources,
 765        .num_resources          = ARRAY_SIZE(mv78xx0_uart2_resources),
 766};
 767
 768void __init mv78xx0_uart2_init(void)
 769{
 770        platform_device_register(&mv78xx0_uart2);
 771}
 772
 773
 774/*****************************************************************************
 775 * UART3
 776 ****************************************************************************/
 777static struct plat_serial8250_port mv78xx0_uart3_data[] = {
 778        {
 779                .mapbase        = UART3_PHYS_BASE,
 780                .membase        = (char *)UART3_VIRT_BASE,
 781                .irq            = IRQ_MV78XX0_UART_3,
 782                .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
 783                .iotype         = UPIO_MEM,
 784                .regshift       = 2,
 785                .uartclk        = 0,
 786        }, {
 787        },
 788};
 789
 790static struct resource mv78xx0_uart3_resources[] = {
 791        {
 792                .start          = UART3_PHYS_BASE,
 793                .end            = UART3_PHYS_BASE + 0xff,
 794                .flags          = IORESOURCE_MEM,
 795        }, {
 796                .start          = IRQ_MV78XX0_UART_3,
 797                .end            = IRQ_MV78XX0_UART_3,
 798                .flags          = IORESOURCE_IRQ,
 799        },
 800};
 801
 802static struct platform_device mv78xx0_uart3 = {
 803        .name                   = "serial8250",
 804        .id                     = 3,
 805        .dev                    = {
 806                .platform_data  = mv78xx0_uart3_data,
 807        },
 808        .resource               = mv78xx0_uart3_resources,
 809        .num_resources          = ARRAY_SIZE(mv78xx0_uart3_resources),
 810};
 811
 812void __init mv78xx0_uart3_init(void)
 813{
 814        platform_device_register(&mv78xx0_uart3);
 815}
 816
 817
 818/*****************************************************************************
 819 * Time handling
 820 ****************************************************************************/
 821static void mv78xx0_timer_init(void)
 822{
 823        orion_time_init(IRQ_MV78XX0_TIMER_1, get_tclk());
 824}
 825
 826struct sys_timer mv78xx0_timer = {
 827        .init = mv78xx0_timer_init,
 828};
 829
 830
 831/*****************************************************************************
 832 * General
 833 ****************************************************************************/
 834static char * __init mv78xx0_id(void)
 835{
 836        u32 dev, rev;
 837
 838        mv78xx0_pcie_id(&dev, &rev);
 839
 840        if (dev == MV78X00_Z0_DEV_ID) {
 841                if (rev == MV78X00_REV_Z0)
 842                        return "MV78X00-Z0";
 843                else
 844                        return "MV78X00-Rev-Unsupported";
 845        } else if (dev == MV78100_DEV_ID) {
 846                if (rev == MV78100_REV_A0)
 847                        return "MV78100-A0";
 848                else if (rev == MV78100_REV_A1)
 849                        return "MV78100-A1";
 850                else
 851                        return "MV78100-Rev-Unsupported";
 852        } else if (dev == MV78200_DEV_ID) {
 853                if (rev == MV78100_REV_A0)
 854                        return "MV78200-A0";
 855                else
 856                        return "MV78200-Rev-Unsupported";
 857        } else {
 858                return "Device-Unknown";
 859        }
 860}
 861
 862static int __init is_l2_writethrough(void)
 863{
 864        return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
 865}
 866
 867void __init mv78xx0_init(void)
 868{
 869        int core_index;
 870        int hclk;
 871        int pclk;
 872        int l2clk;
 873        int tclk;
 874
 875        core_index = mv78xx0_core_index();
 876        hclk = get_hclk();
 877        get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
 878        tclk = get_tclk();
 879
 880        printk(KERN_INFO "%s ", mv78xx0_id());
 881        printk("core #%d, ", core_index);
 882        printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
 883        printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
 884        printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
 885        printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000);
 886
 887        mv78xx0_setup_cpu_mbus();
 888
 889#ifdef CONFIG_CACHE_FEROCEON_L2
 890        feroceon_l2_init(is_l2_writethrough());
 891#endif
 892
 893        mv78xx0_ge00_shared_data.t_clk = tclk;
 894        mv78xx0_ge01_shared_data.t_clk = tclk;
 895        mv78xx0_ge10_shared_data.t_clk = tclk;
 896        mv78xx0_ge11_shared_data.t_clk = tclk;
 897        mv78xx0_uart0_data[0].uartclk = tclk;
 898        mv78xx0_uart1_data[0].uartclk = tclk;
 899        mv78xx0_uart2_data[0].uartclk = tclk;
 900        mv78xx0_uart3_data[0].uartclk = tclk;
 901}
 902
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.