linux/arch/arm/mach-realview/core.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-realview/core.c
   3 *
   4 *  Copyright (C) 1999 - 2003 ARM Limited
   5 *  Copyright (C) 2000 Deep Blue Solutions Ltd
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20 */
  21#include <linux/init.h>
  22#include <linux/platform_device.h>
  23#include <linux/dma-mapping.h>
  24#include <linux/sysdev.h>
  25#include <linux/interrupt.h>
  26#include <linux/amba/bus.h>
  27#include <linux/amba/clcd.h>
  28#include <linux/io.h>
  29#include <linux/smsc911x.h>
  30#include <linux/ata_platform.h>
  31#include <linux/amba/mmci.h>
  32#include <linux/gfp.h>
  33#include <linux/clkdev.h>
  34
  35#include <asm/system.h>
  36#include <mach/hardware.h>
  37#include <asm/irq.h>
  38#include <asm/leds.h>
  39#include <asm/mach-types.h>
  40#include <asm/hardware/arm_timer.h>
  41#include <asm/hardware/icst.h>
  42
  43#include <asm/mach/arch.h>
  44#include <asm/mach/flash.h>
  45#include <asm/mach/irq.h>
  46#include <asm/mach/map.h>
  47
  48#include <asm/hardware/gic.h>
  49
  50#include <mach/platform.h>
  51#include <mach/irqs.h>
  52#include <asm/hardware/timer-sp.h>
  53
  54#include <plat/sched_clock.h>
  55
  56#include "core.h"
  57
  58#ifdef CONFIG_ZONE_DMA
  59/*
  60 * Adjust the zones if there are restrictions for DMA access.
  61 */
  62void __init realview_adjust_zones(unsigned long *size, unsigned long *hole)
  63{
  64        unsigned long dma_size = SZ_256M >> PAGE_SHIFT;
  65
  66        if (!machine_is_realview_pbx() || size[0] <= dma_size)
  67                return;
  68
  69        size[ZONE_NORMAL] = size[0] - dma_size;
  70        size[ZONE_DMA] = dma_size;
  71        hole[ZONE_NORMAL] = hole[0];
  72        hole[ZONE_DMA] = 0;
  73}
  74#endif
  75
  76
  77#define REALVIEW_FLASHCTRL    (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
  78
  79static int realview_flash_init(void)
  80{
  81        u32 val;
  82
  83        val = __raw_readl(REALVIEW_FLASHCTRL);
  84        val &= ~REALVIEW_FLASHPROG_FLVPPEN;
  85        __raw_writel(val, REALVIEW_FLASHCTRL);
  86
  87        return 0;
  88}
  89
  90static void realview_flash_exit(void)
  91{
  92        u32 val;
  93
  94        val = __raw_readl(REALVIEW_FLASHCTRL);
  95        val &= ~REALVIEW_FLASHPROG_FLVPPEN;
  96        __raw_writel(val, REALVIEW_FLASHCTRL);
  97}
  98
  99static void realview_flash_set_vpp(int on)
 100{
 101        u32 val;
 102
 103        val = __raw_readl(REALVIEW_FLASHCTRL);
 104        if (on)
 105                val |= REALVIEW_FLASHPROG_FLVPPEN;
 106        else
 107                val &= ~REALVIEW_FLASHPROG_FLVPPEN;
 108        __raw_writel(val, REALVIEW_FLASHCTRL);
 109}
 110
 111static struct flash_platform_data realview_flash_data = {
 112        .map_name               = "cfi_probe",
 113        .width                  = 4,
 114        .init                   = realview_flash_init,
 115        .exit                   = realview_flash_exit,
 116        .set_vpp                = realview_flash_set_vpp,
 117};
 118
 119struct platform_device realview_flash_device = {
 120        .name                   = "armflash",
 121        .id                     = 0,
 122        .dev                    = {
 123                .platform_data  = &realview_flash_data,
 124        },
 125};
 126
 127int realview_flash_register(struct resource *res, u32 num)
 128{
 129        realview_flash_device.resource = res;
 130        realview_flash_device.num_resources = num;
 131        return platform_device_register(&realview_flash_device);
 132}
 133
 134static struct smsc911x_platform_config smsc911x_config = {
 135        .flags          = SMSC911X_USE_32BIT,
 136        .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
 137        .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
 138        .phy_interface  = PHY_INTERFACE_MODE_MII,
 139};
 140
 141static struct platform_device realview_eth_device = {
 142        .name           = "smsc911x",
 143        .id             = 0,
 144        .num_resources  = 2,
 145};
 146
 147int realview_eth_register(const char *name, struct resource *res)
 148{
 149        if (name)
 150                realview_eth_device.name = name;
 151        realview_eth_device.resource = res;
 152        if (strcmp(realview_eth_device.name, "smsc911x") == 0)
 153                realview_eth_device.dev.platform_data = &smsc911x_config;
 154
 155        return platform_device_register(&realview_eth_device);
 156}
 157
 158struct platform_device realview_usb_device = {
 159        .name                   = "isp1760",
 160        .num_resources          = 2,
 161};
 162
 163int realview_usb_register(struct resource *res)
 164{
 165        realview_usb_device.resource = res;
 166        return platform_device_register(&realview_usb_device);
 167}
 168
 169static struct pata_platform_info pata_platform_data = {
 170        .ioport_shift           = 1,
 171};
 172
 173static struct resource pata_resources[] = {
 174        [0] = {
 175                .start          = REALVIEW_CF_BASE,
 176                .end            = REALVIEW_CF_BASE + 0xff,
 177                .flags          = IORESOURCE_MEM,
 178        },
 179        [1] = {
 180                .start          = REALVIEW_CF_BASE + 0x100,
 181                .end            = REALVIEW_CF_BASE + SZ_4K - 1,
 182                .flags          = IORESOURCE_MEM,
 183        },
 184};
 185
 186struct platform_device realview_cf_device = {
 187        .name                   = "pata_platform",
 188        .id                     = -1,
 189        .num_resources          = ARRAY_SIZE(pata_resources),
 190        .resource               = pata_resources,
 191        .dev                    = {
 192                .platform_data  = &pata_platform_data,
 193        },
 194};
 195
 196static struct resource realview_i2c_resource = {
 197        .start          = REALVIEW_I2C_BASE,
 198        .end            = REALVIEW_I2C_BASE + SZ_4K - 1,
 199        .flags          = IORESOURCE_MEM,
 200};
 201
 202struct platform_device realview_i2c_device = {
 203        .name           = "versatile-i2c",
 204        .id             = 0,
 205        .num_resources  = 1,
 206        .resource       = &realview_i2c_resource,
 207};
 208
 209static struct i2c_board_info realview_i2c_board_info[] = {
 210        {
 211                I2C_BOARD_INFO("ds1338", 0xd0 >> 1),
 212        },
 213};
 214
 215static int __init realview_i2c_init(void)
 216{
 217        return i2c_register_board_info(0, realview_i2c_board_info,
 218                                       ARRAY_SIZE(realview_i2c_board_info));
 219}
 220arch_initcall(realview_i2c_init);
 221
 222#define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
 223
 224/*
 225 * This is only used if GPIOLIB support is disabled
 226 */
 227static unsigned int realview_mmc_status(struct device *dev)
 228{
 229        struct amba_device *adev = container_of(dev, struct amba_device, dev);
 230        u32 mask;
 231
 232        if (machine_is_realview_pb1176()) {
 233                static bool inserted = false;
 234
 235                /*
 236                 * The PB1176 does not have the status register,
 237                 * assume it is inserted at startup, then invert
 238                 * for each call so card insertion/removal will
 239                 * be detected anyway. This will not be called if
 240                 * GPIO on PL061 is active, which is the proper
 241                 * way to do this on the PB1176.
 242                 */
 243                inserted = !inserted;
 244                return inserted ? 0 : 1;
 245        }
 246
 247        if (adev->res.start == REALVIEW_MMCI0_BASE)
 248                mask = 1;
 249        else
 250                mask = 2;
 251
 252        return readl(REALVIEW_SYSMCI) & mask;
 253}
 254
 255struct mmci_platform_data realview_mmc0_plat_data = {
 256        .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
 257        .status         = realview_mmc_status,
 258        .gpio_wp        = 17,
 259        .gpio_cd        = 16,
 260        .cd_invert      = true,
 261};
 262
 263struct mmci_platform_data realview_mmc1_plat_data = {
 264        .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
 265        .status         = realview_mmc_status,
 266        .gpio_wp        = 19,
 267        .gpio_cd        = 18,
 268        .cd_invert      = true,
 269};
 270
 271/*
 272 * Clock handling
 273 */
 274static const struct icst_params realview_oscvco_params = {
 275        .ref            = 24000000,
 276        .vco_max        = ICST307_VCO_MAX,
 277        .vco_min        = ICST307_VCO_MIN,
 278        .vd_min         = 4 + 8,
 279        .vd_max         = 511 + 8,
 280        .rd_min         = 1 + 2,
 281        .rd_max         = 127 + 2,
 282        .s2div          = icst307_s2div,
 283        .idx2s          = icst307_idx2s,
 284};
 285
 286static void realview_oscvco_set(struct clk *clk, struct icst_vco vco)
 287{
 288        void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
 289        u32 val;
 290
 291        val = readl(clk->vcoreg) & ~0x7ffff;
 292        val |= vco.v | (vco.r << 9) | (vco.s << 16);
 293
 294        writel(0xa05f, sys_lock);
 295        writel(val, clk->vcoreg);
 296        writel(0, sys_lock);
 297}
 298
 299static const struct clk_ops oscvco_clk_ops = {
 300        .round  = icst_clk_round,
 301        .set    = icst_clk_set,
 302        .setvco = realview_oscvco_set,
 303};
 304
 305static struct clk oscvco_clk = {
 306        .ops    = &oscvco_clk_ops,
 307        .params = &realview_oscvco_params,
 308};
 309
 310/*
 311 * These are fixed clocks.
 312 */
 313static struct clk ref24_clk = {
 314        .rate   = 24000000,
 315};
 316
 317static struct clk dummy_apb_pclk;
 318
 319static struct clk_lookup lookups[] = {
 320        {       /* Bus clock */
 321                .con_id         = "apb_pclk",
 322                .clk            = &dummy_apb_pclk,
 323        }, {    /* UART0 */
 324                .dev_id         = "dev:uart0",
 325                .clk            = &ref24_clk,
 326        }, {    /* UART1 */
 327                .dev_id         = "dev:uart1",
 328                .clk            = &ref24_clk,
 329        }, {    /* UART2 */
 330                .dev_id         = "dev:uart2",
 331                .clk            = &ref24_clk,
 332        }, {    /* UART3 */
 333                .dev_id         = "fpga:uart3",
 334                .clk            = &ref24_clk,
 335        }, {    /* UART3 is on the dev chip in PB1176 */
 336                .dev_id         = "dev:uart3",
 337                .clk            = &ref24_clk,
 338        }, {    /* UART4 only exists in PB1176 */
 339                .dev_id         = "fpga:uart4",
 340                .clk            = &ref24_clk,
 341        }, {    /* KMI0 */
 342                .dev_id         = "fpga:kmi0",
 343                .clk            = &ref24_clk,
 344        }, {    /* KMI1 */
 345                .dev_id         = "fpga:kmi1",
 346                .clk            = &ref24_clk,
 347        }, {    /* MMC0 */
 348                .dev_id         = "fpga:mmc0",
 349                .clk            = &ref24_clk,
 350        }, {    /* CLCD is in the PB1176 and EB DevChip */
 351                .dev_id         = "dev:clcd",
 352                .clk            = &oscvco_clk,
 353        }, {    /* PB:CLCD */
 354                .dev_id         = "issp:clcd",
 355                .clk            = &oscvco_clk,
 356        }, {    /* SSP */
 357                .dev_id         = "dev:ssp0",
 358                .clk            = &ref24_clk,
 359        }
 360};
 361
 362static int __init clk_init(void)
 363{
 364        if (machine_is_realview_pb1176())
 365                oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET;
 366        else
 367                oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
 368
 369        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 370
 371        return 0;
 372}
 373core_initcall(clk_init);
 374
 375/*
 376 * CLCD support.
 377 */
 378#define SYS_CLCD_NLCDIOON       (1 << 2)
 379#define SYS_CLCD_VDDPOSSWITCH   (1 << 3)
 380#define SYS_CLCD_PWR3V5SWITCH   (1 << 4)
 381#define SYS_CLCD_ID_MASK        (0x1f << 8)
 382#define SYS_CLCD_ID_SANYO_3_8   (0x00 << 8)
 383#define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8)
 384#define SYS_CLCD_ID_EPSON_2_2   (0x02 << 8)
 385#define SYS_CLCD_ID_SANYO_2_5   (0x07 << 8)
 386#define SYS_CLCD_ID_VGA         (0x1f << 8)
 387
 388static struct clcd_panel vga = {
 389        .mode           = {
 390                .name           = "VGA",
 391                .refresh        = 60,
 392                .xres           = 640,
 393                .yres           = 480,
 394                .pixclock       = 39721,
 395                .left_margin    = 40,
 396                .right_margin   = 24,
 397                .upper_margin   = 32,
 398                .lower_margin   = 11,
 399                .hsync_len      = 96,
 400                .vsync_len      = 2,
 401                .sync           = 0,
 402                .vmode          = FB_VMODE_NONINTERLACED,
 403        },
 404        .width          = -1,
 405        .height         = -1,
 406        .tim2           = TIM2_BCD | TIM2_IPC,
 407        .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
 408        .bpp            = 16,
 409};
 410
 411static struct clcd_panel xvga = {
 412        .mode           = {
 413                .name           = "XVGA",
 414                .refresh        = 60,
 415                .xres           = 1024,
 416                .yres           = 768,
 417                .pixclock       = 15748,
 418                .left_margin    = 152,
 419                .right_margin   = 48,
 420                .upper_margin   = 23,
 421                .lower_margin   = 3,
 422                .hsync_len      = 104,
 423                .vsync_len      = 4,
 424                .sync           = 0,
 425                .vmode          = FB_VMODE_NONINTERLACED,
 426        },
 427        .width          = -1,
 428        .height         = -1,
 429        .tim2           = TIM2_BCD | TIM2_IPC,
 430        .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
 431        .bpp            = 16,
 432};
 433
 434static struct clcd_panel sanyo_3_8_in = {
 435        .mode           = {
 436                .name           = "Sanyo QVGA",
 437                .refresh        = 116,
 438                .xres           = 320,
 439                .yres           = 240,
 440                .pixclock       = 100000,
 441                .left_margin    = 6,
 442                .right_margin   = 6,
 443                .upper_margin   = 5,
 444                .lower_margin   = 5,
 445                .hsync_len      = 6,
 446                .vsync_len      = 6,
 447                .sync           = 0,
 448                .vmode          = FB_VMODE_NONINTERLACED,
 449        },
 450        .width          = -1,
 451        .height         = -1,
 452        .tim2           = TIM2_BCD,
 453        .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
 454        .bpp            = 16,
 455};
 456
 457static struct clcd_panel sanyo_2_5_in = {
 458        .mode           = {
 459                .name           = "Sanyo QVGA Portrait",
 460                .refresh        = 116,
 461                .xres           = 240,
 462                .yres           = 320,
 463                .pixclock       = 100000,
 464                .left_margin    = 20,
 465                .right_margin   = 10,
 466                .upper_margin   = 2,
 467                .lower_margin   = 2,
 468                .hsync_len      = 10,
 469                .vsync_len      = 2,
 470                .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 471                .vmode          = FB_VMODE_NONINTERLACED,
 472        },
 473        .width          = -1,
 474        .height         = -1,
 475        .tim2           = TIM2_IVS | TIM2_IHS | TIM2_IPC,
 476        .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
 477        .bpp            = 16,
 478};
 479
 480static struct clcd_panel epson_2_2_in = {
 481        .mode           = {
 482                .name           = "Epson QCIF",
 483                .refresh        = 390,
 484                .xres           = 176,
 485                .yres           = 220,
 486                .pixclock       = 62500,
 487                .left_margin    = 3,
 488                .right_margin   = 2,
 489                .upper_margin   = 1,
 490                .lower_margin   = 0,
 491                .hsync_len      = 3,
 492                .vsync_len      = 2,
 493                .sync           = 0,
 494                .vmode          = FB_VMODE_NONINTERLACED,
 495        },
 496        .width          = -1,
 497        .height         = -1,
 498        .tim2           = TIM2_BCD | TIM2_IPC,
 499        .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
 500        .bpp            = 16,
 501};
 502
 503/*
 504 * Detect which LCD panel is connected, and return the appropriate
 505 * clcd_panel structure.  Note: we do not have any information on
 506 * the required timings for the 8.4in panel, so we presently assume
 507 * VGA timings.
 508 */
 509static struct clcd_panel *realview_clcd_panel(void)
 510{
 511        void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
 512        struct clcd_panel *vga_panel;
 513        struct clcd_panel *panel;
 514        u32 val;
 515
 516        if (machine_is_realview_eb())
 517                vga_panel = &vga;
 518        else
 519                vga_panel = &xvga;
 520
 521        val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
 522        if (val == SYS_CLCD_ID_SANYO_3_8)
 523                panel = &sanyo_3_8_in;
 524        else if (val == SYS_CLCD_ID_SANYO_2_5)
 525                panel = &sanyo_2_5_in;
 526        else if (val == SYS_CLCD_ID_EPSON_2_2)
 527                panel = &epson_2_2_in;
 528        else if (val == SYS_CLCD_ID_VGA)
 529                panel = vga_panel;
 530        else {
 531                printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
 532                        val);
 533                panel = vga_panel;
 534        }
 535
 536        return panel;
 537}
 538
 539/*
 540 * Disable all display connectors on the interface module.
 541 */
 542static void realview_clcd_disable(struct clcd_fb *fb)
 543{
 544        void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
 545        u32 val;
 546
 547        val = readl(sys_clcd);
 548        val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
 549        writel(val, sys_clcd);
 550}
 551
 552/*
 553 * Enable the relevant connector on the interface module.
 554 */
 555static void realview_clcd_enable(struct clcd_fb *fb)
 556{
 557        void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
 558        u32 val;
 559
 560        /*
 561         * Enable the PSUs
 562         */
 563        val = readl(sys_clcd);
 564        val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
 565        writel(val, sys_clcd);
 566}
 567
 568static int realview_clcd_setup(struct clcd_fb *fb)
 569{
 570        unsigned long framesize;
 571        dma_addr_t dma;
 572
 573        if (machine_is_realview_eb())
 574                /* VGA, 16bpp */
 575                framesize = 640 * 480 * 2;
 576        else
 577                /* XVGA, 16bpp */
 578                framesize = 1024 * 768 * 2;
 579
 580        fb->panel               = realview_clcd_panel();
 581
 582        fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
 583                                                    &dma, GFP_KERNEL | GFP_DMA);
 584        if (!fb->fb.screen_base) {
 585                printk(KERN_ERR "CLCD: unable to map framebuffer\n");
 586                return -ENOMEM;
 587        }
 588
 589        fb->fb.fix.smem_start   = dma;
 590        fb->fb.fix.smem_len     = framesize;
 591
 592        return 0;
 593}
 594
 595static int realview_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
 596{
 597        return dma_mmap_writecombine(&fb->dev->dev, vma,
 598                                     fb->fb.screen_base,
 599                                     fb->fb.fix.smem_start,
 600                                     fb->fb.fix.smem_len);
 601}
 602
 603static void realview_clcd_remove(struct clcd_fb *fb)
 604{
 605        dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
 606                              fb->fb.screen_base, fb->fb.fix.smem_start);
 607}
 608
 609struct clcd_board clcd_plat_data = {
 610        .name           = "RealView",
 611        .check          = clcdfb_check,
 612        .decode         = clcdfb_decode,
 613        .disable        = realview_clcd_disable,
 614        .enable         = realview_clcd_enable,
 615        .setup          = realview_clcd_setup,
 616        .mmap           = realview_clcd_mmap,
 617        .remove         = realview_clcd_remove,
 618};
 619
 620#ifdef CONFIG_LEDS
 621#define VA_LEDS_BASE (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
 622
 623void realview_leds_event(led_event_t ledevt)
 624{
 625        unsigned long flags;
 626        u32 val;
 627        u32 led = 1 << smp_processor_id();
 628
 629        local_irq_save(flags);
 630        val = readl(VA_LEDS_BASE);
 631
 632        switch (ledevt) {
 633        case led_idle_start:
 634                val = val & ~led;
 635                break;
 636
 637        case led_idle_end:
 638                val = val | led;
 639                break;
 640
 641        case led_timer:
 642                val = val ^ REALVIEW_SYS_LED7;
 643                break;
 644
 645        case led_halted:
 646                val = 0;
 647                break;
 648
 649        default:
 650                break;
 651        }
 652
 653        writel(val, VA_LEDS_BASE);
 654        local_irq_restore(flags);
 655}
 656#endif  /* CONFIG_LEDS */
 657
 658/*
 659 * The sched_clock counter
 660 */
 661#define REFCOUNTER              (__io_address(REALVIEW_SYS_BASE) + \
 662                                 REALVIEW_SYS_24MHz_OFFSET)
 663
 664/*
 665 * Where is the timer (VA)?
 666 */
 667void __iomem *timer0_va_base;
 668void __iomem *timer1_va_base;
 669void __iomem *timer2_va_base;
 670void __iomem *timer3_va_base;
 671
 672/*
 673 * Set up the clock source and clock events devices
 674 */
 675void __init realview_timer_init(unsigned int timer_irq)
 676{
 677        u32 val;
 678
 679        versatile_sched_clock_init(REFCOUNTER, 24000000);
 680
 681        /* 
 682         * set clock frequency: 
 683         *      REALVIEW_REFCLK is 32KHz
 684         *      REALVIEW_TIMCLK is 1MHz
 685         */
 686        val = readl(__io_address(REALVIEW_SCTL_BASE));
 687        writel((REALVIEW_TIMCLK << REALVIEW_TIMER1_EnSel) |
 688               (REALVIEW_TIMCLK << REALVIEW_TIMER2_EnSel) | 
 689               (REALVIEW_TIMCLK << REALVIEW_TIMER3_EnSel) |
 690               (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val,
 691               __io_address(REALVIEW_SCTL_BASE));
 692
 693        /*
 694         * Initialise to a known state (all timers off)
 695         */
 696        writel(0, timer0_va_base + TIMER_CTRL);
 697        writel(0, timer1_va_base + TIMER_CTRL);
 698        writel(0, timer2_va_base + TIMER_CTRL);
 699        writel(0, timer3_va_base + TIMER_CTRL);
 700
 701        sp804_clocksource_init(timer3_va_base);
 702        sp804_clockevents_init(timer0_va_base, timer_irq);
 703}
 704
 705/*
 706 * Setup the memory banks.
 707 */
 708void realview_fixup(struct machine_desc *mdesc, struct tag *tags, char **from,
 709                    struct meminfo *meminfo)
 710{
 711        /*
 712         * Most RealView platforms have 512MB contiguous RAM at 0x70000000.
 713         * Half of this is mirrored at 0.
 714         */
 715#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
 716        meminfo->bank[0].start = 0x70000000;
 717        meminfo->bank[0].size = SZ_512M;
 718        meminfo->nr_banks = 1;
 719#else
 720        meminfo->bank[0].start = 0;
 721        meminfo->bank[0].size = SZ_256M;
 722        meminfo->nr_banks = 1;
 723#endif
 724}
 725