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