linux/arch/arm/mach-pxa/saar.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-pxa/saar.c
   3 *
   4 *  Support for the Marvell PXA930 Handheld Platform (aka SAAR)
   5 *
   6 *  Copyright (C) 2007-2008 Marvell International Ltd.
   7 *
   8 *  This program is free software; you can redistribute it and/or modify
   9 *  it under the terms of the GNU General Public License version 2 as
  10 *  publishhed by the Free Software Foundation.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/kernel.h>
  15#include <linux/interrupt.h>
  16#include <linux/init.h>
  17#include <linux/platform_device.h>
  18#include <linux/clk.h>
  19#include <linux/gpio.h>
  20#include <linux/delay.h>
  21#include <linux/fb.h>
  22#include <linux/i2c.h>
  23#include <linux/i2c/pxa-i2c.h>
  24#include <linux/smc91x.h>
  25#include <linux/mfd/da903x.h>
  26#include <linux/mtd/mtd.h>
  27#include <linux/mtd/partitions.h>
  28#include <linux/mtd/onenand.h>
  29
  30#include <asm/mach-types.h>
  31#include <asm/mach/arch.h>
  32#include <asm/mach/flash.h>
  33
  34#include "pxa930.h"
  35#include <linux/platform_data/video-pxafb.h>
  36
  37#include "devices.h"
  38#include "generic.h"
  39
  40#define GPIO_LCD_RESET          (16)
  41
  42/* SAAR MFP configurations */
  43static mfp_cfg_t saar_mfp_cfg[] __initdata = {
  44        /* LCD */
  45        GPIO23_LCD_DD0,
  46        GPIO24_LCD_DD1,
  47        GPIO25_LCD_DD2,
  48        GPIO26_LCD_DD3,
  49        GPIO27_LCD_DD4,
  50        GPIO28_LCD_DD5,
  51        GPIO29_LCD_DD6,
  52        GPIO44_LCD_DD7,
  53        GPIO21_LCD_CS,
  54        GPIO22_LCD_VSYNC,
  55        GPIO17_LCD_FCLK_RD,
  56        GPIO18_LCD_LCLK_A0,
  57        GPIO19_LCD_PCLK_WR,
  58        GPIO16_GPIO, /* LCD reset */
  59
  60        /* Ethernet */
  61        DF_nCS1_nCS3,
  62        GPIO97_GPIO,
  63
  64        /* DFI */
  65        DF_INT_RnB_ND_INT_RnB,
  66        DF_nRE_nOE_ND_nRE,
  67        DF_nWE_ND_nWE,
  68        DF_CLE_nOE_ND_CLE,
  69        DF_nADV1_ALE_ND_ALE,
  70        DF_nADV2_ALE_nCS3,
  71        DF_nCS0_ND_nCS0,
  72        DF_IO0_ND_IO0,
  73        DF_IO1_ND_IO1,
  74        DF_IO2_ND_IO2,
  75        DF_IO3_ND_IO3,
  76        DF_IO4_ND_IO4,
  77        DF_IO5_ND_IO5,
  78        DF_IO6_ND_IO6,
  79        DF_IO7_ND_IO7,
  80        DF_IO8_ND_IO8,
  81        DF_IO9_ND_IO9,
  82        DF_IO10_ND_IO10,
  83        DF_IO11_ND_IO11,
  84        DF_IO12_ND_IO12,
  85        DF_IO13_ND_IO13,
  86        DF_IO14_ND_IO14,
  87        DF_IO15_ND_IO15,
  88};
  89
  90#define SAAR_ETH_PHYS   (0x14000000)
  91
  92static struct resource smc91x_resources[] = {
  93        [0] = {
  94                .start  = (SAAR_ETH_PHYS + 0x300),
  95                .end    = (SAAR_ETH_PHYS + 0xfffff),
  96                .flags  = IORESOURCE_MEM,
  97        },
  98        [1] = {
  99                .start  = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)),
 100                .end    = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)),
 101                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 102        }
 103};
 104
 105static struct smc91x_platdata saar_smc91x_info = {
 106        .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
 107};
 108
 109static struct platform_device smc91x_device = {
 110        .name           = "smc91x",
 111        .id             = 0,
 112        .num_resources  = ARRAY_SIZE(smc91x_resources),
 113        .resource       = smc91x_resources,
 114        .dev            = {
 115                .platform_data = &saar_smc91x_info,
 116        },
 117};
 118
 119#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 120static uint16_t lcd_power_on[] = {
 121        /* single frame */
 122        SMART_CMD_NOOP,
 123        SMART_CMD(0x00),
 124        SMART_DELAY(0),
 125
 126        SMART_CMD_NOOP,
 127        SMART_CMD(0x00),
 128        SMART_DELAY(0),
 129
 130        SMART_CMD_NOOP,
 131        SMART_CMD(0x00),
 132        SMART_DELAY(0),
 133
 134        SMART_CMD_NOOP,
 135        SMART_CMD(0x00),
 136        SMART_DELAY(10),
 137
 138        /* calibration control */
 139        SMART_CMD(0x00),
 140        SMART_CMD(0xA4),
 141        SMART_DAT(0x80),
 142        SMART_DAT(0x01),
 143        SMART_DELAY(150),
 144
 145        /*Power-On Init sequence*/
 146        SMART_CMD(0x00),        /* output ctrl */
 147        SMART_CMD(0x01),
 148        SMART_DAT(0x01),
 149        SMART_DAT(0x00),
 150        SMART_CMD(0x00),        /* wave ctrl */
 151        SMART_CMD(0x02),
 152        SMART_DAT(0x07),
 153        SMART_DAT(0x00),
 154        SMART_CMD(0x00),
 155        SMART_CMD(0x03),        /* entry mode */
 156        SMART_DAT(0xD0),
 157        SMART_DAT(0x30),
 158        SMART_CMD(0x00),
 159        SMART_CMD(0x08),        /* display ctrl 2 */
 160        SMART_DAT(0x08),
 161        SMART_DAT(0x08),
 162        SMART_CMD(0x00),
 163        SMART_CMD(0x09),        /* display ctrl 3 */
 164        SMART_DAT(0x04),
 165        SMART_DAT(0x2F),
 166        SMART_CMD(0x00),
 167        SMART_CMD(0x0A),        /* display ctrl 4 */
 168        SMART_DAT(0x00),
 169        SMART_DAT(0x08),
 170        SMART_CMD(0x00),
 171        SMART_CMD(0x0D),        /* Frame Marker position */
 172        SMART_DAT(0x00),
 173        SMART_DAT(0x08),
 174        SMART_CMD(0x00),
 175        SMART_CMD(0x60),        /* Driver output control */
 176        SMART_DAT(0x27),
 177        SMART_DAT(0x00),
 178        SMART_CMD(0x00),
 179        SMART_CMD(0x61),        /* Base image display control */
 180        SMART_DAT(0x00),
 181        SMART_DAT(0x01),
 182        SMART_CMD(0x00),
 183        SMART_CMD(0x30),        /* Y settings 30h-3Dh */
 184        SMART_DAT(0x07),
 185        SMART_DAT(0x07),
 186        SMART_CMD(0x00),
 187        SMART_CMD(0x31),
 188        SMART_DAT(0x00),
 189        SMART_DAT(0x07),
 190        SMART_CMD(0x00),
 191        SMART_CMD(0x32),        /* Timing(3), ASW HOLD=0.5CLK */
 192        SMART_DAT(0x04),
 193        SMART_DAT(0x00),
 194        SMART_CMD(0x00),
 195        SMART_CMD(0x33),        /* Timing(4), CKV ST=0CLK, CKV ED=1CLK */
 196        SMART_DAT(0x03),
 197        SMART_DAT(0x03),
 198        SMART_CMD(0x00),
 199        SMART_CMD(0x34),
 200        SMART_DAT(0x00),
 201        SMART_DAT(0x00),
 202        SMART_CMD(0x00),
 203        SMART_CMD(0x35),
 204        SMART_DAT(0x02),
 205        SMART_DAT(0x05),
 206        SMART_CMD(0x00),
 207        SMART_CMD(0x36),
 208        SMART_DAT(0x1F),
 209        SMART_DAT(0x1F),
 210        SMART_CMD(0x00),
 211        SMART_CMD(0x37),
 212        SMART_DAT(0x07),
 213        SMART_DAT(0x07),
 214        SMART_CMD(0x00),
 215        SMART_CMD(0x38),
 216        SMART_DAT(0x00),
 217        SMART_DAT(0x07),
 218        SMART_CMD(0x00),
 219        SMART_CMD(0x39),
 220        SMART_DAT(0x04),
 221        SMART_DAT(0x00),
 222        SMART_CMD(0x00),
 223        SMART_CMD(0x3A),
 224        SMART_DAT(0x03),
 225        SMART_DAT(0x03),
 226        SMART_CMD(0x00),
 227        SMART_CMD(0x3B),
 228        SMART_DAT(0x00),
 229        SMART_DAT(0x00),
 230        SMART_CMD(0x00),
 231        SMART_CMD(0x3C),
 232        SMART_DAT(0x02),
 233        SMART_DAT(0x05),
 234        SMART_CMD(0x00),
 235        SMART_CMD(0x3D),
 236        SMART_DAT(0x1F),
 237        SMART_DAT(0x1F),
 238        SMART_CMD(0x00),        /* Display control 1 */
 239        SMART_CMD(0x07),
 240        SMART_DAT(0x00),
 241        SMART_DAT(0x01),
 242        SMART_CMD(0x00),        /* Power control 5 */
 243        SMART_CMD(0x17),
 244        SMART_DAT(0x00),
 245        SMART_DAT(0x01),
 246        SMART_CMD(0x00),        /* Power control 1 */
 247        SMART_CMD(0x10),
 248        SMART_DAT(0x10),
 249        SMART_DAT(0xB0),
 250        SMART_CMD(0x00),        /* Power control 2 */
 251        SMART_CMD(0x11),
 252        SMART_DAT(0x01),
 253        SMART_DAT(0x30),
 254        SMART_CMD(0x00),        /* Power control 3 */
 255        SMART_CMD(0x12),
 256        SMART_DAT(0x01),
 257        SMART_DAT(0x9E),
 258        SMART_CMD(0x00),        /* Power control 4 */
 259        SMART_CMD(0x13),
 260        SMART_DAT(0x17),
 261        SMART_DAT(0x00),
 262        SMART_CMD(0x00),        /* Power control 3 */
 263        SMART_CMD(0x12),
 264        SMART_DAT(0x01),
 265        SMART_DAT(0xBE),
 266        SMART_DELAY(100),
 267
 268        /* display mode : 240*320 */
 269        SMART_CMD(0x00),        /* RAM address set(H) 0*/
 270        SMART_CMD(0x20),
 271        SMART_DAT(0x00),
 272        SMART_DAT(0x00),
 273        SMART_CMD(0x00),        /* RAM address set(V)   4*/
 274        SMART_CMD(0x21),
 275        SMART_DAT(0x00),
 276        SMART_DAT(0x00),
 277        SMART_CMD(0x00),        /* Start of Window RAM address set(H) 8*/
 278        SMART_CMD(0x50),
 279        SMART_DAT(0x00),
 280        SMART_DAT(0x00),
 281        SMART_CMD(0x00),        /* End of Window RAM address set(H) 12*/
 282        SMART_CMD(0x51),
 283        SMART_DAT(0x00),
 284        SMART_DAT(0xEF),
 285        SMART_CMD(0x00),        /* Start of Window RAM address set(V) 16*/
 286        SMART_CMD(0x52),
 287        SMART_DAT(0x00),
 288        SMART_DAT(0x00),
 289        SMART_CMD(0x00),        /* End of Window RAM address set(V) 20*/
 290        SMART_CMD(0x53),
 291        SMART_DAT(0x01),
 292        SMART_DAT(0x3F),
 293        SMART_CMD(0x00),        /* Panel interface control 1 */
 294        SMART_CMD(0x90),
 295        SMART_DAT(0x00),
 296        SMART_DAT(0x1A),
 297        SMART_CMD(0x00),        /* Panel interface control 2 */
 298        SMART_CMD(0x92),
 299        SMART_DAT(0x04),
 300        SMART_DAT(0x00),
 301        SMART_CMD(0x00),        /* Panel interface control 3 */
 302        SMART_CMD(0x93),
 303        SMART_DAT(0x00),
 304        SMART_DAT(0x05),
 305        SMART_DELAY(20),
 306};
 307
 308static uint16_t lcd_panel_on[] = {
 309        SMART_CMD(0x00),
 310        SMART_CMD(0x07),
 311        SMART_DAT(0x00),
 312        SMART_DAT(0x21),
 313        SMART_DELAY(1),
 314
 315        SMART_CMD(0x00),
 316        SMART_CMD(0x07),
 317        SMART_DAT(0x00),
 318        SMART_DAT(0x61),
 319        SMART_DELAY(100),
 320
 321        SMART_CMD(0x00),
 322        SMART_CMD(0x07),
 323        SMART_DAT(0x01),
 324        SMART_DAT(0x73),
 325        SMART_DELAY(1),
 326};
 327
 328static uint16_t lcd_panel_off[] = {
 329        SMART_CMD(0x00),
 330        SMART_CMD(0x07),
 331        SMART_DAT(0x00),
 332        SMART_DAT(0x72),
 333        SMART_DELAY(40),
 334
 335        SMART_CMD(0x00),
 336        SMART_CMD(0x07),
 337        SMART_DAT(0x00),
 338        SMART_DAT(0x01),
 339        SMART_DELAY(1),
 340
 341        SMART_CMD(0x00),
 342        SMART_CMD(0x07),
 343        SMART_DAT(0x00),
 344        SMART_DAT(0x00),
 345        SMART_DELAY(1),
 346};
 347
 348static uint16_t lcd_power_off[] = {
 349        SMART_CMD(0x00),
 350        SMART_CMD(0x10),
 351        SMART_DAT(0x00),
 352        SMART_DAT(0x80),
 353
 354        SMART_CMD(0x00),
 355        SMART_CMD(0x11),
 356        SMART_DAT(0x01),
 357        SMART_DAT(0x60),
 358
 359        SMART_CMD(0x00),
 360        SMART_CMD(0x12),
 361        SMART_DAT(0x01),
 362        SMART_DAT(0xAE),
 363        SMART_DELAY(40),
 364
 365        SMART_CMD(0x00),
 366        SMART_CMD(0x10),
 367        SMART_DAT(0x00),
 368        SMART_DAT(0x00),
 369};
 370
 371static uint16_t update_framedata[] = {
 372        /* set display ram: 240*320 */
 373        SMART_CMD(0x00), /* RAM address set(H) 0*/
 374        SMART_CMD(0x20),
 375        SMART_DAT(0x00),
 376        SMART_DAT(0x00),
 377        SMART_CMD(0x00), /* RAM address set(V) 4*/
 378        SMART_CMD(0x21),
 379        SMART_DAT(0x00),
 380        SMART_DAT(0x00),
 381        SMART_CMD(0x00), /* Start of Window RAM address set(H) 8 */
 382        SMART_CMD(0x50),
 383        SMART_DAT(0x00),
 384        SMART_DAT(0x00),
 385        SMART_CMD(0x00), /* End of Window RAM address set(H) 12 */
 386        SMART_CMD(0x51),
 387        SMART_DAT(0x00),
 388        SMART_DAT(0xEF),
 389        SMART_CMD(0x00), /* Start of Window RAM address set(V) 16 */
 390        SMART_CMD(0x52),
 391        SMART_DAT(0x00),
 392        SMART_DAT(0x00),
 393        SMART_CMD(0x00), /* End of Window RAM address set(V) 20 */
 394        SMART_CMD(0x53),
 395        SMART_DAT(0x01),
 396        SMART_DAT(0x3F),
 397
 398        /* wait for vsync cmd before transferring frame data */
 399        SMART_CMD_WAIT_FOR_VSYNC,
 400
 401        /* write ram */
 402        SMART_CMD(0x00),
 403        SMART_CMD(0x22),
 404
 405        /* write frame data */
 406        SMART_CMD_WRITE_FRAME,
 407};
 408
 409static void ltm022a97a_lcd_power(int on, struct fb_var_screeninfo *var)
 410{
 411        static int pin_requested = 0;
 412        struct fb_info *info = container_of(var, struct fb_info, var);
 413        int err;
 414
 415        if (!pin_requested) {
 416                err = gpio_request(GPIO_LCD_RESET, "lcd reset");
 417                if (err) {
 418                        pr_err("failed to request gpio for LCD reset\n");
 419                        return;
 420                }
 421
 422                gpio_direction_output(GPIO_LCD_RESET, 0);
 423                pin_requested = 1;
 424        }
 425
 426        if (on) {
 427                gpio_set_value(GPIO_LCD_RESET, 0); msleep(100);
 428                gpio_set_value(GPIO_LCD_RESET, 1); msleep(10);
 429
 430                pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_power_on));
 431                pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_panel_on));
 432        } else {
 433                pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_panel_off));
 434                pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_power_off));
 435        }
 436
 437        err = pxafb_smart_flush(info);
 438        if (err)
 439                pr_err("%s: timed out\n", __func__);
 440}
 441
 442static void ltm022a97a_update(struct fb_info *info)
 443{
 444        pxafb_smart_queue(info, ARRAY_AND_SIZE(update_framedata));
 445        pxafb_smart_flush(info);
 446}
 447
 448static struct pxafb_mode_info toshiba_ltm022a97a_modes[] = {
 449        [0] = {
 450                .xres                   = 240,
 451                .yres                   = 320,
 452                .bpp                    = 16,
 453                .a0csrd_set_hld         = 30,
 454                .a0cswr_set_hld         = 30,
 455                .wr_pulse_width         = 30,
 456                .rd_pulse_width         = 30,
 457                .op_hold_time           = 30,
 458                .cmd_inh_time           = 60,
 459
 460                /* L_LCLK_A0 and L_LCLK_RD active low */
 461                .sync                   = FB_SYNC_HOR_HIGH_ACT |
 462                                          FB_SYNC_VERT_HIGH_ACT,
 463        },
 464};
 465
 466static struct pxafb_mach_info saar_lcd_info = {
 467        .modes                  = toshiba_ltm022a97a_modes,
 468        .num_modes              = 1,
 469        .lcd_conn               = LCD_SMART_PANEL_8BPP | LCD_PCLK_EDGE_FALL,
 470        .pxafb_lcd_power        = ltm022a97a_lcd_power,
 471        .smart_update           = ltm022a97a_update,
 472};
 473
 474static void __init saar_init_lcd(void)
 475{
 476        pxa_set_fb_info(NULL, &saar_lcd_info);
 477}
 478#else
 479static inline void saar_init_lcd(void) {}
 480#endif
 481
 482#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
 483static struct da9034_backlight_pdata saar_da9034_backlight = {
 484        .output_current = 4,    /* 4mA */
 485};
 486
 487static struct da903x_subdev_info saar_da9034_subdevs[] = {
 488        [0] = {
 489                .name           = "da903x-backlight",
 490                .id             = DA9034_ID_WLED,
 491                .platform_data  = &saar_da9034_backlight,
 492        },
 493};
 494
 495static struct da903x_platform_data saar_da9034_info = {
 496        .num_subdevs    = ARRAY_SIZE(saar_da9034_subdevs),
 497        .subdevs        = saar_da9034_subdevs,
 498};
 499
 500static struct i2c_board_info saar_i2c_info[] = {
 501        [0] = {
 502                .type           = "da9034",
 503                .addr           = 0x34,
 504                .platform_data  = &saar_da9034_info,
 505                .irq            = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO83)),
 506        },
 507};
 508
 509static void __init saar_init_i2c(void)
 510{
 511        pxa_set_i2c_info(NULL);
 512        i2c_register_board_info(0, ARRAY_AND_SIZE(saar_i2c_info));
 513}
 514#else
 515static inline void saar_init_i2c(void) {}
 516#endif
 517
 518#if defined(CONFIG_MTD_ONENAND) || defined(CONFIG_MTD_ONENAND_MODULE)
 519static struct mtd_partition saar_onenand_partitions[] = {
 520        {
 521                .name           = "bootloader",
 522                .offset         = 0,
 523                .size           = SZ_1M,
 524                .mask_flags     = MTD_WRITEABLE,
 525        }, {
 526                .name           = "reserved",
 527                .offset         = MTDPART_OFS_APPEND,
 528                .size           = SZ_128K,
 529                .mask_flags     = MTD_WRITEABLE,
 530        }, {
 531                .name           = "reserved",
 532                .offset         = MTDPART_OFS_APPEND,
 533                .size           = SZ_8M,
 534                .mask_flags     = MTD_WRITEABLE,
 535        }, {
 536                .name           = "kernel",
 537                .offset         = MTDPART_OFS_APPEND,
 538                .size           = (SZ_2M + SZ_1M),
 539                .mask_flags     = 0,
 540        }, {
 541                .name           = "filesystem",
 542                .offset         = MTDPART_OFS_APPEND,
 543                .size           = SZ_32M + SZ_16M,
 544                .mask_flags     = 0,
 545        }
 546};
 547
 548static struct onenand_platform_data saar_onenand_info = {
 549        .parts          = saar_onenand_partitions,
 550        .nr_parts       = ARRAY_SIZE(saar_onenand_partitions),
 551};
 552
 553#define SMC_CS0_PHYS_BASE       (0x10000000)
 554
 555static struct resource saar_resource_onenand[] = {
 556        [0] = {
 557                .start  = SMC_CS0_PHYS_BASE,
 558                .end    = SMC_CS0_PHYS_BASE + SZ_1M,
 559                .flags  = IORESOURCE_MEM,
 560        },
 561};
 562
 563static struct platform_device saar_device_onenand = {
 564        .name           = "onenand-flash",
 565        .id             = -1,
 566        .dev            = {
 567                .platform_data  = &saar_onenand_info,
 568        },
 569        .resource       = saar_resource_onenand,
 570        .num_resources  = ARRAY_SIZE(saar_resource_onenand),
 571};
 572
 573static void __init saar_init_onenand(void)
 574{
 575        platform_device_register(&saar_device_onenand);
 576}
 577#else
 578static void __init saar_init_onenand(void) {}
 579#endif
 580
 581static void __init saar_init(void)
 582{
 583        /* initialize MFP configurations */
 584        pxa3xx_mfp_config(ARRAY_AND_SIZE(saar_mfp_cfg));
 585
 586        pxa_set_ffuart_info(NULL);
 587        pxa_set_btuart_info(NULL);
 588        pxa_set_stuart_info(NULL);
 589
 590        platform_device_register(&smc91x_device);
 591        saar_init_onenand();
 592
 593        saar_init_i2c();
 594        saar_init_lcd();
 595}
 596
 597MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
 598        /* Maintainer: Eric Miao <eric.miao@marvell.com> */
 599        .atag_offset    = 0x100,
 600        .map_io         = pxa3xx_map_io,
 601        .nr_irqs        = PXA_NR_IRQS,
 602        .init_irq       = pxa3xx_init_irq,
 603        .handle_irq       = pxa3xx_handle_irq,
 604        .init_time      = pxa_timer_init,
 605        .init_machine   = saar_init,
 606        .restart        = pxa_restart,
 607MACHINE_END
 608