linux/arch/arm/mach-kirkwood/common.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-kirkwood/common.c
   3 *
   4 * Core functions for Marvell Kirkwood 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/ata_platform.h>
  16#include <linux/mtd/nand.h>
  17#include <linux/dma-mapping.h>
  18#include <net/dsa.h>
  19#include <asm/page.h>
  20#include <asm/timex.h>
  21#include <asm/kexec.h>
  22#include <asm/mach/map.h>
  23#include <asm/mach/time.h>
  24#include <mach/kirkwood.h>
  25#include <mach/bridge-regs.h>
  26#include <plat/audio.h>
  27#include <plat/cache-feroceon-l2.h>
  28#include <plat/mvsdio.h>
  29#include <plat/orion_nand.h>
  30#include <plat/ehci-orion.h>
  31#include <plat/common.h>
  32#include <plat/time.h>
  33#include <plat/addr-map.h>
  34#include "common.h"
  35
  36/*****************************************************************************
  37 * I/O Address Mapping
  38 ****************************************************************************/
  39static struct map_desc kirkwood_io_desc[] __initdata = {
  40        {
  41                .virtual        = KIRKWOOD_PCIE_IO_VIRT_BASE,
  42                .pfn            = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
  43                .length         = KIRKWOOD_PCIE_IO_SIZE,
  44                .type           = MT_DEVICE,
  45        }, {
  46                .virtual        = KIRKWOOD_PCIE1_IO_VIRT_BASE,
  47                .pfn            = __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
  48                .length         = KIRKWOOD_PCIE1_IO_SIZE,
  49                .type           = MT_DEVICE,
  50        }, {
  51                .virtual        = KIRKWOOD_REGS_VIRT_BASE,
  52                .pfn            = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
  53                .length         = KIRKWOOD_REGS_SIZE,
  54                .type           = MT_DEVICE,
  55        },
  56};
  57
  58void __init kirkwood_map_io(void)
  59{
  60        iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
  61}
  62
  63/*
  64 * Default clock control bits.  Any bit _not_ set in this variable
  65 * will be cleared from the hardware after platform devices have been
  66 * registered.  Some reserved bits must be set to 1.
  67 */
  68unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
  69
  70
  71/*****************************************************************************
  72 * EHCI0
  73 ****************************************************************************/
  74void __init kirkwood_ehci_init(void)
  75{
  76        kirkwood_clk_ctrl |= CGC_USB0;
  77        orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA);
  78}
  79
  80
  81/*****************************************************************************
  82 * GE00
  83 ****************************************************************************/
  84void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
  85{
  86        kirkwood_clk_ctrl |= CGC_GE0;
  87
  88        orion_ge00_init(eth_data,
  89                        GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
  90                        IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk);
  91}
  92
  93
  94/*****************************************************************************
  95 * GE01
  96 ****************************************************************************/
  97void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
  98{
  99
 100        kirkwood_clk_ctrl |= CGC_GE1;
 101
 102        orion_ge01_init(eth_data,
 103                        GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
 104                        IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk);
 105}
 106
 107
 108/*****************************************************************************
 109 * Ethernet switch
 110 ****************************************************************************/
 111void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
 112{
 113        orion_ge00_switch_init(d, irq);
 114}
 115
 116
 117/*****************************************************************************
 118 * NAND flash
 119 ****************************************************************************/
 120static struct resource kirkwood_nand_resource = {
 121        .flags          = IORESOURCE_MEM,
 122        .start          = KIRKWOOD_NAND_MEM_PHYS_BASE,
 123        .end            = KIRKWOOD_NAND_MEM_PHYS_BASE +
 124                                KIRKWOOD_NAND_MEM_SIZE - 1,
 125};
 126
 127static struct orion_nand_data kirkwood_nand_data = {
 128        .cle            = 0,
 129        .ale            = 1,
 130        .width          = 8,
 131};
 132
 133static struct platform_device kirkwood_nand_flash = {
 134        .name           = "orion_nand",
 135        .id             = -1,
 136        .dev            = {
 137                .platform_data  = &kirkwood_nand_data,
 138        },
 139        .resource       = &kirkwood_nand_resource,
 140        .num_resources  = 1,
 141};
 142
 143void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
 144                               int chip_delay)
 145{
 146        kirkwood_clk_ctrl |= CGC_RUNIT;
 147        kirkwood_nand_data.parts = parts;
 148        kirkwood_nand_data.nr_parts = nr_parts;
 149        kirkwood_nand_data.chip_delay = chip_delay;
 150        platform_device_register(&kirkwood_nand_flash);
 151}
 152
 153void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
 154                                   int (*dev_ready)(struct mtd_info *))
 155{
 156        kirkwood_clk_ctrl |= CGC_RUNIT;
 157        kirkwood_nand_data.parts = parts;
 158        kirkwood_nand_data.nr_parts = nr_parts;
 159        kirkwood_nand_data.dev_ready = dev_ready;
 160        platform_device_register(&kirkwood_nand_flash);
 161}
 162
 163/*****************************************************************************
 164 * SoC RTC
 165 ****************************************************************************/
 166static void __init kirkwood_rtc_init(void)
 167{
 168        orion_rtc_init(RTC_PHYS_BASE, IRQ_KIRKWOOD_RTC);
 169}
 170
 171
 172/*****************************************************************************
 173 * SATA
 174 ****************************************************************************/
 175void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
 176{
 177        kirkwood_clk_ctrl |= CGC_SATA0;
 178        if (sata_data->n_ports > 1)
 179                kirkwood_clk_ctrl |= CGC_SATA1;
 180
 181        orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA);
 182}
 183
 184
 185/*****************************************************************************
 186 * SD/SDIO/MMC
 187 ****************************************************************************/
 188static struct resource mvsdio_resources[] = {
 189        [0] = {
 190                .start  = SDIO_PHYS_BASE,
 191                .end    = SDIO_PHYS_BASE + SZ_1K - 1,
 192                .flags  = IORESOURCE_MEM,
 193        },
 194        [1] = {
 195                .start  = IRQ_KIRKWOOD_SDIO,
 196                .end    = IRQ_KIRKWOOD_SDIO,
 197                .flags  = IORESOURCE_IRQ,
 198        },
 199};
 200
 201static u64 mvsdio_dmamask = DMA_BIT_MASK(32);
 202
 203static struct platform_device kirkwood_sdio = {
 204        .name           = "mvsdio",
 205        .id             = -1,
 206        .dev            = {
 207                .dma_mask = &mvsdio_dmamask,
 208                .coherent_dma_mask = DMA_BIT_MASK(32),
 209        },
 210        .num_resources  = ARRAY_SIZE(mvsdio_resources),
 211        .resource       = mvsdio_resources,
 212};
 213
 214void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
 215{
 216        u32 dev, rev;
 217
 218        kirkwood_pcie_id(&dev, &rev);
 219        if (rev == 0 && dev != MV88F6282_DEV_ID) /* catch all Kirkwood Z0's */
 220                mvsdio_data->clock = 100000000;
 221        else
 222                mvsdio_data->clock = 200000000;
 223        kirkwood_clk_ctrl |= CGC_SDIO;
 224        kirkwood_sdio.dev.platform_data = mvsdio_data;
 225        platform_device_register(&kirkwood_sdio);
 226}
 227
 228
 229/*****************************************************************************
 230 * SPI
 231 ****************************************************************************/
 232void __init kirkwood_spi_init()
 233{
 234        kirkwood_clk_ctrl |= CGC_RUNIT;
 235        orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk);
 236}
 237
 238
 239/*****************************************************************************
 240 * I2C
 241 ****************************************************************************/
 242void __init kirkwood_i2c_init(void)
 243{
 244        orion_i2c_init(I2C_PHYS_BASE, IRQ_KIRKWOOD_TWSI, 8);
 245}
 246
 247
 248/*****************************************************************************
 249 * UART0
 250 ****************************************************************************/
 251
 252void __init kirkwood_uart0_init(void)
 253{
 254        orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
 255                         IRQ_KIRKWOOD_UART_0, kirkwood_tclk);
 256}
 257
 258
 259/*****************************************************************************
 260 * UART1
 261 ****************************************************************************/
 262void __init kirkwood_uart1_init(void)
 263{
 264        orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
 265                         IRQ_KIRKWOOD_UART_1, kirkwood_tclk);
 266}
 267
 268/*****************************************************************************
 269 * Cryptographic Engines and Security Accelerator (CESA)
 270 ****************************************************************************/
 271void __init kirkwood_crypto_init(void)
 272{
 273        kirkwood_clk_ctrl |= CGC_CRYPTO;
 274        orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE,
 275                          KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO);
 276}
 277
 278
 279/*****************************************************************************
 280 * XOR0
 281 ****************************************************************************/
 282static void __init kirkwood_xor0_init(void)
 283{
 284        kirkwood_clk_ctrl |= CGC_XOR0;
 285
 286        orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
 287                        IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
 288}
 289
 290
 291/*****************************************************************************
 292 * XOR1
 293 ****************************************************************************/
 294static void __init kirkwood_xor1_init(void)
 295{
 296        kirkwood_clk_ctrl |= CGC_XOR1;
 297
 298        orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE,
 299                        IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11);
 300}
 301
 302
 303/*****************************************************************************
 304 * Watchdog
 305 ****************************************************************************/
 306static void __init kirkwood_wdt_init(void)
 307{
 308        orion_wdt_init(kirkwood_tclk);
 309}
 310
 311
 312/*****************************************************************************
 313 * Time handling
 314 ****************************************************************************/
 315void __init kirkwood_init_early(void)
 316{
 317        orion_time_set_base(TIMER_VIRT_BASE);
 318}
 319
 320int kirkwood_tclk;
 321
 322static int __init kirkwood_find_tclk(void)
 323{
 324        u32 dev, rev;
 325
 326        kirkwood_pcie_id(&dev, &rev);
 327
 328        if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID)
 329                if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0)
 330                        return 200000000;
 331
 332        return 166666667;
 333}
 334
 335static void __init kirkwood_timer_init(void)
 336{
 337        kirkwood_tclk = kirkwood_find_tclk();
 338
 339        orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
 340                        IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
 341}
 342
 343struct sys_timer kirkwood_timer = {
 344        .init = kirkwood_timer_init,
 345};
 346
 347/*****************************************************************************
 348 * Audio
 349 ****************************************************************************/
 350static struct resource kirkwood_i2s_resources[] = {
 351        [0] = {
 352                .start  = AUDIO_PHYS_BASE,
 353                .end    = AUDIO_PHYS_BASE + SZ_16K - 1,
 354                .flags  = IORESOURCE_MEM,
 355        },
 356        [1] = {
 357                .start  = IRQ_KIRKWOOD_I2S,
 358                .end    = IRQ_KIRKWOOD_I2S,
 359                .flags  = IORESOURCE_IRQ,
 360        },
 361};
 362
 363static struct kirkwood_asoc_platform_data kirkwood_i2s_data = {
 364        .burst       = 128,
 365};
 366
 367static struct platform_device kirkwood_i2s_device = {
 368        .name           = "kirkwood-i2s",
 369        .id             = -1,
 370        .num_resources  = ARRAY_SIZE(kirkwood_i2s_resources),
 371        .resource       = kirkwood_i2s_resources,
 372        .dev            = {
 373                .platform_data  = &kirkwood_i2s_data,
 374        },
 375};
 376
 377static struct platform_device kirkwood_pcm_device = {
 378        .name           = "kirkwood-pcm-audio",
 379        .id             = -1,
 380};
 381
 382void __init kirkwood_audio_init(void)
 383{
 384        kirkwood_clk_ctrl |= CGC_AUDIO;
 385        platform_device_register(&kirkwood_i2s_device);
 386        platform_device_register(&kirkwood_pcm_device);
 387}
 388
 389/*****************************************************************************
 390 * General
 391 ****************************************************************************/
 392/*
 393 * Identify device ID and revision.
 394 */
 395static char * __init kirkwood_id(void)
 396{
 397        u32 dev, rev;
 398
 399        kirkwood_pcie_id(&dev, &rev);
 400
 401        if (dev == MV88F6281_DEV_ID) {
 402                if (rev == MV88F6281_REV_Z0)
 403                        return "MV88F6281-Z0";
 404                else if (rev == MV88F6281_REV_A0)
 405                        return "MV88F6281-A0";
 406                else if (rev == MV88F6281_REV_A1)
 407                        return "MV88F6281-A1";
 408                else
 409                        return "MV88F6281-Rev-Unsupported";
 410        } else if (dev == MV88F6192_DEV_ID) {
 411                if (rev == MV88F6192_REV_Z0)
 412                        return "MV88F6192-Z0";
 413                else if (rev == MV88F6192_REV_A0)
 414                        return "MV88F6192-A0";
 415                else if (rev == MV88F6192_REV_A1)
 416                        return "MV88F6192-A1";
 417                else
 418                        return "MV88F6192-Rev-Unsupported";
 419        } else if (dev == MV88F6180_DEV_ID) {
 420                if (rev == MV88F6180_REV_A0)
 421                        return "MV88F6180-Rev-A0";
 422                else if (rev == MV88F6180_REV_A1)
 423                        return "MV88F6180-Rev-A1";
 424                else
 425                        return "MV88F6180-Rev-Unsupported";
 426        } else if (dev == MV88F6282_DEV_ID) {
 427                if (rev == MV88F6282_REV_A0)
 428                        return "MV88F6282-Rev-A0";
 429                else if (rev == MV88F6282_REV_A1)
 430                        return "MV88F6282-Rev-A1";
 431                else
 432                        return "MV88F6282-Rev-Unsupported";
 433        } else {
 434                return "Device-Unknown";
 435        }
 436}
 437
 438static void __init kirkwood_l2_init(void)
 439{
 440#ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
 441        writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG);
 442        feroceon_l2_init(1);
 443#else
 444        writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG);
 445        feroceon_l2_init(0);
 446#endif
 447}
 448
 449void __init kirkwood_init(void)
 450{
 451        printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
 452                kirkwood_id(), kirkwood_tclk);
 453        kirkwood_i2s_data.tclk = kirkwood_tclk;
 454
 455        /*
 456         * Disable propagation of mbus errors to the CPU local bus,
 457         * as this causes mbus errors (which can occur for example
 458         * for PCI aborts) to throw CPU aborts, which we're not set
 459         * up to deal with.
 460         */
 461        writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
 462
 463        kirkwood_setup_cpu_mbus();
 464
 465#ifdef CONFIG_CACHE_FEROCEON_L2
 466        kirkwood_l2_init();
 467#endif
 468
 469        /* internal devices that every board has */
 470        kirkwood_rtc_init();
 471        kirkwood_wdt_init();
 472        kirkwood_xor0_init();
 473        kirkwood_xor1_init();
 474        kirkwood_crypto_init();
 475
 476#ifdef CONFIG_KEXEC 
 477        kexec_reinit = kirkwood_enable_pcie;
 478#endif
 479}
 480
 481static int __init kirkwood_clock_gate(void)
 482{
 483        unsigned int curr = readl(CLOCK_GATING_CTRL);
 484        u32 dev, rev;
 485
 486        kirkwood_pcie_id(&dev, &rev);
 487        printk(KERN_DEBUG "Gating clock of unused units\n");
 488        printk(KERN_DEBUG "before: 0x%08x\n", curr);
 489
 490        /* Make sure those units are accessible */
 491        writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
 492
 493        /* For SATA: first shutdown the phy */
 494        if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
 495                /* Disable PLL and IVREF */
 496                writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
 497                /* Disable PHY */
 498                writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
 499        }
 500        if (!(kirkwood_clk_ctrl & CGC_SATA1)) {
 501                /* Disable PLL and IVREF */
 502                writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
 503                /* Disable PHY */
 504                writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
 505        }
 506        
 507        /* For PCIe: first shutdown the phy */
 508        if (!(kirkwood_clk_ctrl & CGC_PEX0)) {
 509                writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
 510                while (1)
 511                        if (readl(PCIE_STATUS) & 0x1)
 512                                break;
 513                writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
 514        }
 515
 516        /* For PCIe 1: first shutdown the phy */
 517        if (dev == MV88F6282_DEV_ID) {
 518                if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
 519                        writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
 520                        while (1)
 521                                if (readl(PCIE1_STATUS) & 0x1)
 522                                        break;
 523                        writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
 524                }
 525        } else  /* keep this bit set for devices that don't have PCIe1 */
 526                kirkwood_clk_ctrl |= CGC_PEX1;
 527
 528        /* Now gate clock the required units */
 529        writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
 530        printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
 531
 532        return 0;
 533}
 534late_initcall(kirkwood_clock_gate);
 535
 536void kirkwood_restart(char mode, const char *cmd)
 537{
 538        /*
 539         * Enable soft reset to assert RSTOUTn.
 540         */
 541        writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
 542
 543        /*
 544         * Assert soft reset.
 545         */
 546        writel(SOFT_RESET, SYSTEM_SOFT_RESET);
 547
 548        while (1)
 549                ;
 550}
 551